From 90c7d99f5ba9e88242bf396b625df38655ff947a Mon Sep 17 00:00:00 2001 From: "Tim J. Robbins" Date: Wed, 5 Nov 2003 07:56:45 +0000 Subject: [PATCH] Implement mbrtowc() and wcrtomb() directly (sync with big5.c). --- lib/libc/locale/gbk.c | 103 ++++++++++++++++++++---------------------- 1 file changed, 50 insertions(+), 53 deletions(-) diff --git a/lib/libc/locale/gbk.c b/lib/libc/locale/gbk.c index 8384070df9d2..2ed37abd9884 100644 --- a/lib/libc/locale/gbk.c +++ b/lib/libc/locale/gbk.c @@ -1,4 +1,5 @@ /*- + * Copyright (c) 2002, 2003 Tim J. Robbins. All rights reserved. * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. * @@ -37,80 +38,76 @@ #include __FBSDID("$FreeBSD$"); -#include +#include +#include #include #include #include -#include +#include -rune_t _GBK_sgetrune(const char *, size_t, char const **); -int _GBK_sputrune(rune_t, char *, size_t, char **); +extern size_t (*__mbrtowc)(wchar_t * __restrict, const char * __restrict, + size_t, mbstate_t * __restrict); +extern size_t (*__wcrtomb)(char * __restrict, wchar_t, mbstate_t * __restrict); + +int _GBK_init(_RuneLocale *); +size_t _GBK_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t, + mbstate_t * __restrict); +size_t _GBK_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict); int -_GBK_init(rl) - _RuneLocale *rl; +_GBK_init(_RuneLocale *rl) { - rl->sgetrune = _GBK_sgetrune; - rl->sputrune = _GBK_sputrune; + + __mbrtowc = _GBK_mbrtowc; + __wcrtomb = _GBK_wcrtomb; _CurrentRuneLocale = rl; __mb_cur_max = 2; return (0); } -static inline int -_gbk_check(c) - u_int c; +static __inline int +_gbk_check(u_int c) { + c &= 0xff; return ((c >= 0x80 && c <= 0xfe) ? 2 : 1); } -rune_t -_GBK_sgetrune(string, n, result) - const char *string; - size_t n; - char const **result; +size_t +_GBK_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, + mbstate_t * __restrict ps __unused) { - rune_t rune = 0; - int len; + wchar_t wc; + int i, len; - if (n < 1 || (len = _gbk_check(*string)) > n) { - if (result) - *result = string; - return (_INVALID_RUNE); - } - while (--len >= 0) - rune = (rune << 8) | ((u_int)(*string++) & 0xff); - if (result) - *result = string; - return rune; + if (s == NULL) + /* Reset to initial shift state (no-op) */ + return (0); + if (n == 0 || (size_t)(len = _gbk_check(*s)) > n) + /* Incomplete multibyte sequence */ + return ((size_t)-2); + wc = 0; + i = len; + while (i-- > 0) + wc = (wc << 8) | (unsigned char)*s++; + if (pwc != NULL) + *pwc = wc; + return (wc == L'\0' ? 0 : len); } -int -_GBK_sputrune(c, string, n, result) - rune_t c; - char *string, **result; - size_t n; +size_t +_GBK_wcrtomb(char * __restrict s, wchar_t wc, + mbstate_t * __restrict ps __unused) { - if (c & 0x8000) { - if (n >= 2) { - string[0] = (c >> 8) & 0xff; - string[1] = c & 0xff; - if (result) - *result = string + 2; - return (2); - } + + if (s == NULL) + /* Reset to initial shift state (no-op) */ + return (1); + if (wc & 0x8000) { + *s++ = (wc >> 8) & 0xff; + *s = wc & 0xff; + return (2); } - else { - if (n >= 1) { - *string = c & 0xff; - if (result) - *result = string + 1; - return (1); - } - } - if (result) - *result = string; - return (0); - + *s = wc & 0xff; + return (1); }