Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

136 lines
3.9 KiB

  1. /***
  2. *_mbslen.c - Return number of multibyte characters in a multibyte string
  3. *
  4. * Copyright (c) 1989-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * Return number of multibyte characters in a multibyte string
  8. * excluding the terminal null. Locale-dependent.
  9. *
  10. *Revision History:
  11. * 10-01-91 ETC Created.
  12. * 12-08-91 ETC Add multithread lock.
  13. * 12-18-92 CFW Ported to Cuda tree, changed _CALLTYPE1 to _CRTAPI1.
  14. * 04-29-93 CFW Change to const char *s.
  15. * 06-01-93 CFW Test for bad MB chars.
  16. * 06-02-93 SRW ignore _INTL if _NTSUBSET_ defined.
  17. * 06-03-93 CFW Change name to avoid conflict with mbstring function.
  18. * Change return type to size_t.
  19. * 08-19-93 CFW Disallow skipping LB:NULL combos.
  20. * 09-15-93 CFW Use ANSI conformant "__" names.
  21. * 10-22-93 CFW Test for invalid MB chars using global preset flag.
  22. * 01-14-94 SRW if _NTSUBSET_ defined call Rtl functions
  23. * 09-06-94 CFW Remove _INTL switch.
  24. * 12-21-94 CFW Remove invalid MB chars NT 3.1 hack.
  25. * 02-06-95 CFW assert -> _ASSERTE.
  26. * 09-26-95 GJF New locking macro, and scheme, for functions which
  27. * reference the locale.
  28. * 04-01-96 BWT POSIX work.
  29. * 06-21-96 GJF Purged DLL_FOR_WIN32S. Polished format a bit.
  30. * 07-16-96 SKS Added missing call to _unlock_locale()
  31. * 02-27-98 RKP Added 64 bit support.
  32. * 07-22-98 GJF Revised multithread support based on threadlocinfo
  33. * struct.
  34. *
  35. *******************************************************************************/
  36. #if defined(_NTSUBSET_) || defined(_POSIX_)
  37. #include <nt.h>
  38. #include <ntrtl.h>
  39. #include <nturtl.h>
  40. #endif
  41. #include <cruntime.h>
  42. #include <internal.h>
  43. #include <stdlib.h>
  44. #include <ctype.h>
  45. #include <mtdll.h>
  46. #include <locale.h>
  47. #include <setlocal.h>
  48. #include <dbgint.h>
  49. /***
  50. *_mbstrlen - Return number of multibyte characters in a multibyte string
  51. *
  52. *Purpose:
  53. * Return number of multibyte characters in a multibyte string
  54. * excluding the terminal null. Locale-dependent.
  55. *
  56. *Entry:
  57. * char *s = string
  58. *
  59. *Exit:
  60. * Returns the number of multibyte characters in the string, or
  61. * (size_t)-1 if the string contains an invalid multibyte character.
  62. *
  63. *Exceptions:
  64. *
  65. *******************************************************************************/
  66. size_t __cdecl _mbstrlen(
  67. const char *s
  68. )
  69. {
  70. size_t n;
  71. #ifdef _MT
  72. pthreadlocinfo ptloci = _getptd()->ptlocinfo;
  73. if ( ptloci != __ptlocinfo )
  74. ptloci = __updatetlocinfo();
  75. #endif
  76. _ASSERTE (MB_CUR_MAX == 1 || MB_CUR_MAX == 2);
  77. #ifdef _MT
  78. if ( ptloci->mb_cur_max == 1 )
  79. #else
  80. if ( MB_CUR_MAX == 1 )
  81. #endif
  82. /* handle single byte character sets */
  83. return (int)strlen(s);
  84. #if !defined(_NTSUBSET_) && !defined(_POSIX_)
  85. /* verify all valid MB chars */
  86. #ifdef _MT
  87. if ( MultiByteToWideChar( ptloci->lc_codepage,
  88. #else
  89. if ( MultiByteToWideChar( __lc_codepage,
  90. #endif
  91. MB_PRECOMPOSED | MB_ERR_INVALID_CHARS,
  92. s,
  93. -1,
  94. NULL,
  95. 0 ) == 0 )
  96. {
  97. /* bad MB char */
  98. return (size_t)-1;
  99. }
  100. /* count MB chars */
  101. for (n = 0; *s; n++, s++) {
  102. #ifdef _MT
  103. if ( __isleadbyte_mt(ptloci, (unsigned char)*s) ) {
  104. #else
  105. if ( isleadbyte((unsigned char)*s) ) {
  106. #endif
  107. if (*++s == '\0')
  108. break;
  109. }
  110. }
  111. #else
  112. {
  113. char *s1 = (char *)s;
  114. while (RtlAnsiCharToUnicodeChar( &s1 ) != UNICODE_NULL)
  115. ;
  116. n = s1 - s;
  117. }
  118. #endif
  119. return(n);
  120. }