/*** *_mbslen.c - Return number of multibyte characters in a multibyte string * * Copyright (c) 1989-2001, Microsoft Corporation. All rights reserved. * *Purpose: * Return number of multibyte characters in a multibyte string * excluding the terminal null. Locale-dependent. * *Revision History: * 10-01-91 ETC Created. * 12-08-91 ETC Add multithread lock. * 12-18-92 CFW Ported to Cuda tree, changed _CALLTYPE1 to _CRTAPI1. * 04-29-93 CFW Change to const char *s. * 06-01-93 CFW Test for bad MB chars. * 06-02-93 SRW ignore _INTL if _NTSUBSET_ defined. * 06-03-93 CFW Change name to avoid conflict with mbstring function. * Change return type to size_t. * 08-19-93 CFW Disallow skipping LB:NULL combos. * 09-15-93 CFW Use ANSI conformant "__" names. * 10-22-93 CFW Test for invalid MB chars using global preset flag. * 01-14-94 SRW if _NTSUBSET_ defined call Rtl functions * 09-06-94 CFW Remove _INTL switch. * 12-21-94 CFW Remove invalid MB chars NT 3.1 hack. * 02-06-95 CFW assert -> _ASSERTE. * 09-26-95 GJF New locking macro, and scheme, for functions which * reference the locale. * 04-01-96 BWT POSIX work. * 06-21-96 GJF Purged DLL_FOR_WIN32S. Polished format a bit. * 07-16-96 SKS Added missing call to _unlock_locale() * 02-27-98 RKP Added 64 bit support. * 07-22-98 GJF Revised multithread support based on threadlocinfo * struct. * *******************************************************************************/ #if defined(_NTSUBSET_) || defined(_POSIX_) #include #include #include #endif #include #include #include #include #include #include #include #include /*** *_mbstrlen - Return number of multibyte characters in a multibyte string * *Purpose: * Return number of multibyte characters in a multibyte string * excluding the terminal null. Locale-dependent. * *Entry: * char *s = string * *Exit: * Returns the number of multibyte characters in the string, or * (size_t)-1 if the string contains an invalid multibyte character. * *Exceptions: * *******************************************************************************/ size_t __cdecl _mbstrlen( const char *s ) { size_t n; #ifdef _MT pthreadlocinfo ptloci = _getptd()->ptlocinfo; if ( ptloci != __ptlocinfo ) ptloci = __updatetlocinfo(); #endif _ASSERTE (MB_CUR_MAX == 1 || MB_CUR_MAX == 2); #ifdef _MT if ( ptloci->mb_cur_max == 1 ) #else if ( MB_CUR_MAX == 1 ) #endif /* handle single byte character sets */ return (int)strlen(s); #if !defined(_NTSUBSET_) && !defined(_POSIX_) /* verify all valid MB chars */ #ifdef _MT if ( MultiByteToWideChar( ptloci->lc_codepage, #else if ( MultiByteToWideChar( __lc_codepage, #endif MB_PRECOMPOSED | MB_ERR_INVALID_CHARS, s, -1, NULL, 0 ) == 0 ) { /* bad MB char */ return (size_t)-1; } /* count MB chars */ for (n = 0; *s; n++, s++) { #ifdef _MT if ( __isleadbyte_mt(ptloci, (unsigned char)*s) ) { #else if ( isleadbyte((unsigned char)*s) ) { #endif if (*++s == '\0') break; } } #else { char *s1 = (char *)s; while (RtlAnsiCharToUnicodeChar( &s1 ) != UNICODE_NULL) ; n = s1 - s; } #endif return(n); }