Leaked source code of windows server 2003
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.

165 lines
5.3 KiB

  1. /***
  2. *mblen.c - length of multibyte character
  3. *
  4. * Copyright (c) 1990-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * Return the number of bytes contained in a multibyte character.
  8. *
  9. *Revision History:
  10. * 03-19-90 KRS Module created.
  11. * 12-20-90 KRS Include ctype.h.
  12. * 03-20-91 KRS Ported from 16-bit tree.
  13. * 12-09-91 ETC Updated comments; move __mb_cur_max to nlsdata1.c;
  14. * add multithread.
  15. * 04-06-93 SKS Replace _CRTAPI* with _cdecl
  16. * 06-01-93 CFW Re-write; verify valid MB char, proper error return,
  17. * optimize, correct conversion bug.
  18. * 06-02-93 SRW ignore _INTL if _NTSUBSET_ defined.
  19. * 09-15-93 CFW Use ANSI conformant "__" names.
  20. * 09-27-93 GJF Merged NT SDK and Cuda versions.
  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. * 01-07-95 CFW Mac merge cleanup.
  26. * 02-06-95 CFW assert -> _ASSERTE.
  27. * 04-01-96 BWT POSIX work.
  28. * 06-25-96 GJF Replaced defined(_WIN32) with !defined(_MAC). Also,
  29. * polished format a bit.
  30. * 02-27-98 RKP Added 64 bit support.
  31. * 07-27-98 GJF Revised multithread support based on threadlocinfo
  32. * struct.
  33. * 05-17-99 PML Remove all Macintosh support.
  34. *
  35. *******************************************************************************/
  36. #if defined(_NTSUBSET_) || defined(_POSIX_)
  37. #include <nt.h>
  38. #include <ntrtl.h>
  39. #include <nturtl.h>
  40. #endif
  41. #include <internal.h>
  42. #include <locale.h>
  43. #include <setlocal.h>
  44. #include <cruntime.h>
  45. #include <stdlib.h>
  46. #include <ctype.h>
  47. #include <mtdll.h>
  48. #include <dbgint.h>
  49. /***
  50. *int mblen() - length of multibyte character
  51. *
  52. *Purpose:
  53. * Return the number of bytes contained in a multibyte character.
  54. * [ANSI].
  55. *
  56. *Entry:
  57. * const char *s = pointer to multibyte character
  58. * size_t n = maximum length of multibyte character to consider
  59. *
  60. *Exit:
  61. * If s = NULL, returns 0, indicating we use (only) state-independent
  62. * character encodings.
  63. *
  64. * If s != NULL, returns: 0 (if *s = null char),
  65. * -1 (if the next n or fewer bytes not valid
  66. * mbc),
  67. * number of bytes contained in multibyte char
  68. *
  69. *Exceptions:
  70. *
  71. *******************************************************************************/
  72. int __cdecl mblen
  73. (
  74. const char * s,
  75. size_t n
  76. )
  77. {
  78. #ifdef _MT
  79. pthreadlocinfo ptloci = _getptd()->ptlocinfo;
  80. if ( ptloci != __ptlocinfo )
  81. ptloci = __updatetlocinfo();
  82. _ASSERTE (ptloci->mb_cur_max == 1 || ptloci->mb_cur_max == 2);
  83. #else
  84. _ASSERTE (MB_CUR_MAX == 1 || MB_CUR_MAX == 2);
  85. #endif
  86. if ( !s || !(*s) || (n == 0) )
  87. /* indicate do not have state-dependent encodings,
  88. empty string length is 0 */
  89. return 0;
  90. #if !defined(_NTSUBSET_) && !defined(_POSIX_)
  91. #ifdef _MT
  92. if ( __isleadbyte_mt(ptloci, (unsigned char)*s) )
  93. #else
  94. if ( isleadbyte((unsigned char)*s) )
  95. #endif
  96. {
  97. /* multi-byte char */
  98. /* verify valid MB char */
  99. #ifdef _MT
  100. if ( ptloci->mb_cur_max <= 1 ||
  101. (int)n < ptloci->mb_cur_max ||
  102. MultiByteToWideChar( ptloci->lc_codepage,
  103. MB_PRECOMPOSED | MB_ERR_INVALID_CHARS,
  104. s,
  105. ptloci->mb_cur_max,
  106. NULL,
  107. 0 ) == 0 )
  108. #else
  109. if ( MB_CUR_MAX <= 1 ||
  110. (int)n < MB_CUR_MAX ||
  111. MultiByteToWideChar( __lc_codepage,
  112. MB_PRECOMPOSED | MB_ERR_INVALID_CHARS,
  113. s,
  114. MB_CUR_MAX,
  115. NULL,
  116. 0 ) == 0 )
  117. #endif
  118. /* bad MB char */
  119. return -1;
  120. else
  121. #ifdef _MT
  122. return ptloci->mb_cur_max;
  123. #else
  124. return MB_CUR_MAX;
  125. #endif
  126. }
  127. else {
  128. /* single byte char */
  129. /* verify valid SB char */
  130. #ifdef _MT
  131. if ( MultiByteToWideChar( __lc_codepage,
  132. #else
  133. if ( MultiByteToWideChar( __lc_codepage,
  134. #endif
  135. MB_PRECOMPOSED | MB_ERR_INVALID_CHARS,
  136. s,
  137. 1,
  138. NULL,
  139. 0 ) == 0 )
  140. return -1;
  141. return sizeof(char);
  142. }
  143. #else /* _NTSUBSET_ */
  144. {
  145. char *s1 = (char *)s;
  146. RtlAnsiCharToUnicodeChar( &s1 );
  147. return (int)(s1 - s);
  148. }
  149. #endif /* _NTSUBSET_ */
  150. }