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.

177 lines
5.5 KiB

  1. /***
  2. *wctomb.c - Convert wide character to multibyte character.
  3. *
  4. * Copyright (c) 1990-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * Convert a wide character into the equivalent multibyte character.
  8. *
  9. *Revision History:
  10. * 03-19-90 KRS Module created.
  11. * 12-20-90 KRS Include ctype.h.
  12. * 01-14-91 KRS Fix argument error: wchar is pass-by-value.
  13. * 03-20-91 KRS Ported from 16-bit tree.
  14. * 07-23-91 KRS Hard-coded for "C" locale to avoid bogus interim #'s.
  15. * 10-15-91 ETC Locale support under _INTL (finally!).
  16. * 12-09-91 ETC Updated nlsapi; added multithread.
  17. * 08-20-92 KRS Activated NLSAPI support.
  18. * 08-22-92 SRW Allow INTL definition to be conditional for building ntcrt.lib
  19. * 09-02-92 SRW Get _INTL definition via ..\crt32.def
  20. * 04-06-93 SKS Replace _CRTAPI* with _cdecl
  21. * 05-04-93 CFW Kinder, gentler error handling.
  22. * 06-01-93 CFW Minor optimization and beautify.
  23. * 06-02-93 SRW ignore _INTL if _NTSUBSET_ defined.
  24. * 09-15-93 CFW Use ANSI conformant "__" names.
  25. * 09-28-93 GJF Merged NT SDK and Cuda versions.
  26. * 01-14-94 SRW if _NTSUBSET_ defined call Rtl functions
  27. * 02-07-94 CFW POSIXify.
  28. * 09-06-94 CFW Remove _INTL switch.
  29. * 01-07-95 CFW Mac merge cleanup.
  30. * 04-19-95 CFW Rearrange & fix non-Win32 version.
  31. * 09-26-95 GJF New locking macro, and scheme, for functions which
  32. * reference the locale.
  33. * 12-07-95 SKS Fix misspelling of _NTSUBSET_ (final _ was missing)
  34. * 04-01-96 BWT POSIX work.
  35. * 06-25-96 GJF Removed DLL_FOR_WIN32S. Replaced defined(_WIN32) with
  36. * !defined(_MAC). Polished the format a bit.
  37. * 07-22-98 GJF Revised multithread support based on threadlocinfo
  38. * struct.
  39. * 04-28-99 GJF Changed dwFlags arg value to 0 in WideCharToMultiByte
  40. * calls to avoid problems with codepage 1258 on NT 5.0.
  41. * 05-17-99 PML Remove all Macintosh support.
  42. *
  43. *******************************************************************************/
  44. #if defined(_NTSUBSET_) || defined(_POSIX_)
  45. #include <nt.h>
  46. #include <ntrtl.h>
  47. #include <nturtl.h>
  48. #endif
  49. #include <cruntime.h>
  50. #include <stdlib.h>
  51. #include <mtdll.h>
  52. #include <errno.h>
  53. #include <locale.h>
  54. #include <setlocal.h>
  55. /***
  56. *int wctomb() - Convert wide character to multibyte character.
  57. *
  58. *Purpose:
  59. * Convert a wide character into the equivalent multi-byte character,
  60. * according to the LC_CTYPE category of the current locale.
  61. * [ANSI].
  62. *
  63. * NOTE: Currently, the C libraries support the "C" locale only.
  64. * Non-C locale support now available under _INTL switch.
  65. *Entry:
  66. * char *s = pointer to multibyte character
  67. * wchar_t wchar = source wide character
  68. *
  69. *Exit:
  70. * If s = NULL, returns 0, indicating we only use state-independent
  71. * character encodings.
  72. * If s != NULL, returns:
  73. * -1 (if error) or number of bytes comprising
  74. * converted mbc
  75. *
  76. *Exceptions:
  77. *
  78. *******************************************************************************/
  79. int __cdecl wctomb (
  80. char *s,
  81. wchar_t wchar
  82. )
  83. {
  84. #ifdef _MT
  85. pthreadlocinfo ptloci = _getptd()->ptlocinfo;
  86. if ( ptloci != __ptlocinfo )
  87. ptloci = __updatetlocinfo();
  88. return __wctomb_mt(ptloci, s, wchar);
  89. }
  90. int __cdecl __wctomb_mt (
  91. pthreadlocinfo ptloci,
  92. char *s,
  93. wchar_t wchar
  94. )
  95. {
  96. #endif
  97. if ( !s )
  98. /* indicate do not have state-dependent encodings */
  99. return 0;
  100. #if defined(_NTSUBSET_) || defined(_POSIX_)
  101. {
  102. NTSTATUS Status;
  103. int size;
  104. Status = RtlUnicodeToMultiByteN( s,
  105. MB_CUR_MAX,
  106. (PULONG)&size,
  107. &wchar,
  108. sizeof( wchar )
  109. );
  110. if (!NT_SUCCESS(Status))
  111. {
  112. errno = EILSEQ;
  113. size = -1;
  114. }
  115. return size;
  116. }
  117. #else /* _NTSUBSET_/_POSIX_ */
  118. #ifdef _MT
  119. if ( ptloci->lc_handle[LC_CTYPE] == _CLOCALEHANDLE )
  120. #else
  121. if ( __lc_handle[LC_CTYPE] == _CLOCALEHANDLE )
  122. #endif
  123. {
  124. if ( wchar > 255 ) /* validate high byte */
  125. {
  126. errno = EILSEQ;
  127. return -1;
  128. }
  129. *s = (char) wchar;
  130. return sizeof(char);
  131. }
  132. else
  133. {
  134. int size;
  135. BOOL defused = 0;
  136. #ifdef _MT
  137. if ( ((size = WideCharToMultiByte( ptloci->lc_codepage,
  138. #else
  139. if ( ((size = WideCharToMultiByte( __lc_codepage,
  140. #endif
  141. 0,
  142. &wchar,
  143. 1,
  144. s,
  145. #ifdef _MT
  146. ptloci->mb_cur_max,
  147. #else
  148. MB_CUR_MAX,
  149. #endif
  150. NULL,
  151. &defused) ) == 0) ||
  152. (defused) )
  153. {
  154. errno = EILSEQ;
  155. return -1;
  156. }
  157. return size;
  158. }
  159. #endif /* ! _NTSUBSET_/_POSIX_ */
  160. }