ReactOS 0.4.16-dev-737-g3368adc
CompareStringA.cpp
Go to the documentation of this file.
1/***
2*a_cmp.c - A version of CompareString.
3*
4* Copyright (c) Microsoft Corporation. All rights reserved.
5*
6*Purpose:
7* Use either CompareStringA or CompareStringW depending on which is
8* available
9*
10*******************************************************************************/
11#include <corecrt_internal.h>
12
13
14
15/***
16*int __cdecl __acrt_CompareStringA - Get type information about an ANSI string.
17*
18*Purpose:
19* Internal support function. Assumes info in ANSI string format. Tries
20* to use NLS API call CompareStringA if available and uses CompareStringW
21* if it must. If neither are available it fails and returns 0.
22*
23*Entry:
24* LPCWSTR LocaleName - locale context for the comparison.
25* DWORD dwCmpFlags - see NT\Chicago docs
26* LPCSTR lpStringn - multibyte string to be compared
27* int cchCountn - char (byte) count (NOT including nullptr)
28* (-1 if nullptr terminated)
29* int code_page - for MB/WC conversion. If 0, use __lc_codepage
30*
31*Exit:
32* Success: 1 - if lpString1 < lpString2
33* 2 - if lpString1 == lpString2
34* 3 - if lpString1 > lpString2
35* Failure: 0
36*
37*Exceptions:
38*
39*******************************************************************************/
40
44 DWORD dwCmpFlags,
45 PCCH lpString1,
46 int cchCount1,
47 PCCH lpString2,
48 int cchCount2,
49 int code_page
50 ) throw()
51{
52 /*
53 * CompareString will compare past nullptr. Must find nullptr if in string
54 * before cchCountn chars.
55 */
56
57 if (cchCount1 > 0)
58 cchCount1 = static_cast<int>(__strncnt(lpString1, cchCount1));
59 else if (cchCount1 < -1)
60 return FALSE;
61
62 if (cchCount2 > 0)
63 cchCount2 = static_cast<int>(__strncnt(lpString2, cchCount2));
64 else if (cchCount2 < -1)
65 return FALSE;
66
67
68 int buff_size1;
69 int buff_size2;
70
71 /*
72 * Use __lc_codepage for conversion if code_page not specified
73 */
74
75 if (0 == code_page)
76 code_page = plocinfo->locinfo->_public._locale_lc_codepage;
77
78 /*
79 * Special case: at least one count is zero
80 */
81
82 if (!cchCount1 || !cchCount2)
83 {
84 unsigned char *cp; // char pointer
85 CPINFO cpInfo; // struct for use with GetCPInfo
86
87 /* both strings zero */
88 if (cchCount1 == cchCount2)
89 return 2;
90
91 /* string 1 greater */
92 if (cchCount2 > 1)
93 return 1;
94
95 /* string 2 greater */
96 if (cchCount1 > 1)
97 return 3;
98
99 /*
100 * one has zero count, the other has a count of one
101 * - if the one count is a naked lead byte, the strings are equal
102 * - otherwise it is a single character and they are unequal
103 */
104
105 if (GetCPInfo(code_page, &cpInfo) == FALSE)
106 return 0;
107
108 _ASSERTE(cchCount1==0 && cchCount2==1 || cchCount1==1 && cchCount2==0);
109
110 /* string 1 has count of 1 */
111 if (cchCount1 > 0)
112 {
113 if (cpInfo.MaxCharSize < 2)
114 return 3;
115
116 for ( cp = (unsigned char *)cpInfo.LeadByte ;
117 cp[0] && cp[1] ;
118 cp += 2 )
119 if ( (*(unsigned char *)lpString1 >= cp[0]) &&
120 (*(unsigned char *)lpString1 <= cp[1]) )
121 return 2;
122
123 return 3;
124 }
125
126 /* string 2 has count of 1 */
127 if (cchCount2 > 0)
128 {
129 if (cpInfo.MaxCharSize < 2)
130 return 1;
131
132 for ( cp = (unsigned char *)cpInfo.LeadByte ;
133 cp[0] && cp[1] ;
134 cp += 2 )
135 if ( (*(unsigned char *)lpString2 >= cp[0]) &&
136 (*(unsigned char *)lpString2 <= cp[1]) )
137 return 2;
138
139 return 1;
140 }
141 }
142
143 /*
144 * Convert strings and return the requested information.
145 */
146
147 /* find out how big a buffer we need (includes nullptr if any) */
148 if ( 0 == (buff_size1 = __acrt_MultiByteToWideChar( code_page,
151 lpString1,
152 cchCount1,
153 nullptr,
154 0 )) )
155 return 0;
156
157 /* allocate enough space for chars */
158 __crt_scoped_stack_ptr<wchar_t> wbuffer1(_malloca_crt_t(wchar_t, buff_size1));
159 if (wbuffer1.get() == nullptr)
160 return 0;
161
162 /* do the conversion */
163 if ( 0 == __acrt_MultiByteToWideChar( code_page,
165 lpString1,
166 cchCount1,
167 wbuffer1.get(),
168 buff_size1 ) )
169 return 0;
170
171 /* find out how big a buffer we need (includes nullptr if any) */
172 if ( 0 == (buff_size2 = __acrt_MultiByteToWideChar( code_page,
175 lpString2,
176 cchCount2,
177 nullptr,
178 0 )) )
179 return 0;
180
181 /* allocate enough space for chars */
182 __crt_scoped_stack_ptr<wchar_t> const wbuffer2(_malloca_crt_t(wchar_t, buff_size2));
183 if (wbuffer2.get() == nullptr)
184 return 0;
185
186 int const actual_size = __acrt_MultiByteToWideChar(
187 code_page,
189 lpString2,
190 cchCount2,
191 wbuffer2.get(),
192 buff_size2);
193
194 if (actual_size == 0)
195 return 0;
196
199 dwCmpFlags,
200 wbuffer1.get(),
201 buff_size1,
202 wbuffer2.get(),
203 buff_size2,
204 nullptr,
205 nullptr,
206 0);
207}
208
210 _locale_t const locale,
211 LPCWSTR const locale_name,
212 DWORD const compare_flags,
213 PCCH const string1,
214 int const string1_count,
215 PCCH const string2,
216 int const string2_count,
217 int const code_page
218 )
219{
220 _LocaleUpdate locale_update(locale);
221
223 locale_update.GetLocaleT(),
225 compare_flags,
226 string1,
227 string1_count,
228 string2,
229 string2_count,
231 );
232}
int __cdecl __acrt_CompareStringA(_locale_t const locale, LPCWSTR const locale_name, DWORD const compare_flags, PCCH const string1, int const string1_count, PCCH const string2, int const string2_count, int const code_page)
static int __cdecl InternalCompareStringA(_locale_t plocinfo, LPCWSTR LocaleName, DWORD dwCmpFlags, PCCH lpString1, int cchCount1, PCCH lpString2, int cchCount2, int code_page)
static _In_ LPCWSTR LocaleName
#define __cdecl
Definition: accygwin.h:79
Definition: _locale.h:75
_Out_opt_ UINT * code_page
int WINAPI __acrt_CompareStringEx(_In_opt_ LPCWSTR locale_name, _In_ DWORD flags, _In_NLS_string_(string1_count) LPCWCH string1, _In_ int string1_count, _In_NLS_string_(string2_count) LPCWCH string2, _In_ int string2_count, _Reserved_ LPNLSVERSIONINFO version, _Reserved_ LPVOID reserved, _Reserved_ LPARAM param)
#define _ASSERTE(expr)
Definition: crtdbg.h:114
#define FALSE
Definition: types.h:117
BOOL WINAPI GetCPInfo(UINT codepage, LPCPINFO cpinfo)
Definition: locale.c:2144
unsigned long DWORD
Definition: ntddk_ex.h:95
#define MB_ERR_INVALID_CHARS
Definition: unicode.h:41
_CRTIMP size_t __cdecl __strncnt(const char *_Str, size_t _Cnt)
Definition: strncnt.cpp:13
_locale_t plocinfo
Definition: ismbbyte.cpp:75
POINT cp
Definition: magnifier.c:59
static CHAR string1[MAX_PATH]
Definition: asmname.c:32
static CHAR string2[MAX_PATH]
Definition: automation.c:345
CONST CHAR * PCCH
Definition: ntbasedef.h:400
BYTE LeadByte[MAX_LEADBYTES]
Definition: winnls.h:585
UINT MaxCharSize
Definition: winnls.h:583
pthreadlocinfo locinfo
Definition: corecrt.h:23
#define MB_PRECOMPOSED
Definition: winnls.h:283
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185