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.

161 lines
5.2 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. * 05-17-99 PML Remove all Macintosh support.
  19. * 01-29-01 GB Added _func function version of data variable used in msvcprt.lib
  20. * to work with STATIC_CPPLIB
  21. *
  22. *******************************************************************************/
  23. #include <cruntime.h>
  24. #include <string.h>
  25. #include <xlocinfo.h> /* for _Collvec, _Strxfrm */
  26. #include <windows.h>
  27. #include <stdlib.h>
  28. #include <limits.h>
  29. #include <malloc.h>
  30. #include <locale.h>
  31. #include <setlocal.h>
  32. #include <awint.h>
  33. #include <mtdll.h>
  34. /* Define _CRTIMP2 */
  35. #ifndef _CRTIMP2
  36. #ifdef CRTDLL2
  37. #define _CRTIMP2 __declspec(dllexport)
  38. #else /* ndef CRTDLL2 */
  39. #ifdef _DLL
  40. #define _CRTIMP2 __declspec(dllimport)
  41. #else /* ndef _DLL */
  42. #define _CRTIMP2
  43. #endif /* _DLL */
  44. #endif /* CRTDLL2 */
  45. #endif /* _CRTIMP2 */
  46. /***
  47. *size_t _Strxfrm() - Transform a string using locale information
  48. *
  49. *Purpose:
  50. * Transform the string pointer to by _string2 and place the
  51. * resulting string into the array pointer to by _string1.
  52. * No more than _end1 - _string1 characters are place into the
  53. * resulting string (including the null).
  54. *
  55. * The transformation is such that if strcmp() is applied to
  56. * the two transformed strings, the return value is equal to
  57. * the result of strcoll() applied to the two original strings.
  58. * Thus, the conversion must take the locale LC_COLLATE info
  59. * into account.
  60. * [ANSI]
  61. *
  62. * The value of the following expression is the size of the array
  63. * needed to hold the transformation of the source string:
  64. *
  65. * 1 + strxfrm(NULL,string,0)
  66. *
  67. * NOTE: Currently, the C libraries support the "C" locale only.
  68. * Thus, _Strxfrm() simply resolves to strncpy()/strlen().
  69. *
  70. *Entry:
  71. * char *_string1 = pointer to beginning of result string
  72. * char *_end1 = pointer past end of result string
  73. * const char *_string2 = pointer to beginning of source string
  74. * const char *_end2 = pointer past end of source string
  75. * const _Collvec *ploc = pointer to locale info
  76. *
  77. *Exit:
  78. * Length of the transformed string.
  79. * If the value returned is too big, the contents of the
  80. * _string1 array are indeterminate.
  81. *
  82. *Exceptions:
  83. * Non-standard: if OM/API error, return INT_MAX.
  84. *
  85. *******************************************************************************/
  86. _CRTIMP2 size_t __cdecl _Strxfrm (
  87. char *_string1,
  88. char *_end1,
  89. const char *_string2,
  90. const char *_end2,
  91. const _Collvec *ploc
  92. )
  93. {
  94. size_t _n1 = _end1 - _string1;
  95. size_t _n2 = _end2 - _string2;
  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_func()[LC_COLLATE];
  107. codepage = ___lc_collate_cp_func();
  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. if (_n2 <= _n1)
  119. memcpy(_string1, _string2, _n2);
  120. return _n2;
  121. }
  122. /* Inquire size of dst string in BYTES */
  123. if (0 == (dstlen = __crtLCMapStringA(handle,
  124. LCMAP_SORTKEY,
  125. _string2,
  126. (int)_n2,
  127. NULL,
  128. 0,
  129. codepage,
  130. TRUE)))
  131. goto error_cleanup;
  132. retval = dstlen;
  133. /* if not enough room, return amount needed */
  134. if (dstlen > (int)(_n1))
  135. goto error_cleanup;
  136. /* Map src string to dst string */
  137. if (0 == __crtLCMapStringA(handle,
  138. LCMAP_SORTKEY,
  139. _string2,
  140. (int)_n2,
  141. _string1,
  142. (int)_n1,
  143. codepage,
  144. TRUE))
  145. goto error_cleanup;
  146. error_cleanup:
  147. _unlock_locale( local_lock_flag )
  148. return (size_t)retval;
  149. }