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.

142 lines
4.8 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. *
  19. *******************************************************************************/
  20. #include <cruntime.h>
  21. #include <windows.h>
  22. #include <string.h>
  23. #include <limits.h>
  24. #include <locale.h>
  25. #include <setlocal.h>
  26. #include <stdlib.h>
  27. #include <mtdll.h>
  28. #include <awint.h>
  29. #include <dbgint.h>
  30. #include <xlocinfo.h> /* for _Collvec, _Wcsxfrm */
  31. /***
  32. *size_t _Wcsxfrm() - Transform a string using locale information
  33. *
  34. *Purpose:
  35. * Transform the wide string pointed to by _string2 and place the
  36. * resulting wide string into the array pointed to by _string1.
  37. * No more than _end1 - _string1 wide characters are placed into the
  38. * resulting string (including the null).
  39. *
  40. * The transformation is such that if wcscmp() is applied to
  41. * the two transformed strings, the return value is equal to
  42. * the result of wcscoll() applied to the two original strings.
  43. * Thus, the conversion must take the locale LC_COLLATE info
  44. * into account.
  45. *
  46. * In the C locale, wcsxfrm() simply resolves to wcsncpy()/wcslen().
  47. *
  48. *Entry:
  49. * wchar_t *_string1 = pointer to beginning of result string
  50. * wchar_t *_end1 = pointer past end of result string
  51. * const wchar_t *_string2 = pointer to beginning of source string
  52. * const wchar_t *_end2 = pointer past end of source string
  53. * const _Collvec *ploc = pointer to locale info
  54. *
  55. *Exit:
  56. * Length of the transformed string.
  57. * If the value returned is too big, the contents of the
  58. * _string1 array are indeterminate.
  59. *
  60. *Exceptions:
  61. * Non-standard: if OM/API error, return INT_MAX.
  62. *
  63. *******************************************************************************/
  64. size_t __cdecl _Wcsxfrm (
  65. wchar_t *_string1,
  66. wchar_t *_end1,
  67. const wchar_t *_string2,
  68. const wchar_t *_end2,
  69. const _Collvec *ploc
  70. )
  71. {
  72. size_t _n1 = _end1 - _string1;
  73. size_t _n2 = _end2 - _string2;
  74. int size = INT_MAX;
  75. unsigned char *bbuffer;
  76. LCID handle;
  77. #ifdef _MT
  78. int local_lock_flag;
  79. _lock_locale( local_lock_flag )
  80. #endif
  81. if (ploc == 0)
  82. handle = __lc_handle[LC_COLLATE];
  83. else
  84. handle = ploc->_Hand;
  85. if (handle == _CLOCALEHANDLE) {
  86. _unlock_locale( local_lock_flag )
  87. if (_n2 <= _n1)
  88. memcpy(_string1, _string2, _n2 * sizeof (wchar_t));
  89. return _n2;
  90. }
  91. /*
  92. * When using LCMAP_SORTKEY, LCMapStringW handles BYTES not wide
  93. * chars. We use a byte buffer to hold bytes and then convert the
  94. * byte string to a wide char string and return this so it can be
  95. * compared using wcscmp(). User's buffer is _n1 wide chars, so
  96. * use an internal buffer of _n1 bytes.
  97. */
  98. if (NULL == (bbuffer = (unsigned char *)_malloc_crt(_n1)))
  99. goto error_cleanup;
  100. if (0 == (size = __crtLCMapStringW(handle,
  101. LCMAP_SORTKEY,
  102. _string2,
  103. (int)_n2,
  104. (wchar_t *)bbuffer,
  105. (int)_n1,
  106. __lc_collate_cp)))
  107. {
  108. /* buffer not big enough, get size required. */
  109. if (0 == (size = __crtLCMapStringW(handle,
  110. LCMAP_SORTKEY,
  111. _string2,
  112. (int)_n2,
  113. NULL,
  114. 0,
  115. __lc_collate_cp)))
  116. size = INT_MAX; /* default error */
  117. } else {
  118. int i;
  119. /* string successfully mapped, convert to wide char */
  120. for (i = 0; i < size; i++)
  121. _string1[i] = (wchar_t)bbuffer[i];
  122. }
  123. error_cleanup:
  124. _unlock_locale( local_lock_flag )
  125. _free_crt(bbuffer);
  126. return (size_t)size;
  127. }