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.

165 lines
5.1 KiB

  1. /***
  2. *xstrxfrm.c - Transform a string using locale information
  3. *
  4. * Copyright (c) 1996-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * Transform a string using the locale information as set by
  8. * LC_COLLATE.
  9. *
  10. *Revision History:
  11. * 01-XX-96 PJP Created from strxfrm.c January 1996 by P.J. Plauger
  12. * 04-18-96 GJF Updated for current locale locking. Also, reformatted
  13. * and made several cosmetic changes.
  14. * 03-17-97 RDK Added error flag to __crtLCMapStringA.
  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 <string.h>
  22. #include <xlocinfo.h> /* for _Collvec, _Strxfrm */
  23. #ifdef _WIN32
  24. #include <windows.h>
  25. #include <stdlib.h>
  26. #include <limits.h>
  27. #include <malloc.h>
  28. #include <locale.h>
  29. #include <setlocal.h>
  30. #include <awint.h>
  31. #include <mtdll.h>
  32. #endif /* _WIN32 */
  33. /* Define _CRTIMP2 */
  34. #ifndef _CRTIMP2
  35. #ifdef CRTDLL2
  36. #define _CRTIMP2 __declspec(dllexport)
  37. #else /* ndef CRTDLL2 */
  38. #ifdef _DLL
  39. #define _CRTIMP2 __declspec(dllimport)
  40. #else /* ndef _DLL */
  41. #define _CRTIMP2
  42. #endif /* _DLL */
  43. #endif /* CRTDLL2 */
  44. #endif /* _CRTIMP2 */
  45. /***
  46. *size_t _Strxfrm() - Transform a string using locale information
  47. *
  48. *Purpose:
  49. * Transform the string pointer to by _string2 and place the
  50. * resulting string into the array pointer to by _string1.
  51. * No more than _end1 - _string1 characters are place into the
  52. * resulting string (including the null).
  53. *
  54. * The transformation is such that if strcmp() is applied to
  55. * the two transformed strings, the return value is equal to
  56. * the result of strcoll() applied to the two original strings.
  57. * Thus, the conversion must take the locale LC_COLLATE info
  58. * into account.
  59. * [ANSI]
  60. *
  61. * The value of the following expression is the size of the array
  62. * needed to hold the transformation of the source string:
  63. *
  64. * 1 + strxfrm(NULL,string,0)
  65. *
  66. * NOTE: Currently, the C libraries support the "C" locale only.
  67. * Thus, _Strxfrm() simply resolves to strncpy()/strlen().
  68. *
  69. *Entry:
  70. * char *_string1 = pointer to beginning of result string
  71. * char *_end1 = pointer past end of result string
  72. * const char *_string2 = pointer to beginning of source string
  73. * const char *_end2 = pointer past end of source string
  74. * const _Collvec *ploc = pointer to locale info
  75. *
  76. *Exit:
  77. * Length of the transformed string.
  78. * If the value returned is too big, the contents of the
  79. * _string1 array are indeterminate.
  80. *
  81. *Exceptions:
  82. * Non-standard: if OM/API error, return INT_MAX.
  83. *
  84. *******************************************************************************/
  85. _CRTIMP2 size_t __cdecl _Strxfrm (
  86. char *_string1,
  87. char *_end1,
  88. const char *_string2,
  89. const char *_end2,
  90. const _Collvec *ploc
  91. )
  92. {
  93. size_t _n1 = _end1 - _string1;
  94. size_t _n2 = _end2 - _string2;
  95. #ifdef _WIN32
  96. int dstlen;
  97. int retval = INT_MAX; /* NON-ANSI: default if OM or API error */
  98. LCID handle;
  99. UINT codepage;
  100. #ifdef _MT
  101. int local_lock_flag;
  102. _lock_locale( local_lock_flag )
  103. #endif
  104. if (ploc == 0)
  105. {
  106. handle = __lc_handle[LC_COLLATE];
  107. codepage = __lc_collate_cp;
  108. }
  109. else
  110. {
  111. handle = ploc->_Hand;
  112. codepage = ploc->_Page;
  113. }
  114. if ((handle == _CLOCALEHANDLE) &&
  115. (codepage == _CLOCALECP))
  116. {
  117. _unlock_locale( local_lock_flag )
  118. #endif /* _WIN32 */
  119. if (_n2 <= _n1)
  120. memcpy(_string1, _string2, _n2);
  121. return _n2;
  122. #ifdef _WIN32
  123. }
  124. /* Inquire size of dst string in BYTES */
  125. if (0 == (dstlen = __crtLCMapStringA(handle,
  126. LCMAP_SORTKEY,
  127. _string2,
  128. (int)_n2,
  129. NULL,
  130. 0,
  131. codepage,
  132. TRUE)))
  133. goto error_cleanup;
  134. retval = dstlen;
  135. /* if not enough room, return amount needed */
  136. if (dstlen > (int)(_n1))
  137. goto error_cleanup;
  138. /* Map src string to dst string */
  139. if (0 == __crtLCMapStringA(handle,
  140. LCMAP_SORTKEY,
  141. _string2,
  142. (int)_n2,
  143. _string1,
  144. (int)_n1,
  145. codepage,
  146. TRUE))
  147. goto error_cleanup;
  148. error_cleanup:
  149. _unlock_locale( local_lock_flag )
  150. return (size_t)retval;
  151. #endif /* _WIN32 */
  152. }