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.

144 lines
5.1 KiB

  1. /***
  2. *xwcsxfrm.c - Transform a wide-character string using locale information
  3. *
  4. * Copyright (c) 1996-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *
  7. *Purpose:
  8. * Transform a wide-character string using the locale information as set by
  9. * LC_COLLATE.
  10. *
  11. *Revision History:
  12. * 01-XX-96 PJP Created from wcsxfrm.c January 1996 by P.J. Plauger
  13. * 04-18-96 GJF Updated for current locale locking. Also, reformatted
  14. * and made several cosmetic changes.
  15. * 12-02-97 GJF Removed bogus codepage determination.
  16. * 01-12-98 GJF Use _lc_collate_cp codepage.
  17. * 01-05-99 GJF Changes for 64-bit size_t.
  18. * 01-29-01 GB Added _func function version of data variable used in msvcprt.lib
  19. * to work with STATIC_CPPLIB
  20. *
  21. *******************************************************************************/
  22. #include <cruntime.h>
  23. #include <windows.h>
  24. #include <string.h>
  25. #include <limits.h>
  26. #include <locale.h>
  27. #include <setlocal.h>
  28. #include <stdlib.h>
  29. #include <mtdll.h>
  30. #include <awint.h>
  31. #include <dbgint.h>
  32. #include <xlocinfo.h> /* for _Collvec, _Wcsxfrm */
  33. /***
  34. *size_t _Wcsxfrm() - Transform a string using locale information
  35. *
  36. *Purpose:
  37. * Transform the wide string pointed to by _string2 and place the
  38. * resulting wide string into the array pointed to by _string1.
  39. * No more than _end1 - _string1 wide characters are placed into the
  40. * resulting string (including the null).
  41. *
  42. * The transformation is such that if wcscmp() is applied to
  43. * the two transformed strings, the return value is equal to
  44. * the result of wcscoll() applied to the two original strings.
  45. * Thus, the conversion must take the locale LC_COLLATE info
  46. * into account.
  47. *
  48. * In the C locale, wcsxfrm() simply resolves to wcsncpy()/wcslen().
  49. *
  50. *Entry:
  51. * wchar_t *_string1 = pointer to beginning of result string
  52. * wchar_t *_end1 = pointer past end of result string
  53. * const wchar_t *_string2 = pointer to beginning of source string
  54. * const wchar_t *_end2 = pointer past end of source string
  55. * const _Collvec *ploc = pointer to locale info
  56. *
  57. *Exit:
  58. * Length of the transformed string.
  59. * If the value returned is too big, the contents of the
  60. * _string1 array are indeterminate.
  61. *
  62. *Exceptions:
  63. * Non-standard: if OM/API error, return INT_MAX.
  64. *
  65. *******************************************************************************/
  66. size_t __cdecl _Wcsxfrm (
  67. wchar_t *_string1,
  68. wchar_t *_end1,
  69. const wchar_t *_string2,
  70. const wchar_t *_end2,
  71. const _Collvec *ploc
  72. )
  73. {
  74. size_t _n1 = _end1 - _string1;
  75. size_t _n2 = _end2 - _string2;
  76. int size = INT_MAX;
  77. unsigned char *bbuffer;
  78. LCID handle;
  79. #ifdef _MT
  80. int local_lock_flag;
  81. _lock_locale( local_lock_flag )
  82. #endif
  83. if (ploc == 0)
  84. handle = ___lc_handle_func()[LC_COLLATE];
  85. else
  86. handle = ploc->_Hand;
  87. if (handle == _CLOCALEHANDLE) {
  88. _unlock_locale( local_lock_flag )
  89. if (_n2 <= _n1)
  90. memcpy(_string1, _string2, _n2 * sizeof (wchar_t));
  91. return _n2;
  92. }
  93. /*
  94. * When using LCMAP_SORTKEY, LCMapStringW handles BYTES not wide
  95. * chars. We use a byte buffer to hold bytes and then convert the
  96. * byte string to a wide char string and return this so it can be
  97. * compared using wcscmp(). User's buffer is _n1 wide chars, so
  98. * use an internal buffer of _n1 bytes.
  99. */
  100. if (NULL == (bbuffer = (unsigned char *)_malloc_crt(_n1)))
  101. goto error_cleanup;
  102. if (0 == (size = __crtLCMapStringW(handle,
  103. LCMAP_SORTKEY,
  104. _string2,
  105. (int)_n2,
  106. (wchar_t *)bbuffer,
  107. (int)_n1,
  108. ___lc_collate_cp_func())))
  109. {
  110. /* buffer not big enough, get size required. */
  111. if (0 == (size = __crtLCMapStringW(handle,
  112. LCMAP_SORTKEY,
  113. _string2,
  114. (int)_n2,
  115. NULL,
  116. 0,
  117. ___lc_collate_cp_func())))
  118. size = INT_MAX; /* default error */
  119. } else {
  120. int i;
  121. /* string successfully mapped, convert to wide char */
  122. for (i = 0; i < size; i++)
  123. _string1[i] = (wchar_t)bbuffer[i];
  124. }
  125. error_cleanup:
  126. _unlock_locale( local_lock_flag )
  127. _free_crt(bbuffer);
  128. return (size_t)size;
  129. }