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.

164 lines
5.6 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. * 04-29-02 GB Added try-finally arounds lock-unlock.
  22. *
  23. *******************************************************************************/
  24. #include <cruntime.h>
  25. #include <string.h>
  26. #include <xlocinfo.h> /* for _Collvec, _Strxfrm */
  27. #include <windows.h>
  28. #include <stdlib.h>
  29. #include <limits.h>
  30. #include <malloc.h>
  31. #include <locale.h>
  32. #include <setlocal.h>
  33. #include <awint.h>
  34. #include <mtdll.h>
  35. /* Define _CRTIMP2 */
  36. #ifndef _CRTIMP2
  37. #ifdef CRTDLL2
  38. #define _CRTIMP2 __declspec(dllexport)
  39. #else /* ndef CRTDLL2 */
  40. #ifdef _DLL
  41. #define _CRTIMP2 __declspec(dllimport)
  42. #else /* ndef _DLL */
  43. #define _CRTIMP2
  44. #endif /* _DLL */
  45. #endif /* CRTDLL2 */
  46. #endif /* _CRTIMP2 */
  47. /***
  48. *size_t _Strxfrm() - Transform a string using locale information
  49. *
  50. *Purpose:
  51. * Transform the string pointer to by _string2 and place the
  52. * resulting string into the array pointer to by _string1.
  53. * No more than _end1 - _string1 characters are place into the
  54. * resulting string (including the null).
  55. *
  56. * The transformation is such that if strcmp() is applied to
  57. * the two transformed strings, the return value is equal to
  58. * the result of strcoll() applied to the two original strings.
  59. * Thus, the conversion must take the locale LC_COLLATE info
  60. * into account.
  61. * [ANSI]
  62. *
  63. * The value of the following expression is the size of the array
  64. * needed to hold the transformation of the source string:
  65. *
  66. * 1 + strxfrm(NULL,string,0)
  67. *
  68. * NOTE: Currently, the C libraries support the "C" locale only.
  69. * Thus, _Strxfrm() simply resolves to strncpy()/strlen().
  70. *
  71. *Entry:
  72. * char *_string1 = pointer to beginning of result string
  73. * char *_end1 = pointer past end of result string
  74. * const char *_string2 = pointer to beginning of source string
  75. * const char *_end2 = pointer past end of source string
  76. * const _Collvec *ploc = pointer to locale info
  77. *
  78. *Exit:
  79. * Length of the transformed string.
  80. * If the value returned is too big, 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. _CRTIMP2 size_t __cdecl _Strxfrm (
  88. char *_string1,
  89. char *_end1,
  90. const char *_string2,
  91. const char *_end2,
  92. const _Collvec *ploc
  93. )
  94. {
  95. size_t _n1 = _end1 - _string1;
  96. size_t _n2 = _end2 - _string2;
  97. int dstlen;
  98. int retval = INT_MAX; /* NON-ANSI: default if OM or API error */
  99. LCID handle;
  100. UINT codepage;
  101. #ifdef _MT
  102. int local_lock_flag;
  103. _lock_locale( local_lock_flag )
  104. #endif
  105. __TRY
  106. if (ploc == 0)
  107. {
  108. handle = ___lc_handle_func()[LC_COLLATE];
  109. codepage = ___lc_collate_cp_func();
  110. }
  111. else
  112. {
  113. handle = ploc->_Hand;
  114. codepage = ploc->_Page;
  115. }
  116. if ((handle == _CLOCALEHANDLE) &&
  117. (codepage == _CLOCALECP))
  118. {
  119. if (_n2 <= _n1)
  120. memcpy(_string1, _string2, _n2);
  121. return _n2;
  122. }
  123. /* Inquire size of dst string in BYTES */
  124. if (0 == (dstlen = __crtLCMapStringA(handle,
  125. LCMAP_SORTKEY,
  126. _string2,
  127. (int)_n2,
  128. NULL,
  129. 0,
  130. codepage,
  131. TRUE)))
  132. goto error_cleanup;
  133. retval = dstlen;
  134. /* if not enough room, return amount needed */
  135. if (dstlen > (int)(_n1))
  136. goto error_cleanup;
  137. /* Map src string to dst string */
  138. if (0 == __crtLCMapStringA(handle,
  139. LCMAP_SORTKEY,
  140. _string2,
  141. (int)_n2,
  142. _string1,
  143. (int)_n1,
  144. codepage,
  145. TRUE))
  146. goto error_cleanup;
  147. error_cleanup:;
  148. __FINALLY
  149. _unlock_locale( local_lock_flag )
  150. __END_TRY_FINALLY
  151. return (size_t)retval;
  152. }