MyString.cpp revision baa3858d3f5d128a5c8466b700098109edcad5f2
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
20wchar_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
38wchar_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
56wchar_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
68wchar_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/*
83inline int ConvertCompareResult(int r) { return r - 2; }
84
85int 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
100int MyStringCollate(const char *s1, const char *s2)
101{
102  return ConvertCompareResult(CompareStringA(
103    LOCALE_USER_DEFAULT, SORT_STRINGSORT, s1, -1, s2, -1));
104}
105
106int 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
113int 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
130wchar_t MyCharUpper(wchar_t c)
131{
132  return toupper(c);
133}
134
135/*
136int 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
154int 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
166int 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
178int 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/*
196int MyStringCompareNoCase(const char *s1, const char *s2)
197{
198  return MyStringCompareNoCase(MultiByteToUnicodeString(s1), MultiByteToUnicodeString(s2));
199}
200*/
201