The example programs given in the last sections are only brief and do
not contain all the error checking, etc. Presented here is a complete
and documented example. It features the mbrtowc function but it
should be easy to derive versions using the other functions.
int
file_mbsrtowcs (int input, int output)
{
/* Note the use of MB_LEN_MAX.MB_CUR_MAX cannot portably be used here. */
char buffer[BUFSIZ + MB_LEN_MAX];
mbstate_t state;
int filled = 0;
int eof = 0;
/* Initialize the state. */
memset (&state, '\0', sizeof (state));
while (!eof)
{
ssize_t nread;
ssize_t nwrite;
char *inp = buffer;
wchar_t outbuf[BUFSIZ];
wchar_t *outp = outbuf;
/* Fill up the buffer from the input file. */
nread = read (input, buffer + filled, BUFSIZ);
if (nread < 0)
{
perror ("read");
return 0;
}
/* If we reach end of file, make a note to read no more. */
if (nread == 0)
eof = 1;
/* filled is now the number of bytes in buffer. */
filled += nread;
/* Convert those bytes to wide characters--as many as we can. */
while (1)
{
size_t thislen = mbrtowc (outp, inp, filled, &state);
/* Stop converting at invalid character;this can mean we have read just the first partof a valid character. */
if (thislen == (size_t) -1)
break;
/* We want to handle embedded NUL bytesbut the return value is 0. Correct this. */
if (thislen == 0)
thislen = 1;
/* Advance past this character. */
inp += thislen;
filled -= thislen;
++outp;
}
/* Write the wide characters we just made. */
nwrite = write (output, outbuf,
(outp - outbuf) * sizeof (wchar_t));
if (nwrite < 0)
{
perror ("write");
return 0;
}
/* See if we have a real invalid character. */
if ((eof && filled > 0) || filled >= MB_CUR_MAX)
{
error (0, 0, "invalid multibyte character");
return 0;
}
/* If any characters must be carried forward,put them at the beginning of buffer. */
if (filled > 0)
memmove (inp, buffer, filled);
}
return 1;
}
Published under the terms of the GNU General Public License