static size_t __cdecl common_mbstrlen_l( char const* const string, size_t const max_size, _locale_t const locale ) { _LocaleUpdate locale_update(locale); _ASSERTE( locale_update.GetLocaleT()->locinfo->_public._locale_mb_cur_max == 1 || locale_update.GetLocaleT()->locinfo->_public._locale_mb_cur_max == 2); // Handle single byte character sets: if (locale_update.GetLocaleT()->locinfo->_public._locale_mb_cur_max == 1) { return strnlen(string, max_size); } // Verify that all of the multibyte characters are valid: if (MultiByteToWideChar( locale_update.GetLocaleT()->locinfo->_public._locale_lc_codepage, MB_PRECOMPOSED | MB_ERR_INVALID_CHARS, string, static_cast<int>(max_size), nullptr, 0 ) == 0) { // There was a bad multibyte character: errno = EILSEQ; return static_cast<size_t>(-1); } // Count multibyte characters: size_t n = 0; // Number of multibyte characters read size_t size = 0; // Number of bytes read for (char const* it = string; size < max_size && *it; ++n, ++it, ++size) { if (_isleadbyte_l(static_cast<unsigned char>(*it), locale_update.GetLocaleT())) { ++size; if (size >= max_size) break; ++it; if (*it == '\0') break; } } return size >= max_size ? max_size : n; }
extern "C" size_t __cdecl _mbstowcs_l_helper ( wchar_t *pwcs, const char *s, size_t n, _locale_t plocinfo ) { size_t count = 0; if (pwcs && n == 0) /* dest string exists, but 0 bytes converted */ return (size_t) 0; if (pwcs && n > 0) { *pwcs = '\0'; } /* validation section */ _VALIDATE_RETURN(s != NULL, EINVAL, (size_t)-1); /* n must fit into an int for MultiByteToWideChar */ _VALIDATE_RETURN(n <= INT_MAX, EINVAL, (size_t)-1); _LocaleUpdate _loc_update(plocinfo); /* if destination string exists, fill it in */ if (pwcs) { if (_loc_update.GetLocaleT()->locinfo->lc_handle[LC_CTYPE] == _CLOCALEHANDLE) { /* C locale: easy and fast */ while (count < n) { *pwcs = (wchar_t) ((unsigned char)s[count]); if (!s[count]) return count; count++; pwcs++; } return count; } else { int bytecnt, charcnt; unsigned char *p; /* Assume that the buffer is large enough */ if ( (count = MultiByteToWideChar( _loc_update.GetLocaleT()->locinfo->lc_codepage, MB_PRECOMPOSED | MB_ERR_INVALID_CHARS, s, -1, pwcs, (int)n )) != 0 ) return count - 1; /* don't count NUL */ if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { errno = EILSEQ; *pwcs = '\0'; return (size_t)-1; } /* User-supplied buffer not large enough. */ /* How many bytes are in n characters of the string? */ charcnt = (int)n; for (p = (unsigned char *)s; (charcnt-- && *p); p++) { if ( _isleadbyte_l(*p, _loc_update.GetLocaleT()) ) { if(p[1]=='\0') { /* this is a leadbyte followed by EOS -- a dud MBCS string We choose not to assert here because this function is defined to deal with dud strings on input and return a known value */ errno = EILSEQ; *pwcs = '\0'; return (size_t)-1; } else { p++; } } } bytecnt = ((int) ((char *)p - (char *)s)); if ( (count = MultiByteToWideChar( _loc_update.GetLocaleT()->locinfo->lc_codepage, MB_PRECOMPOSED, s, bytecnt, pwcs, (int)n )) == 0 ) { errno = EILSEQ; *pwcs = '\0'; return (size_t)-1; } return count; /* no NUL in string */ } } else { /* pwcs == NULL, get size only, s must be NUL-terminated */ if (_loc_update.GetLocaleT()->locinfo->lc_handle[LC_CTYPE] == _CLOCALEHANDLE) { return strlen(s); } else if ( (count = MultiByteToWideChar( _loc_update.GetLocaleT()->locinfo->lc_codepage, MB_PRECOMPOSED | MB_ERR_INVALID_CHARS, s, -1, NULL, 0 )) == 0 ) { errno = EILSEQ; return (size_t)-1; } else { return count - 1; } } }
extern "C" int __cdecl _mbtowc_l( wchar_t* pwc, const char* s, size_t n, _locale_t plocinfo ) { if (!s || n == 0) /* indicate do not have state-dependent encodings, handle zero length string */ { return 0; } if (!*s) { /* handle NULL char */ if (pwc) { *pwc = 0; } return 0; } _LocaleUpdate _loc_update(plocinfo); _ASSERTE(_loc_update.GetLocaleT()->locinfo->mb_cur_max == 1 || _loc_update.GetLocaleT()->locinfo->mb_cur_max == 2); if (_loc_update.GetLocaleT()->locinfo->lc_handle[LC_CTYPE] == _CLOCALEHANDLE) { if (pwc) { *pwc = (wchar_t)(unsigned char) * s; } return sizeof(char); } if (_isleadbyte_l((unsigned char)*s, _loc_update.GetLocaleT())) { /* multi-byte char */ if ((_loc_update.GetLocaleT()->locinfo->mb_cur_max <= 1) || ((int)n < _loc_update.GetLocaleT()->locinfo->mb_cur_max) || (MultiByteToWideChar(_loc_update.GetLocaleT()->locinfo->lc_codepage, MB_PRECOMPOSED | MB_ERR_INVALID_CHARS, s, _loc_update.GetLocaleT()->locinfo->mb_cur_max, pwc, (pwc) ? 1 : 0) == 0)) { /* validate high byte of mbcs char */ if ((n < (size_t)_loc_update.GetLocaleT()->locinfo->mb_cur_max) || (!*(s + 1))) { errno = EILSEQ; return -1; } } return _loc_update.GetLocaleT()->locinfo->mb_cur_max; } else { /* single byte char */ if (MultiByteToWideChar(_loc_update.GetLocaleT()->locinfo->lc_codepage, MB_PRECOMPOSED | MB_ERR_INVALID_CHARS, s, 1, pwc, (pwc) ? 1 : 0) == 0) { errno = EILSEQ; return -1; } return sizeof(char); } }