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