diff options
Diffstat (limited to 'newlib/libc/stdlib/wctomb_r.c')
-rw-r--r-- | newlib/libc/stdlib/wctomb_r.c | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/newlib/libc/stdlib/wctomb_r.c b/newlib/libc/stdlib/wctomb_r.c index b382c995f..991e0a610 100644 --- a/newlib/libc/stdlib/wctomb_r.c +++ b/newlib/libc/stdlib/wctomb_r.c @@ -12,6 +12,63 @@ _DEFUN (_wctomb_r, (r, s, wchar, state), { if (strlen (r->_current_locale) <= 1) { /* fall-through */ } + else if (!strcmp (r->_current_locale, "UTF-8")) + { + if (s == NULL) + return 0; /* UTF-8 encoding is not state-dependent */ + + if (wchar <= 0x7f) + { + *s = wchar; + return 1; + } + else if (wchar >= 0x80 && wchar <= 0x7ff) + { + *s++ = 0xc0 | ((wchar & 0x7c0) >> 6); + *s = 0x80 | (wchar & 0x3f); + return 2; + } + else if (wchar >= 0x800 && wchar <= 0xffff) + { + /* UTF-16 surrogates -- must not occur in normal UCS-4 data */ + if (wchar >= 0xd800 && wchar <= 0xdfff) + return -1; + + *s++ = 0xe0 | ((wchar & 0xf000) >> 12); + *s++ = 0x80 | ((wchar & 0xfc0) >> 6); + *s = 0x80 | (wchar & 0x3f); + return 3; + } + else if (wchar >= 0x10000 && wchar <= 0x1fffff) + { + *s++ = 0xf0 | ((wchar & 0x1c0000) >> 18); + *s++ = 0x80 | ((wchar & 0x3f000) >> 12); + *s++ = 0x80 | ((wchar & 0xfc0) >> 6); + *s = 0x80 | (wchar & 0x3f); + return 4; + } + else if (wchar >= 0x200000 && wchar <= 0x3ffffff) + { + *s++ = 0xf8 | ((wchar & 0x3000000) >> 24); + *s++ = 0x80 | ((wchar & 0xfc0000) >> 18); + *s++ = 0x80 | ((wchar & 0x3f000) >> 12); + *s++ = 0x80 | ((wchar & 0xfc0) >> 6); + *s = 0x80 | (wchar & 0x3f); + return 5; + } + else if (wchar >= 0x4000000 && wchar <= 0x7fffffff) + { + *s++ = 0xfc | ((wchar & 0x40000000) >> 30); + *s++ = 0x80 | ((wchar & 0x3f000000) >> 24); + *s++ = 0x80 | ((wchar & 0xfc0000) >> 18); + *s++ = 0x80 | ((wchar & 0x3f000) >> 12); + *s++ = 0x80 | ((wchar & 0xfc0) >> 6); + *s = 0x80 | (wchar & 0x3f); + return 6; + } + else + return -1; + } else if (!strcmp (r->_current_locale, "C-SJIS")) { unsigned char char2 = (unsigned char)wchar; |