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.

223 lines
7.7 KiB

  1. /***
  2. *mbtowc.c - Convert multibyte char to wide char.
  3. *
  4. * Copyright (c) 1990-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * Convert a multibyte character into the equivalent wide character.
  8. *
  9. *Revision History:
  10. * 03-19-90 KRS Module created.
  11. * 12-20-90 KRS Put some intl stuff here for now...
  12. * 03-18-91 KRS Fixed bogus cast involving wchar_t. Fix copyright.
  13. * 03-20-91 KRS Ported from 16-bit tree.
  14. * 07-22-91 KRS C700 3525: Check for s==0 before calling mblen.
  15. * 07-23-91 KRS Hard-coded for "C" locale to avoid bogus interim #'s.
  16. * 10-15-91 ETC Locale support under _INTL (finally!).
  17. * 12-09-91 ETC Updated nlsapi; added multithread.
  18. * 08-20-92 KRS Activated NLSAPI support.
  19. * 08-31-92 SRW Allow INTL definition to be conditional for building ntcrt.lib
  20. * 09-02-92 SRW Get _INTL definition via ..\crt32.def
  21. * 04-06-93 SKS Replace _CRTAPI* with _cdecl
  22. * 04-26-93 CFW Remove unused variable.
  23. * 05-04-93 CFW Kinder, gentler error handling.
  24. * 06-01-93 CFW Re-write; verify valid MB char, proper error return,
  25. * optimize, fix bugs.
  26. * 06-02-93 SRW ignore _INTL if _NTSUBSET_ defined.
  27. * 09-15-93 CFW Use ANSI conformant "__" names.
  28. * 09-28-93 GJF Merged NT SDK and Cuda versions. Also, replace MTHREAD
  29. * with _MT.
  30. * 10-22-93 CFW Test for invalid MB chars using global preset flag.
  31. * 01-14-94 SRW if _NTSUBSET_ defined call Rtl functions
  32. * 02-03-94 GJF Merged in Steve Wood's latest change (affects
  33. * _NTSUBSET_ build only).
  34. * 02-07-94 CFW POSIXify.
  35. * 09-06-94 CFW Remove _INTL switch.
  36. * 10-18-94 BWT Fix build warning for call to RtlMultiByteToUnicodeN
  37. * 12-21-94 CFW Remove invalid MB chars NT 3.1 hack.
  38. * 01-07-95 CFW Mac merge cleanup.
  39. * 02-06-95 CFW assert -> _ASSERTE.
  40. * 04-19-95 CFW Rearrange & fix non-Win32 version.
  41. * 09-26-95 GJF New locking macro, and scheme, for functions which
  42. * reference the locale.
  43. * 04-01-96 BWT POSIX work.
  44. * 06-25-96 GJF Removed DLL_FOR_WIN32S. Replaced defined(_WIN32) with
  45. * !defined(_MAC). Polished the format a bit.
  46. * 07-27-98 GJF Revised multithread support based on threadlocinfo
  47. * struct.
  48. * 04-07-99 GJF Replace MT with _MT.
  49. * 05-17-99 PML Remove all Macintosh support.
  50. * 03-19-01 BWT Fix NTSUBSET to use RtlAnsiCharToUnicodeChar. MultiByteToUnicodeN
  51. * isn't tolerant of bogus buffers.
  52. *
  53. *******************************************************************************/
  54. #if defined(_NTSUBSET_) || defined(_POSIX_)
  55. #include <nt.h>
  56. #include <ntrtl.h>
  57. #include <nturtl.h>
  58. #endif
  59. #include <cruntime.h>
  60. #include <stdlib.h>
  61. #include <mtdll.h>
  62. #include <errno.h>
  63. #include <dbgint.h>
  64. #include <ctype.h>
  65. #include <internal.h>
  66. #include <locale.h>
  67. #include <setlocal.h>
  68. /***
  69. *int mbtowc() - Convert multibyte char to wide character.
  70. *
  71. *Purpose:
  72. * Convert a multi-byte character into the equivalent wide character,
  73. * according to the LC_CTYPE category of the current locale.
  74. * [ANSI].
  75. *
  76. * NOTE: Currently, the C libraries support the "C" locale only.
  77. * Non-C locale support now available under _INTL switch.
  78. *Entry:
  79. * wchar_t *pwc = pointer to destination wide character
  80. * const char *s = pointer to multibyte character
  81. * size_t n = maximum length of multibyte character to consider
  82. *
  83. *Exit:
  84. * If s = NULL, returns 0, indicating we only use state-independent
  85. * character encodings.
  86. * If s != NULL, returns: 0 (if *s = null char)
  87. * -1 (if the next n or fewer bytes not valid mbc)
  88. * number of bytes comprising converted mbc
  89. *
  90. *Exceptions:
  91. *
  92. *******************************************************************************/
  93. int __cdecl mbtowc(
  94. wchar_t *pwc,
  95. const char *s,
  96. size_t n
  97. )
  98. {
  99. #ifdef _MT
  100. pthreadlocinfo ptloci = _getptd()->ptlocinfo;
  101. if ( ptloci != __ptlocinfo )
  102. ptloci = __updatetlocinfo();
  103. return __mbtowc_mt(ptloci, pwc, s, n);
  104. }
  105. int __cdecl __mbtowc_mt (
  106. pthreadlocinfo ptloci,
  107. wchar_t *pwc,
  108. const char *s,
  109. size_t n
  110. )
  111. {
  112. _ASSERTE (ptloci->mb_cur_max == 1 || ptloci->mb_cur_max == 2);
  113. #else
  114. _ASSERTE (MB_CUR_MAX == 1 || MB_CUR_MAX == 2);
  115. #endif
  116. if ( !s || n == 0 )
  117. /* indicate do not have state-dependent encodings,
  118. handle zero length string */
  119. return 0;
  120. if ( !*s )
  121. {
  122. /* handle NULL char */
  123. if (pwc)
  124. *pwc = 0;
  125. return 0;
  126. }
  127. #if !defined(_NTSUBSET_) && !defined (_POSIX_)
  128. #ifdef _MT
  129. if ( ptloci->lc_handle[LC_CTYPE] == _CLOCALEHANDLE )
  130. #else
  131. if ( __lc_handle[LC_CTYPE] == _CLOCALEHANDLE )
  132. #endif
  133. {
  134. if (pwc)
  135. *pwc = (wchar_t)(unsigned char)*s;
  136. return sizeof(char);
  137. }
  138. #ifdef _MT
  139. if ( __isleadbyte_mt(ptloci, (unsigned char)*s) )
  140. {
  141. /* multi-byte char */
  142. if ( (ptloci->mb_cur_max <= 1) || ((int)n < ptloci->mb_cur_max) ||
  143. (MultiByteToWideChar( ptloci->lc_codepage,
  144. MB_PRECOMPOSED | MB_ERR_INVALID_CHARS,
  145. s,
  146. ptloci->mb_cur_max,
  147. pwc,
  148. (pwc) ? 1 : 0 ) == 0) )
  149. {
  150. /* validate high byte of mbcs char */
  151. if ( (n < (size_t)ptloci->mb_cur_max) || (!*(s + 1)) )
  152. {
  153. errno = EILSEQ;
  154. return -1;
  155. }
  156. }
  157. return ptloci->mb_cur_max;
  158. }
  159. #else
  160. if ( isleadbyte((unsigned char)*s) )
  161. {
  162. /* multi-byte char */
  163. if ( (MB_CUR_MAX <= 1) || ((int)n < MB_CUR_MAX) ||
  164. (MultiByteToWideChar( __lc_codepage,
  165. MB_PRECOMPOSED | MB_ERR_INVALID_CHARS,
  166. s,
  167. MB_CUR_MAX,
  168. pwc,
  169. (pwc) ? 1 : 0 ) == 0) )
  170. {
  171. /* validate high byte of mbcs char */
  172. if ( (n < (size_t)MB_CUR_MAX) || (!*(s + 1)) )
  173. {
  174. errno = EILSEQ;
  175. return -1;
  176. }
  177. }
  178. return MB_CUR_MAX;
  179. }
  180. #endif
  181. else {
  182. /* single byte char */
  183. #ifdef _MT
  184. if ( MultiByteToWideChar( ptloci->lc_codepage,
  185. #else
  186. if ( MultiByteToWideChar( __lc_codepage,
  187. #endif
  188. MB_PRECOMPOSED | MB_ERR_INVALID_CHARS,
  189. s,
  190. 1,
  191. pwc,
  192. (pwc) ? 1 : 0 ) == 0 )
  193. {
  194. errno = EILSEQ;
  195. return -1;
  196. }
  197. return sizeof(char);
  198. }
  199. #else /* _NTSUBSET_ */
  200. {
  201. char *s1 = (char *)s;
  202. *pwc = RtlAnsiCharToUnicodeChar(&s1);
  203. return((int)(s1-s));
  204. }
  205. #endif /* _NTSUBSET_/_POSIX_ */
  206. }