#include <stdlib.h>
#include <wchar.h>
#include <strsafe.h>
+#include <stdio.h>
#include <errno.h>
#include "cm_nls.h"
#define AFS_NORM_FORM NormalizationC
+static LCID nls_lcid = LOCALE_INVARIANT;
+
+static int nls_init = 0;
+
+static BOOL
+is_windows_2000 (void)
+{
+ static BOOL fChecked = FALSE;
+ static BOOL fIsWin2K = FALSE;
+
+ if (!fChecked)
+ {
+ OSVERSIONINFO Version;
+
+ memset (&Version, 0x00, sizeof(Version));
+ Version.dwOSVersionInfoSize = sizeof(Version);
+
+ if (GetVersionEx (&Version))
+ {
+ if (Version.dwPlatformId == VER_PLATFORM_WIN32_NT &&
+ Version.dwMajorVersion >= 5)
+ fIsWin2K = TRUE;
+ }
+ fChecked = TRUE;
+ }
+
+ return fIsWin2K;
+}
+
long cm_InitNormalization(void)
{
HMODULE h_Nls;
(WINAPI *)( NORM_FORM, LPCWSTR, int ))
GetProcAddress(h_Nls, "IsNormalizedString");
+ if (is_windows_2000())
+ nls_lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
+
+ nls_init = 1;
+
return (pNormalizeString && pIsNormalizedString);
}
static wchar_t *
NormalizeUtf16String(const wchar_t * src, int cch_src, wchar_t * ext_dest, int *pcch_dest)
{
+ if (!nls_init)
+ cm_InitNormalization();
+
#ifdef DEBUG_UNICODE
assert (pNormalizeString != NULL && pIsNormalizedString != NULL);
#endif
int cch_dest = 0;
cm_normchar_t * r;
+ if (!nls_init)
+ cm_InitNormalization();
+
if (s == NULL || cch_src == 0 || *s == L'\0') {
if (pcch_dest)
*pcch_dest = ((cch_src != 0)? 1: 0);
int tcch = cch_dest;
cm_normchar_t * r;
+ if (!nls_init)
+ cm_InitNormalization();
+
r = NormalizeUtf16String(s, cch_src, dest, &tcch);
if (r != dest) {
int cch_dest;
cm_utf8char_t * dest;
+ if (!nls_init)
+ cm_InitNormalization();
+
if (s == NULL || cch_src == 0 || *s == L'\0') {
if (pcch_dest)
*pcch_dest = ((cch_src != 0)?1:0);
int cm_Utf16ToUtf8(const cm_unichar_t * src, int cch_src,
cm_utf8char_t * dest, int cch_dest)
{
+ if (!nls_init)
+ cm_InitNormalization();
+
return WideCharToMultiByte(CP_UTF8, 0, src, cch_src, dest, cch_dest, NULL, FALSE);
}
int cm_Utf16ToUtf16(const cm_unichar_t * src, int cch_src,
cm_unichar_t * dest, int cch_dest)
{
+ if (!nls_init)
+ cm_InitNormalization();
+
if (cch_src == -1) {
StringCchCopyW(dest, cch_dest, src);
return wcslen(dest) + 1;
long cm_NormalizeUtf16StringToUtf8(const wchar_t * src, int cch_src,
char * adest, int cch_adest)
{
+ if (!nls_init)
+ cm_InitNormalization();
+
if (cch_src < 0) {
size_t cch;
char * odest, int cch_dest)
{
char * dest = odest;
+
+ if (!nls_init)
+ cm_InitNormalization();
+
while (cch_src > 0 && *src && cch_dest > 0) {
unsigned short rc;
int cch;
int cch_norm;
+ if (!nls_init)
+ cm_InitNormalization();
+
/* Get some edge cases out first, so we don't have to worry about
cch_src being 0 etc. */
if (cch_src == 0) {
int cch;
int cch_norm;
+ if (!nls_init)
+ cm_InitNormalization();
+
/* Get some edge cases out first, so we don't have to worry about
cch_src being 0 etc. */
if (cch_src == 0 || src == NULL || *src == '\0') {
{
int cch;
+ if (!nls_init)
+ cm_InitNormalization();
+
if (cch_src == -1) {
cch_src = strlen(src) + 1;
}
cm_unichar_t * ustr = NULL;
int cch;
+ if (!nls_init)
+ cm_InitNormalization();
+
if (cch_src == 0 || src == NULL || *src == '\0') {
if (pcch_dest)
*pcch_dest = ((cch_src != 0)? 1 : 0);
int cch;
int cch_norm;
+ if (!nls_init)
+ cm_InitNormalization();
+
/* Get some edge cases out first, so we don't have to worry about
cch_src being 0 etc. */
if (cch_src == 0) {
wchar_t wstr2[NLSMAXCCH];
int rv;
+ if (!nls_init)
+ cm_InitNormalization();
+
/* first check for NULL pointers (assume NULL < "") */
if (str1 == NULL) {
if (str2 == NULL)
wstr2[0] = L'\0';
}
- rv = CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, wstr1, len1, wstr2, len2);
+ rv = CompareStringW(nls_lcid, NORM_IGNORECASE, wstr1, len1, wstr2, len2);
if (rv > 0)
return (rv - 2);
else {
size_t cch1;
size_t cch2;
+ if (!nls_init)
+ cm_InitNormalization();
+
/* first check for NULL pointers */
if (str1 == NULL) {
if (str2 == NULL)
if (FAILED(StringCchLengthW(str2, len, &cch2)))
cch2 = len;
- rv = CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, str1, cch1, str2, cch2);
+ rv = CompareStringW(nls_lcid, NORM_IGNORECASE, str1, cch1, str2, cch2);
if (rv > 0)
return (rv - 2);
else {
{
int rv;
+ if (!nls_init)
+ cm_InitNormalization();
+
/* first check for NULL pointers */
if (str1 == NULL) {
if (str2 == NULL)
return 1;
}
- rv = CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, str1, -1, str2, -1);
+ rv = CompareStringW(nls_lcid, NORM_IGNORECASE, str1, -1, str2, -1);
if (rv > 0)
return (rv - 2);
else {
int rv;
int len;
+ if (!nls_init)
+ cm_InitNormalization();
+
len = wcslen(str) + 1;
- rv = LCMapStringW(LOCALE_INVARIANT, LCMAP_LOWERCASE, str, len, str, len);
+ rv = LCMapStringW(nls_lcid, LCMAP_LOWERCASE, str, len, str, len);
#ifdef DEBUG
if (rv == 0) {
DebugBreak();
int rv;
int len;
+ if (!nls_init)
+ cm_InitNormalization();
+
len = wcslen(str) + 1;
- rv = LCMapStringW(LOCALE_INVARIANT, LCMAP_UPPERCASE, str, len, str, len);
+ rv = LCMapStringW(nls_lcid, LCMAP_UPPERCASE, str, len, str, len);
#ifdef DEBUG
if (rv == 0) {
DebugBreak();
wchar_t wstr2[NLSMAXCCH];
int rv;
+ if (!nls_init)
+ cm_InitNormalization();
+
/* first check for NULL pointers */
if (str1 == NULL) {
if (str2 == NULL)
wstr2[0] = L'\0';
}
- rv = CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, wstr1, len1, wstr2, len2);
+ rv = CompareStringW(nls_lcid, NORM_IGNORECASE, wstr1, len1, wstr2, len2);
if (rv > 0)
return (rv - 2);
else {
wchar_t wstrd[NLSMAXCCH];
int len;
+ if (!nls_init)
+ cm_InitNormalization();
+
len = cbstr / sizeof(wchar_t);
- len = LCMapStringW(LOCALE_INVARIANT, LCMAP_UPPERCASE, wstr, len, wstrd, NLSMAXCCH);
+ len = LCMapStringW(nls_lcid, LCMAP_UPPERCASE, wstr, len, wstrd, NLSMAXCCH);
StringCbCopyW(wstr, cbstr, wstrd);
return wstr;
wchar_t wstrd[NLSMAXCCH];
int len;
+ if (!nls_init)
+ cm_InitNormalization();
+
len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, str, -1, wstr, NLSMAXCCH);
if (len == 0)
return str;
- len = LCMapStringW(LOCALE_INVARIANT, LCMAP_UPPERCASE, wstr, len, wstrd, NLSMAXCCH);
+ len = LCMapStringW(nls_lcid, LCMAP_UPPERCASE, wstr, len, wstrd, NLSMAXCCH);
len = WideCharToMultiByte(CP_UTF8, 0, wstrd, -1, str, cbstr, NULL, FALSE);