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.

187 lines
6.5 KiB

  1. /***
  2. *wcsxfrm.c - Transform a wide-character string using locale information
  3. *
  4. * Copyright (c) 1988-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * Transform a wide-character string using the locale information as set by
  8. * LC_COLLATE.
  9. *
  10. *Revision History:
  11. * 09-09-91 ETC Created from strxfrm.c.
  12. * 12-09-91 ETC Updated api; Added multithread lock.
  13. * 12-18-91 ETC Changed back LCMAP_SORTKEYA --> LCMAP_SORTKEY.
  14. * 04-06-92 KRS Fix so it works without _INTL too.
  15. * 08-19-92 KRS Activate use of NLS API.
  16. * 09-02-92 SRW Get _INTL definition via ..\crt32.def
  17. * 12-15-92 KRS Fix return value to match ANSI/ISO Std.
  18. * 04-06-93 SKS Replace _CRTAPI* with __cdecl
  19. * 09-15-93 CFW Use ANSI conformant "__" names.
  20. * 09-22-93 CFW Use __crtxxx internal NLS API wrapper.
  21. * 09-23-93 CFW Complete re-write. Non-C locale totally broken.
  22. * 11-09-93 CFW Use LC_COLLATE code page for __crtxxx() conversion.
  23. * 02-07-94 CFW POSIXify.
  24. * 09-06-94 CFW Remove _INTL switch.
  25. * 10-25-94 GJF Sped up C locale, multi-thread case.
  26. * 01-10-95 CFW Debug CRT allocs.
  27. * 09-26-95 GJF New locking macro, and scheme, for functions which
  28. * reference the locale.
  29. * 10-11-95 BWT Fix NTSUBSET
  30. * 11-24-97 GJF Removed bogus codepage determination.
  31. * 01-12-98 GJF Use _lc_collate_cp codepage.
  32. * 07-16-98 GJF Revised multithread support based on threadlocinfo
  33. * struct. Also, use _alloca instead of _malloc_crt if
  34. * possible.
  35. * 01-04-99 GJF Changes for 64-bit size_t.
  36. * 04-30-99 PML Minor cleanup as part of 64-bit merge.
  37. * 12-10-99 GB Added support for recovery from stack overflow around
  38. * _alloca().
  39. * 10-12-00 GB Changed the function to be similar to strxfrm()
  40. *
  41. *******************************************************************************/
  42. #ifndef _POSIX_
  43. #include <cruntime.h>
  44. #include <windows.h>
  45. #include <string.h>
  46. #include <limits.h>
  47. #include <locale.h>
  48. #include <setlocal.h>
  49. #include <stdlib.h>
  50. #include <mtdll.h>
  51. #include <awint.h>
  52. #include <dbgint.h>
  53. #include <malloc.h>
  54. /***
  55. *size_t wcsxfrm() - Transform a string using locale information
  56. *
  57. *Purpose:
  58. * Transform the wide string pointed to by _string2 and place the
  59. * resulting wide string into the array pointed to by _string1.
  60. * No more than _count wide characters are placed into the
  61. * resulting string (including the null).
  62. *
  63. * The transformation is such that if wcscmp() is applied to
  64. * the two transformed strings, the return value is equal to
  65. * the result of wcscoll() applied to the two original strings.
  66. * Thus, the conversion must take the locale LC_COLLATE info
  67. * into account.
  68. *
  69. * In the C locale, wcsxfrm() simply resolves to wcsncpy()/wcslen().
  70. *
  71. *Entry:
  72. * wchar_t *_string1 = result string
  73. * const wchar_t *_string2 = source string
  74. * size_t _count = max wide chars to move
  75. *
  76. * [If _count is 0, _string1 is permitted to be NULL.]
  77. *
  78. *Exit:
  79. * Length of the transformed string (not including the terminating
  80. * null). If the value returned is >= _count, the contents of the
  81. * _string1 array are indeterminate.
  82. *
  83. *Exceptions:
  84. * Non-standard: if OM/API error, return INT_MAX.
  85. *
  86. *******************************************************************************/
  87. size_t __cdecl wcsxfrm (
  88. wchar_t *_string1,
  89. const wchar_t *_string2,
  90. size_t _count
  91. )
  92. {
  93. #ifdef _NTSUBSET_
  94. if (_string1)
  95. wcsncpy(_string1, _string2, _count);
  96. return wcslen(_string2);
  97. #else
  98. int size = INT_MAX;
  99. #ifdef _MT
  100. pthreadlocinfo ptloci;
  101. #endif
  102. if ( _count > INT_MAX )
  103. return (size_t)size;
  104. #ifdef _MT
  105. ptloci = _getptd()->ptlocinfo;
  106. if ( ptloci != __ptlocinfo )
  107. ptloci = __updatetlocinfo();
  108. if ( ptloci->lc_handle[LC_COLLATE] == _CLOCALEHANDLE )
  109. #else
  110. if ( __lc_handle[LC_COLLATE] == _CLOCALEHANDLE )
  111. #endif
  112. {
  113. wcsncpy(_string1, _string2, _count);
  114. return wcslen(_string2);
  115. }
  116. #ifdef _MT
  117. if ( 0 == (size = __crtLCMapStringW( ptloci->lc_handle[LC_COLLATE],
  118. #else
  119. if ( 0 == (size = __crtLCMapStringW( __lc_handle[LC_COLLATE],
  120. #endif
  121. LCMAP_SORTKEY,
  122. _string2,
  123. -1,
  124. NULL,
  125. 0,
  126. #ifdef _MT
  127. ptloci->lc_collate_cp )) )
  128. #else
  129. __lc_collate_cp )) )
  130. #endif
  131. {
  132. size = INT_MAX;
  133. } else
  134. {
  135. if ( (size_t)size <= _count)
  136. {
  137. #ifdef _MT
  138. if ( 0 == (size = __crtLCMapStringW( ptloci->lc_handle[LC_COLLATE],
  139. #else
  140. if ( 0 == (size = __crtLCMapStringW( __lc_handle[LC_COLLATE],
  141. #endif
  142. LCMAP_SORTKEY,
  143. _string2,
  144. -1,
  145. (wchar_t *)_string1,
  146. (int)_count,
  147. #ifdef _MT
  148. ptloci->lc_collate_cp )) )
  149. #else
  150. __lc_collate_cp )) )
  151. #endif
  152. {
  153. size = INT_MAX; /* default error */
  154. } else
  155. {
  156. // Note that the size that LCMapStringW returns for
  157. // LCMAP_SORTKEY is number of bytes needed. That's why it
  158. // is safe to convert the buffer to wide char from end.
  159. _count = size--;
  160. for (;_count-- > 0;)
  161. {
  162. _string1[_count] = (wchar_t)((unsigned char *)_string1)[_count];
  163. }
  164. }
  165. } else
  166. {
  167. size--;
  168. }
  169. }
  170. return (size_t)size;
  171. #endif /* _NTSUBSET_ */
  172. }
  173. #endif /* _POSIX_ */