rlm@1: // Common/MyString.cpp rlm@1: rlm@1: #include "StdAfx.h" rlm@1: rlm@1: #ifdef _WIN32 rlm@1: #include "StringConvert.h" rlm@1: #else rlm@1: #include rlm@1: #endif rlm@1: rlm@1: #include "MyString.h" rlm@1: rlm@1: rlm@1: #ifdef _WIN32 rlm@1: rlm@1: #ifndef _UNICODE rlm@1: rlm@1: wchar_t MyCharUpper(wchar_t c) rlm@1: { rlm@1: if (c == 0) rlm@1: return 0; rlm@1: wchar_t *res = CharUpperW((LPWSTR)(UINT_PTR)(unsigned int)c); rlm@1: if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) rlm@1: return (wchar_t)(unsigned int)(UINT_PTR)res; rlm@1: const int kBufferSize = 4; rlm@1: char s[kBufferSize + 1]; rlm@1: int numChars = ::WideCharToMultiByte(CP_ACP, 0, &c, 1, s, kBufferSize, 0, 0); rlm@1: if (numChars == 0 || numChars > kBufferSize) rlm@1: return c; rlm@1: s[numChars] = 0; rlm@1: ::CharUpperA(s); rlm@1: ::MultiByteToWideChar(CP_ACP, 0, s, numChars, &c, 1); rlm@1: return c; rlm@1: } rlm@1: rlm@1: wchar_t MyCharLower(wchar_t c) rlm@1: { rlm@1: if (c == 0) rlm@1: return 0; rlm@1: wchar_t *res = CharLowerW((LPWSTR)(UINT_PTR)(unsigned int)c); rlm@1: if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) rlm@1: return (wchar_t)(unsigned int)(UINT_PTR)res; rlm@1: const int kBufferSize = 4; rlm@1: char s[kBufferSize + 1]; rlm@1: int numChars = ::WideCharToMultiByte(CP_ACP, 0, &c, 1, s, kBufferSize, 0, 0); rlm@1: if (numChars == 0 || numChars > kBufferSize) rlm@1: return c; rlm@1: s[numChars] = 0; rlm@1: ::CharLowerA(s); rlm@1: ::MultiByteToWideChar(CP_ACP, 0, s, numChars, &c, 1); rlm@1: return c; rlm@1: } rlm@1: rlm@1: wchar_t * MyStringUpper(wchar_t *s) rlm@1: { rlm@1: if (s == 0) rlm@1: return 0; rlm@1: wchar_t *res = CharUpperW(s); rlm@1: if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) rlm@1: return res; rlm@1: AString a = UnicodeStringToMultiByte(s); rlm@1: a.MakeUpper(); rlm@1: return MyStringCopy(s, (const wchar_t *)MultiByteToUnicodeString(a)); rlm@1: } rlm@1: rlm@1: wchar_t * MyStringLower(wchar_t *s) rlm@1: { rlm@1: if (s == 0) rlm@1: return 0; rlm@1: wchar_t *res = CharLowerW(s); rlm@1: if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) rlm@1: return res; rlm@1: AString a = UnicodeStringToMultiByte(s); rlm@1: a.MakeLower(); rlm@1: return MyStringCopy(s, (const wchar_t *)MultiByteToUnicodeString(a)); rlm@1: } rlm@1: rlm@1: #endif rlm@1: rlm@1: /* rlm@1: inline int ConvertCompareResult(int r) { return r - 2; } rlm@1: rlm@1: int MyStringCollate(const wchar_t *s1, const wchar_t *s2) rlm@1: { rlm@1: int res = CompareStringW( rlm@1: LOCALE_USER_DEFAULT, SORT_STRINGSORT, s1, -1, s2, -1); rlm@1: #ifdef _UNICODE rlm@1: return ConvertCompareResult(res); rlm@1: #else rlm@1: if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) rlm@1: return ConvertCompareResult(res); rlm@1: return MyStringCollate(UnicodeStringToMultiByte(s1), rlm@1: UnicodeStringToMultiByte(s2)); rlm@1: #endif rlm@1: } rlm@1: rlm@1: #ifndef _WIN32_WCE rlm@1: int MyStringCollate(const char *s1, const char *s2) rlm@1: { rlm@1: return ConvertCompareResult(CompareStringA( rlm@1: LOCALE_USER_DEFAULT, SORT_STRINGSORT, s1, -1, s2, -1)); rlm@1: } rlm@1: rlm@1: int MyStringCollateNoCase(const char *s1, const char *s2) rlm@1: { rlm@1: return ConvertCompareResult(CompareStringA( rlm@1: LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, s1, -1, s2, -1)); rlm@1: } rlm@1: #endif rlm@1: rlm@1: int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2) rlm@1: { rlm@1: int res = CompareStringW( rlm@1: LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, s1, -1, s2, -1); rlm@1: #ifdef _UNICODE rlm@1: return ConvertCompareResult(res); rlm@1: #else rlm@1: if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) rlm@1: return ConvertCompareResult(res); rlm@1: return MyStringCollateNoCase(UnicodeStringToMultiByte(s1), rlm@1: UnicodeStringToMultiByte(s2)); rlm@1: #endif rlm@1: } rlm@1: */ rlm@1: rlm@1: #else rlm@1: rlm@1: wchar_t MyCharUpper(wchar_t c) rlm@1: { rlm@1: return toupper(c); rlm@1: } rlm@1: rlm@1: /* rlm@1: int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2) rlm@1: { rlm@1: for (;;) rlm@1: { rlm@1: wchar_t c1 = *s1++; rlm@1: wchar_t c2 = *s2++; rlm@1: wchar_t u1 = MyCharUpper(c1); rlm@1: wchar_t u2 = MyCharUpper(c2); rlm@1: rlm@1: if (u1 < u2) return -1; rlm@1: if (u1 > u2) return 1; rlm@1: if (u1 == 0) return 0; rlm@1: } rlm@1: } rlm@1: */ rlm@1: rlm@1: #endif rlm@1: rlm@1: int MyStringCompare(const char *s1, const char *s2) rlm@1: { rlm@1: for (;;) rlm@1: { rlm@1: unsigned char c1 = (unsigned char)*s1++; rlm@1: unsigned char c2 = (unsigned char)*s2++; rlm@1: if (c1 < c2) return -1; rlm@1: if (c1 > c2) return 1; rlm@1: if (c1 == 0) return 0; rlm@1: } rlm@1: } rlm@1: rlm@1: int MyStringCompare(const wchar_t *s1, const wchar_t *s2) rlm@1: { rlm@1: for (;;) rlm@1: { rlm@1: wchar_t c1 = *s1++; rlm@1: wchar_t c2 = *s2++; rlm@1: if (c1 < c2) return -1; rlm@1: if (c1 > c2) return 1; rlm@1: if (c1 == 0) return 0; rlm@1: } rlm@1: } rlm@1: rlm@1: int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2) rlm@1: { rlm@1: for (;;) rlm@1: { rlm@1: wchar_t c1 = *s1++; rlm@1: wchar_t c2 = *s2++; rlm@1: if (c1 != c2) rlm@1: { rlm@1: wchar_t u1 = MyCharUpper(c1); rlm@1: wchar_t u2 = MyCharUpper(c2); rlm@1: if (u1 < u2) return -1; rlm@1: if (u1 > u2) return 1; rlm@1: } rlm@1: if (c1 == 0) return 0; rlm@1: } rlm@1: } rlm@1: rlm@1: #ifdef _WIN32 rlm@1: int MyStringCompareNoCase(const char *s1, const char *s2) rlm@1: { rlm@1: return MyStringCompareNoCase(MultiByteToUnicodeString(s1), MultiByteToUnicodeString(s2)); rlm@1: } rlm@1: #endif