12 #include "WinCompat.h"
15 #include "PathHelpers.h"
17 /*************************************************************************
18 * LCMapStringEx (KERNEL32.@)
20 * Map characters in a locale sensitive string.
23 * name [I] Locale name for the conversion.
24 * flags [I] Flags controlling the mapping (LCMAP_ constants from "winnls.h")
25 * src [I] String to map
26 * srclen [I] Length of src in chars, or -1 if src is NUL terminated
27 * dst [O] Destination for mapped string
28 * dstlen [I] Length of dst in characters
29 * version [I] reserved, must be NULL
30 * reserved [I] reserved, must be NULL
31 * lparam [I] reserved, must be 0
34 * Success: The length of the mapped string in dst, including the NUL terminator.
35 * Failure: 0. Use GetLastError() to determine the cause.
37 WINPORT_DECL(LCMapStringEx
, INT
, (LPCWSTR name
, DWORD flags
, LPCWSTR src
, INT srclen
, LPWSTR dst
, INT dstlen
,
38 LPNLSVERSIONINFO version
, LPVOID reserved
, LPARAM lparam
))
43 if (!src
|| !srclen
|| dstlen
< 0)
45 WINPORT(SetLastError
)(ERROR_INVALID_PARAMETER
);
49 /* mutually exclusive flags */
50 if ((flags
& (LCMAP_LOWERCASE
| LCMAP_UPPERCASE
)) == (LCMAP_LOWERCASE
| LCMAP_UPPERCASE
) ||
51 (flags
& (LCMAP_HIRAGANA
| LCMAP_KATAKANA
)) == (LCMAP_HIRAGANA
| LCMAP_KATAKANA
) ||
52 (flags
& (LCMAP_HALFWIDTH
| LCMAP_FULLWIDTH
)) == (LCMAP_HALFWIDTH
| LCMAP_FULLWIDTH
) ||
53 (flags
& (LCMAP_TRADITIONAL_CHINESE
| LCMAP_SIMPLIFIED_CHINESE
)) == (LCMAP_TRADITIONAL_CHINESE
| LCMAP_SIMPLIFIED_CHINESE
))
55 WINPORT(SetLastError
)(ERROR_INVALID_FLAGS
);
59 if (!dstlen
) dst
= NULL
;
61 if (flags
& LCMAP_SORTKEY
)
66 WINPORT(SetLastError
)(ERROR_INVALID_FLAGS
);
70 if (srclen
< 0) srclen
= wcslen(src
);
72 ret
= wine_get_sortkey(flags
, src
, srclen
, (char *)dst
, dstlen
);
74 WINPORT(SetLastError
)(ERROR_INSUFFICIENT_BUFFER
);
80 /* SORT_STRINGSORT must be used exclusively with LCMAP_SORTKEY */
81 if (flags
& SORT_STRINGSORT
)
83 WINPORT(SetLastError
)(ERROR_INVALID_FLAGS
);
87 if (srclen
< 0) srclen
= wcslen(src
) + 1;
90 if (!dst
) /* return required string length */
94 for (len
= 0; srclen
; src
++, srclen
--)
97 /* tests show that win2k just ignores NORM_IGNORENONSPACE,
98 * and skips white space and punctuation characters for
101 if ((flags
& NORM_IGNORESYMBOLS
) && (iswspace(wch
) || iswpunct(wch
)))
108 if (flags
& LCMAP_UPPERCASE
)
110 for (dst_ptr
= dst
; srclen
&& dstlen
; src
++, srclen
--)
113 if ((flags
& NORM_IGNORESYMBOLS
) && (iswspace(wch
) || iswpunct(wch
)))
115 *dst_ptr
++ = towupper(wch
);
119 else if (flags
& LCMAP_LOWERCASE
)
121 for (dst_ptr
= dst
; srclen
&& dstlen
; src
++, srclen
--)
124 if ((flags
& NORM_IGNORESYMBOLS
) && (iswspace(wch
) || iswpunct(wch
)))
126 *dst_ptr
++ = towlower(wch
);
134 WINPORT(SetLastError
)(ERROR_INVALID_FLAGS
);
137 for (dst_ptr
= dst
; srclen
&& dstlen
; src
++, srclen
--)
140 if ((flags
& NORM_IGNORESYMBOLS
) && (iswspace(wch
) || iswpunct(wch
)))
149 WINPORT(SetLastError
)(ERROR_INSUFFICIENT_BUFFER
);
153 return dst_ptr
- dst
;
157 /******************************************************************************
158 * CompareStringEx (KERNEL32.@)
160 INT WINAPI
WINPORT(CompareStringEx
)(LPCWSTR locale
, DWORD flags
, LPCWSTR str1
, INT len1
,
161 LPCWSTR str2
, INT len2
, LPNLSVERSIONINFO version
, LPVOID reserved
, LPARAM lParam
)
163 DWORD supported_flags
= NORM_IGNORECASE
|NORM_IGNORENONSPACE
|NORM_IGNORESYMBOLS
|SORT_STRINGSORT
164 |NORM_IGNOREKANATYPE
|NORM_IGNOREWIDTH
|LOCALE_USE_CP_ACP
;
165 DWORD semistub_flags
= NORM_LINGUISTIC_CASING
|LINGUISTIC_IGNORECASE
|0x10000000;
166 /* 0x10000000 is related to diacritics in Arabic, Japanese, and Hebrew */
171 WINPORT(SetLastError
)(ERROR_INVALID_PARAMETER
);
175 if (flags
& ~(supported_flags
|semistub_flags
))
177 WINPORT(SetLastError
)(ERROR_INVALID_FLAGS
);
181 if (len1
< 0) len1
= wcslen(str1
);
182 if (len2
< 0) len2
= wcslen(str2
);
184 ret
= wine_compare_string(flags
, str1
, len1
, str2
, len2
);
186 if (ret
) /* need to translate result */
187 return (ret
< 0) ? CSTR_LESS_THAN
: CSTR_GREATER_THAN
;
191 WINPORT_DECL(CompareStringA
, int, ( LCID Locale
, DWORD dwCmpFlags
,
192 LPCSTR lpString1
, int cchCount1
, LPCSTR lpString2
, int cchCount2
))
194 if (cchCount1
==-1) cchCount1
= lpString1
? strlen(lpString1
) : 0;
195 if (cchCount2
==-1) cchCount2
= lpString2
? strlen(lpString2
) : 0;
196 std::vector
<WCHAR
> wstr1(cchCount1
* 2 + 1);
197 std::vector
<WCHAR
> wstr2(cchCount2
* 2 + 1);
198 int l1
= WINPORT(MultiByteToWideChar
)(CP_ACP
, 0, lpString1
, cchCount1
, &wstr1
[0], wstr1
.size() - 1 );
199 int l2
= WINPORT(MultiByteToWideChar
)(CP_ACP
, 0, lpString2
, cchCount2
, &wstr2
[0], wstr2
.size() - 1);
200 return WINPORT(CompareString
)( Locale
, dwCmpFlags
, &wstr1
[0], l1
, &wstr2
[0], l2
);
203 //////////////////////////
205 WINPORT_DECL(LCMapString
, INT
, (LCID lcid
, DWORD flags
, LPCWSTR src
, INT srclen
, LPWSTR dst
, INT dstlen
))
207 return WINPORT(LCMapStringEx
)(NULL
, flags
, src
, srclen
, dst
, dstlen
, NULL
, NULL
, 0);
211 WINPORT_DECL(CharLowerBuff
, DWORD
, ( LPWSTR str
, DWORD len
))
213 if (!str
) return 0; /* YES */
214 return WINPORT(LCMapString
)( LOCALE_USER_DEFAULT
, LCMAP_LOWERCASE
, str
, len
, str
, len
);
217 WINPORT_DECL(CharUpperBuff
, DWORD
, ( LPWSTR str
, DWORD len
))
219 if (!str
) return 0; /* YES */
220 return WINPORT(LCMapString
)( LOCALE_USER_DEFAULT
, LCMAP_UPPERCASE
, str
, len
, str
, len
);
223 WINPORT_DECL(IsCharLower
, BOOL
, (WCHAR ch
))
228 WINPORT_DECL(IsCharUpper
, BOOL
, (WCHAR ch
))
233 WINPORT_DECL(IsCharAlphaNumeric
, BOOL
, (WCHAR ch
))
238 WINPORT_DECL(IsCharAlpha
, BOOL
, (WCHAR ch
))
244 WINPORT_DECL(CompareString
, INT
, (LCID lcid
, DWORD flags
, LPCWSTR str1
, INT len1
, LPCWSTR str2
, INT len2
))
246 return WINPORT(CompareStringEx
)(NULL
, flags
, str1
, len1
, str2
, len2
, NULL
, NULL
, 0);
249 WINPORT_DECL(CharLower
, LPWSTR
, (LPWSTR str
))
251 if (!IS_INTRESOURCE( str
))
253 WINPORT(CharLowerBuff
)( str
, wcslen( str
));
258 WCHAR ch
= LOWORD( str
);
259 WINPORT(CharLowerBuff
)( &ch
, 1 );
260 return (LPWSTR
)(UINT_PTR
)ch
;
264 WINPORT_DECL(CharUpper
, LPWSTR
, (LPWSTR str
))
266 if (!IS_INTRESOURCE( str
))
268 WINPORT(CharUpperBuff
)( str
, wcslen( str
));
273 WCHAR ch
= LOWORD( str
);
274 WINPORT(CharUpperBuff
)( &ch
, 1 );
275 return (LPWSTR
)(UINT_PTR
)ch
;