Implement the XSI extension which allows the destination string to be

NULL, and returns the number of bytes that would be required to store
the result of the conversion without storing anything.

PR:		17694
This commit is contained in:
Tim J. Robbins 2002-08-31 14:16:12 +00:00
parent 83e563275f
commit a5f76f1911
2 changed files with 48 additions and 6 deletions

View File

@ -37,6 +37,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <errno.h>
#include <stdlib.h>
#include <limits.h>
#include <stddef.h>
@ -50,18 +51,38 @@ mbstowcs(pwcs, s, n)
{
char const *e;
int cnt = 0;
rune_t r;
if (!pwcs || !s)
if (!s) {
errno = EINVAL;
return (-1);
}
if (pwcs == NULL) {
/* Convert and count only, do not store. */
while ((r = sgetrune(s, MB_LEN_MAX, &e)) != _INVALID_RUNE &&
r != 0) {
s = e;
cnt++;
}
if (r == _INVALID_RUNE) {
errno = EILSEQ;
return (-1);
}
}
/* Convert, store and count characters. */
while (n-- > 0) {
*pwcs = sgetrune(s, MB_LEN_MAX, &e);
if (*pwcs == _INVALID_RUNE)
if (*pwcs == _INVALID_RUNE) {
errno = EILSEQ;
return (-1);
}
if (*pwcs++ == 0)
break;
s = e;
++cnt;
}
return (cnt);
}

View File

@ -37,6 +37,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <errno.h>
#include <stdlib.h>
#include <limits.h>
#include <stddef.h>
@ -48,26 +49,46 @@ wcstombs(s, pwcs, n)
const wchar_t *pwcs;
size_t n;
{
char buf[MB_LEN_MAX];
char *e;
int cnt, nb;
if (!pwcs || !s || n > INT_MAX)
if (!pwcs || n > INT_MAX) {
errno = EINVAL;
return (-1);
}
nb = n;
cnt = 0;
if (s == NULL) {
/* Convert and count only, do not store. */
while (*pwcs != L'\0') {
if (!sputrune(*pwcs++, buf, MB_LEN_MAX, &e)) {
errno = EILSEQ;
return (-1);
}
cnt += e - buf;
}
return (cnt);
}
/* Convert, store and count characters. */
nb = n;
while (nb > 0) {
if (*pwcs == 0) {
*s = 0;
break;
}
if (!sputrune(*pwcs++, s, nb, &e))
return (-1); /* encoding error */
if (!sputrune(*pwcs++, s, nb, &e)) {
errno = EILSEQ;
return (-1);
}
if (!e) /* too long */
return (cnt);
cnt += e - s;
nb -= e - s;
s = e;
}
return (cnt);
}