#include "mb_wc_common.h" #include #include #include #define WIN32_LEAN_AND_MEAN #include static int __MINGW_ATTRIB_NONNULL(1) __MINGW_ATTRIB_NONNULL(4) __mbrtowc_cp (wchar_t * __restrict__ pwc, const char * __restrict__ s, size_t n, mbstate_t* __restrict__ ps, const unsigned int cp, const unsigned int mb_max) { union { mbstate_t val; char mbcs[4]; } shift_state; /* Do the prelim checks */ if (s == NULL) return 0; if (n == 0) /* The standard doesn't mention this case explicitly. Tell caller that the conversion from a non-null s is incomplete. */ return -2; /* Save the current shift state, in case we need it in DBCS case. */ shift_state.val = *ps; *ps = 0; if (!*s) { *pwc = 0; return 0; } if (mb_max > 1) { if (shift_state.mbcs[0] != 0) { /* Complete the mb char with the trailing byte. */ shift_state.mbcs[1] = *s; /* the second byte */ if (MultiByteToWideChar(cp, MB_ERR_INVALID_CHARS, shift_state.mbcs, 2, pwc, 1) == 0) { /* An invalid trailing byte */ errno = EILSEQ; return -1; } return 2; } else if (IsDBCSLeadByteEx (cp, *s)) { /* If told to translate one byte, just save the leadbyte in *ps. */ if (n < 2) { ((char*) ps)[0] = *s; return -2; } /* Else translate the first two bytes */ else if (MultiByteToWideChar (cp, MB_ERR_INVALID_CHARS, s, 2, pwc, 1) == 0) { errno = EILSEQ; return -1; } return 2; } } /* Fall through to single byte char */ if (cp == 0) *pwc = (wchar_t)(unsigned char)*s; else if (MultiByteToWideChar (cp, MB_ERR_INVALID_CHARS, s, 1, pwc, 1) == 0) { errno = EILSEQ; return -1; } return 1; } size_t mbrtowc (wchar_t * __restrict__ pwc, const char * __restrict__ s, size_t n, mbstate_t* __restrict__ ps) { static mbstate_t internal_mbstate = 0; wchar_t byte_bucket = 0; wchar_t* dst = pwc ? pwc : &byte_bucket; return (size_t) __mbrtowc_cp (dst, s, n, ps ? ps : &internal_mbstate, get_cp_from_locale(), MB_CUR_MAX); } size_t mbsrtowcs (wchar_t* __restrict__ dst, const char ** __restrict__ src, size_t len, mbstate_t* __restrict__ ps) { int ret =0 ; size_t n = 0; static mbstate_t internal_mbstate = 0; mbstate_t* internal_ps = ps ? ps : &internal_mbstate; const unsigned int cp = get_cp_from_locale();; const unsigned int mb_max = MB_CUR_MAX; if ( src == NULL || *src == NULL ) /* undefined behavior */ return 0; if (dst != NULL) { while (n < len && (ret = __mbrtowc_cp(dst, *src, len - n, internal_ps, cp, mb_max)) > 0) { ++dst; *src += ret; n += ret; } if (n < len && ret == 0) *src = (char *)NULL; } else { wchar_t byte_bucket = 0; while (n < len && (ret = __mbrtowc_cp (&byte_bucket, *src, mb_max, internal_ps, cp, mb_max)) > 0) { *src += ret; n += ret; } } return n; } size_t mbrlen (const char * __restrict__ s, size_t n, mbstate_t * __restrict__ ps) { static mbstate_t s_mbstate = 0; wchar_t byte_bucket = 0; return __mbrtowc_cp (&byte_bucket, s, n, (ps) ? ps : &s_mbstate, get_cp_from_locale(), MB_CUR_MAX); }