Home | History | Annotate | Download | only in Common
      1 // Common/MyString.cpp
      2 
      3 #include "StdAfx.h"
      4 
      5 #ifndef _WIN32
      6 #include <ctype.h>
      7 #endif
      8 
      9 #ifndef _UNICODE
     10 #include "StringConvert.h"
     11 #endif
     12 
     13 #include "MyString.h"
     14 
     15 
     16 #ifdef _WIN32
     17 
     18 #ifndef _UNICODE
     19 
     20 wchar_t MyCharUpper(wchar_t c)
     21 {
     22   if (c == 0)
     23     return 0;
     24   wchar_t *res = CharUpperW((LPWSTR)(UINT_PTR)(unsigned int)c);
     25   if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
     26     return (wchar_t)(unsigned int)(UINT_PTR)res;
     27   const int kBufferSize = 4;
     28   char s[kBufferSize + 1];
     29   int numChars = ::WideCharToMultiByte(CP_ACP, 0, &c, 1, s, kBufferSize, 0, 0);
     30   if (numChars == 0 || numChars > kBufferSize)
     31     return c;
     32   s[numChars] = 0;
     33   ::CharUpperA(s);
     34   ::MultiByteToWideChar(CP_ACP, 0, s, numChars, &c, 1);
     35   return c;
     36 }
     37 
     38 wchar_t MyCharLower(wchar_t c)
     39 {
     40   if (c == 0)
     41     return 0;
     42   wchar_t *res = CharLowerW((LPWSTR)(UINT_PTR)(unsigned int)c);
     43   if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
     44     return (wchar_t)(unsigned int)(UINT_PTR)res;
     45   const int kBufferSize = 4;
     46   char s[kBufferSize + 1];
     47   int numChars = ::WideCharToMultiByte(CP_ACP, 0, &c, 1, s, kBufferSize, 0, 0);
     48   if (numChars == 0 || numChars > kBufferSize)
     49     return c;
     50   s[numChars] = 0;
     51   ::CharLowerA(s);
     52   ::MultiByteToWideChar(CP_ACP, 0, s, numChars, &c, 1);
     53   return c;
     54 }
     55 
     56 wchar_t * MyStringUpper(wchar_t *s)
     57 {
     58   if (s == 0)
     59     return 0;
     60   wchar_t *res = CharUpperW(s);
     61   if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
     62     return res;
     63   AString a = UnicodeStringToMultiByte(s);
     64   a.MakeUpper();
     65   return MyStringCopy(s, (const wchar_t *)MultiByteToUnicodeString(a));
     66 }
     67 
     68 wchar_t * MyStringLower(wchar_t *s)
     69 {
     70   if (s == 0)
     71     return 0;
     72   wchar_t *res = CharLowerW(s);
     73   if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
     74     return res;
     75   AString a = UnicodeStringToMultiByte(s);
     76   a.MakeLower();
     77   return MyStringCopy(s, (const wchar_t *)MultiByteToUnicodeString(a));
     78 }
     79 
     80 #endif
     81 
     82 /*
     83 inline int ConvertCompareResult(int r) { return r - 2; }
     84 
     85 int MyStringCollate(const wchar_t *s1, const wchar_t *s2)
     86 {
     87   int res = CompareStringW(
     88         LOCALE_USER_DEFAULT, SORT_STRINGSORT, s1, -1, s2, -1);
     89   #ifdef _UNICODE
     90   return ConvertCompareResult(res);
     91   #else
     92   if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
     93     return ConvertCompareResult(res);
     94   return MyStringCollate(UnicodeStringToMultiByte(s1),
     95         UnicodeStringToMultiByte(s2));
     96   #endif
     97 }
     98 
     99 #ifndef UNDER_CE
    100 int MyStringCollate(const char *s1, const char *s2)
    101 {
    102   return ConvertCompareResult(CompareStringA(
    103     LOCALE_USER_DEFAULT, SORT_STRINGSORT, s1, -1, s2, -1));
    104 }
    105 
    106 int MyStringCollateNoCase(const char *s1, const char *s2)
    107 {
    108   return ConvertCompareResult(CompareStringA(
    109     LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, s1, -1, s2, -1));
    110 }
    111 #endif
    112 
    113 int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2)
    114 {
    115   int res = CompareStringW(
    116         LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, s1, -1, s2, -1);
    117   #ifdef _UNICODE
    118   return ConvertCompareResult(res);
    119   #else
    120   if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
    121     return ConvertCompareResult(res);
    122   return MyStringCollateNoCase(UnicodeStringToMultiByte(s1),
    123       UnicodeStringToMultiByte(s2));
    124   #endif
    125 }
    126 */
    127 
    128 #else
    129 
    130 wchar_t MyCharUpper(wchar_t c)
    131 {
    132   return toupper(c);
    133 }
    134 
    135 /*
    136 int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2)
    137 {
    138   for (;;)
    139   {
    140     wchar_t c1 = *s1++;
    141     wchar_t c2 = *s2++;
    142     wchar_t u1 = MyCharUpper(c1);
    143     wchar_t u2 = MyCharUpper(c2);
    144 
    145     if (u1 < u2) return -1;
    146     if (u1 > u2) return 1;
    147     if (u1 == 0) return 0;
    148   }
    149 }
    150 */
    151 
    152 #endif
    153 
    154 int MyStringCompare(const char *s1, const char *s2)
    155 {
    156   for (;;)
    157   {
    158     unsigned char c1 = (unsigned char)*s1++;
    159     unsigned char c2 = (unsigned char)*s2++;
    160     if (c1 < c2) return -1;
    161     if (c1 > c2) return 1;
    162     if (c1 == 0) return 0;
    163   }
    164 }
    165 
    166 int MyStringCompare(const wchar_t *s1, const wchar_t *s2)
    167 {
    168   for (;;)
    169   {
    170     wchar_t c1 = *s1++;
    171     wchar_t c2 = *s2++;
    172     if (c1 < c2) return -1;
    173     if (c1 > c2) return 1;
    174     if (c1 == 0) return 0;
    175   }
    176 }
    177 
    178 int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2)
    179 {
    180   for (;;)
    181   {
    182     wchar_t c1 = *s1++;
    183     wchar_t c2 = *s2++;
    184     if (c1 != c2)
    185     {
    186       wchar_t u1 = MyCharUpper(c1);
    187       wchar_t u2 = MyCharUpper(c2);
    188       if (u1 < u2) return -1;
    189       if (u1 > u2) return 1;
    190     }
    191     if (c1 == 0) return 0;
    192   }
    193 }
    194 
    195 /*
    196 int MyStringCompareNoCase(const char *s1, const char *s2)
    197 {
    198   return MyStringCompareNoCase(MultiByteToUnicodeString(s1), MultiByteToUnicodeString(s2));
    199 }
    200 */
    201