Index: citrus_utf1632.c =================================================================== RCS file: /cvs/cvsroot/src/lib/libc/citrus/modules/citrus_utf1632.c,v retrieving revision 1.7 diff -u -r1.7 citrus_utf1632.c --- citrus_utf1632.c 27 Oct 2006 14:13:55 -0000 1.7 +++ citrus_utf1632.c 18 Mar 2008 09:39:18 -0000 @@ -252,38 +252,60 @@ { int ret; wchar_t wc2; + static const char _bom[4] = { +#if BYTE_ORDER == BIG_ENDIAN + 0x00, 0x00, 0xFE, 0xFF, +#else + 0xFF, 0xFE, 0x00, 0x00, +#endif + }; + const char *bom = &_bom[0]; + size_t cnt; _DIAGASSERT(ei != NULL); _DIAGASSERT(nresult != 0); _DIAGASSERT(s != NULL); + cnt = (size_t)0; + if (psenc->current_endian == _ENDIAN_UNKNOWN) { + if ((ei->mode & _MODE_FORCE_ENDIAN) == 0) { + if (ei->mode & _MODE_UTF32) { + cnt = 4; + } else { + cnt = 2; +#if BYTE_ORDER == BIG_ENDIAN + bom += 2; +#endif + } + if (n < cnt) + goto e2big; + memcpy(s, bom, cnt); + s += cnt, n -= cnt; + } + psenc->current_endian = ei->preffered_endian; + } + wc2 = 0; if ((ei->mode & _MODE_UTF32)==0) { /* UTF16 */ if (wc>0xFFFF) { /* surrogate */ - if (wc>0x10FFFF) { - ret = EILSEQ; - goto err; - } - if (n < 4) { - ret = E2BIG; - goto err; - } + if (wc>0x10FFFF) + goto eilseq; + if (n < 4) + goto e2big; + cnt += 4; wc -= 0x10000; wc2 = (wc & 0x3FF) | 0xDC00; wc = (wc>>10) | 0xD800; - *nresult = (size_t)4; } else { - if (n < 2) { - ret = E2BIG; - goto err; - } - *nresult = (size_t)2; + if (n < 2) + goto e2big; + cnt += 2; } surrogate: - switch (ei->preffered_endian) { + switch (psenc->current_endian) { case _ENDIAN_BIG: s[1] = wc; s[0] = (wc >>= 8); @@ -302,12 +324,11 @@ } else { /* UTF32 */ if (wc >= 0xD800 && wc <= 0xDFFF) - goto err; - if (n < 4) { - ret = E2BIG; - goto err; - } - switch (ei->preffered_endian) { + goto eilseq; + if (n < 4) + goto e2big; + cnt += 4; + switch (psenc->current_endian) { case _ENDIAN_BIG: s[3] = wc; s[2] = (wc >>= 8); @@ -321,14 +342,17 @@ s[3] = (wc >>= 8); break; } - *nresult = (size_t)4; } + *nresult = cnt; return 0; -err: +eilseq: *nresult = (size_t)-1; - return ret; + return EILSEQ; +e2big: + *nresult = E2BIG; + return E2BIG; } static void