Reactos
1/***
2*strxfrm.c - Transform a string using locale information
3*
4* Copyright (c) Microsoft Corporation. All rights reserved.
5*
6*Purpose:
7* Transform a string using the locale information as set by
8* LC_COLLATE.
9*
10*******************************************************************************/
11#include <corecrt_internal.h>
12#include <ctype.h>
13#include <locale.h>
14#include <string.h>
15
16/***
17*size_t strxfrm() - Transform a string using locale information
18*
19*Purpose:
20* Transform the string pointed to by _string2 and place the
21* resulting string into the array pointed to by _string1.
22* No more than _count characters are place into the
23* resulting string (including the null).
24*
25* The transformation is such that if strcmp() is applied to
26* the two transformed strings, the return value is equal to
27* the result of strcoll() applied to the two original strings.
28* Thus, the conversion must take the locale LC_COLLATE info
29* into account.
30* [ANSI]
31*
32* The value of the following expression is the size of the array
33* needed to hold the transformation of the source string:
34*
35* 1 + strxfrm(nullptr,string,0)
36*
37*Entry:
38* char *_string1 = result string
39* const char *_string2 = source string
40* size_t _count = max chars to move
41*
42* [If _count is 0, _string1 is permitted to be nullptr.]
43*
44*Exit:
45* Length of the transformed string (not including the terminating
46* null). If the value returned is >= _count, the contents of the
47* _string1 array are indeterminate.
48*
49*Exceptions:
50* Non-standard: if OM/API error, return INT_MAX.
51* Input parameters are validated. Refer to the validation section of the function.
52*
53*******************************************************************************/
54
55extern "C" size_t __cdecl _strxfrm_l (
56 char *_string1,
57 const char *_string2,
58 size_t _count,
59 _locale_t plocinfo
60 )
61{
62 int dstlen;
63 size_t retval = INT_MAX; /* NON-ANSI: default if OM or API error */
64 _LocaleUpdate _loc_update(plocinfo);
65
66 /* validation section */
67 _VALIDATE_RETURN(_count <= INT_MAX, EINVAL, INT_MAX);
68 _VALIDATE_RETURN(_string1 != nullptr || _count == 0, EINVAL, INT_MAX);
69 _VALIDATE_RETURN(_string2 != nullptr, EINVAL, INT_MAX);
70
71 /* pre-init output in case of error */
72 if(_string1!=nullptr && _count>0)
73 {
74 *_string1='\0';
75 }
76
77 if ( (_loc_update.GetLocaleT()->locinfo->locale_name[LC_COLLATE] == nullptr) &&
78 (_loc_update.GetLocaleT()->locinfo->lc_collate_cp == CP_ACP) )
79 {
80_BEGIN_SECURE_CRT_DEPRECATION_DISABLE
81 strncpy(_string1, _string2, _count);
82_END_SECURE_CRT_DEPRECATION_DISABLE
83 return strlen(_string2);
84 }
85
86 /* Inquire size of dst string in BYTES */
87 if ( 0 == (dstlen = __acrt_LCMapStringA(
88 _loc_update.GetLocaleT(),
89 _loc_update.GetLocaleT()->locinfo->locale_name[LC_COLLATE],
90 LCMAP_SORTKEY,
91 _string2,
92 -1,
93 nullptr,
94 0,
95 _loc_update.GetLocaleT()->locinfo->lc_collate_cp,
96 TRUE )) )
97 {
98 errno = EILSEQ;
99 return INT_MAX;
100 }
101
102 retval = (size_t)dstlen;
103
104 /* if not enough room, return amount needed */
105 if ( retval > _count )
106 {
107 if (_string1 != nullptr && _count > 0)
108 {
109 *_string1 = '\0';
110 errno = ERANGE;
111 }
112 /* the return value is the string length (without the terminating 0) */
113 retval--;
114 return retval;
115 }
116
117 /* Map src string to dst string */
118 if ( 0 == __acrt_LCMapStringA(
119 _loc_update.GetLocaleT(),
120 _loc_update.GetLocaleT()->locinfo->locale_name[LC_COLLATE],
121 LCMAP_SORTKEY,
122 _string2,
123 -1,
124 _string1,
125 (int)_count,
126 _loc_update.GetLocaleT()->locinfo->lc_collate_cp,
127 TRUE ) )
128 {
129 errno = EILSEQ;
130 return INT_MAX;
131 }
132 /* the return value is the string length (without the terminating 0) */
133 retval--;
134
135 return retval;
136}
137
138extern "C" size_t __cdecl strxfrm (
139 char *_string1,
140 const char *_string2,
141 size_t _count
142 )
143{
144
145 return _strxfrm_l(_string1, _string2, _count, nullptr);
146
147}