Home | History | Annotate | Download | only in Common
      1 // Common/String.h
      2 
      3 #ifndef __COMMON_STRING_H
      4 #define __COMMON_STRING_H
      5 
      6 #include <string.h>
      7 
      8 #ifndef _WIN32
      9 #include <wctype.h>
     10 #include <wchar.h>
     11 #endif
     12 
     13 #include "MyWindows.h"
     14 #include "MyTypes.h"
     15 #include "MyVector.h"
     16 
     17 
     18 #ifdef _MSC_VER
     19   #ifdef _NATIVE_WCHAR_T_DEFINED
     20     #define MY_NATIVE_WCHAR_T_DEFINED
     21   #endif
     22 #else
     23     #define MY_NATIVE_WCHAR_T_DEFINED
     24 #endif
     25 
     26 /*
     27   native support for wchar_t:
     28  _MSC_VER == 1600 : /Zc:wchar_t is not supported
     29  _MSC_VER == 1310 (VS2003)
     30  ? _MSC_VER == 1400 (VS2005) : wchar_t <- unsigned short
     31               /Zc:wchar_t  : wchar_t <- __wchar_t, _WCHAR_T_DEFINED and _NATIVE_WCHAR_T_DEFINED
     32  _MSC_VER > 1400 (VS2008+)
     33               /Zc:wchar_t[-]
     34               /Zc:wchar_t is on by default
     35 */
     36 
     37 #ifdef _WIN32
     38 #define IS_PATH_SEPAR(c) ((c) == '\\' || (c) == '/')
     39 #else
     40 #define IS_PATH_SEPAR(c) ((c) == CHAR_PATH_SEPARATOR)
     41 #endif
     42 
     43 inline bool IsPathSepar(char    c) { return IS_PATH_SEPAR(c); }
     44 inline bool IsPathSepar(wchar_t c) { return IS_PATH_SEPAR(c); }
     45 
     46 inline unsigned MyStringLen(const char *s)
     47 {
     48   unsigned i;
     49   for (i = 0; s[i] != 0; i++);
     50   return i;
     51 }
     52 
     53 inline void MyStringCopy(char *dest, const char *src)
     54 {
     55   while ((*dest++ = *src++) != 0);
     56 }
     57 
     58 inline char *MyStpCpy(char *dest, const char *src)
     59 {
     60   for (;;)
     61   {
     62     char c = *src;
     63     *dest = c;
     64     if (c == 0)
     65       return dest;
     66     src++;
     67     dest++;
     68   }
     69 }
     70 
     71 inline unsigned MyStringLen(const wchar_t *s)
     72 {
     73   unsigned i;
     74   for (i = 0; s[i] != 0; i++);
     75   return i;
     76 }
     77 
     78 inline void MyStringCopy(wchar_t *dest, const wchar_t *src)
     79 {
     80   while ((*dest++ = *src++) != 0);
     81 }
     82 
     83 inline void MyStringCat(wchar_t *dest, const wchar_t *src)
     84 {
     85   MyStringCopy(dest + MyStringLen(dest), src);
     86 }
     87 
     88 
     89 /*
     90 inline wchar_t *MyWcpCpy(wchar_t *dest, const wchar_t *src)
     91 {
     92   for (;;)
     93   {
     94     wchar_t c = *src;
     95     *dest = c;
     96     if (c == 0)
     97       return dest;
     98     src++;
     99     dest++;
    100   }
    101 }
    102 */
    103 
    104 int FindCharPosInString(const char *s, char c) throw();
    105 int FindCharPosInString(const wchar_t *s, wchar_t c) throw();
    106 
    107 #ifdef _WIN32
    108   #ifndef _UNICODE
    109     #define STRING_UNICODE_THROW
    110   #endif
    111 #endif
    112 
    113 #ifndef STRING_UNICODE_THROW
    114   #define STRING_UNICODE_THROW throw()
    115 #endif
    116 
    117 
    118 inline char MyCharUpper_Ascii(char c)
    119 {
    120   if (c >= 'a' && c <= 'z')
    121     return (char)((unsigned char)c - 0x20);
    122   return c;
    123 }
    124 
    125 /*
    126 inline wchar_t MyCharUpper_Ascii(wchar_t c)
    127 {
    128   if (c >= 'a' && c <= 'z')
    129     return (wchar_t)(c - 0x20);
    130   return c;
    131 }
    132 */
    133 
    134 inline char MyCharLower_Ascii(char c)
    135 {
    136   if (c >= 'A' && c <= 'Z')
    137     return (char)((unsigned char)c + 0x20);
    138   return c;
    139 }
    140 
    141 inline wchar_t MyCharLower_Ascii(wchar_t c)
    142 {
    143   if (c >= 'A' && c <= 'Z')
    144     return (wchar_t)(c + 0x20);
    145   return c;
    146 }
    147 
    148 wchar_t MyCharUpper_WIN(wchar_t c) throw();
    149 
    150 inline wchar_t MyCharUpper(wchar_t c) throw()
    151 {
    152   if (c < 'a') return c;
    153   if (c <= 'z') return (wchar_t)(c - 0x20);
    154   if (c <= 0x7F) return c;
    155   #ifdef _WIN32
    156     #ifdef _UNICODE
    157       return (wchar_t)(unsigned)(UINT_PTR)CharUpperW((LPWSTR)(UINT_PTR)(unsigned)c);
    158     #else
    159       return (wchar_t)MyCharUpper_WIN(c);
    160     #endif
    161   #else
    162     return (wchar_t)towupper(c);
    163   #endif
    164 }
    165 
    166 /*
    167 wchar_t MyCharLower_WIN(wchar_t c) throw();
    168 
    169 inline wchar_t MyCharLower(wchar_t c) throw()
    170 {
    171   if (c < 'A') return c;
    172   if (c <= 'Z') return (wchar_t)(c + 0x20);
    173   if (c <= 0x7F) return c;
    174   #ifdef _WIN32
    175     #ifdef _UNICODE
    176       return (wchar_t)(unsigned)(UINT_PTR)CharLowerW((LPWSTR)(UINT_PTR)(unsigned)c);
    177     #else
    178       return (wchar_t)MyCharLower_WIN(c);
    179     #endif
    180   #else
    181     return (wchar_t)tolower(c);
    182   #endif
    183 }
    184 */
    185 
    186 // char *MyStringUpper(char *s) throw();
    187 // char *MyStringLower(char *s) throw();
    188 
    189 // void MyStringUpper_Ascii(char *s) throw();
    190 // void MyStringUpper_Ascii(wchar_t *s) throw();
    191 void MyStringLower_Ascii(char *s) throw();
    192 void MyStringLower_Ascii(wchar_t *s) throw();
    193 // wchar_t *MyStringUpper(wchar_t *s) STRING_UNICODE_THROW;
    194 // wchar_t *MyStringLower(wchar_t *s) STRING_UNICODE_THROW;
    195 
    196 bool StringsAreEqualNoCase(const wchar_t *s1, const wchar_t *s2) throw();
    197 
    198 bool IsString1PrefixedByString2(const char *s1, const char *s2) throw();
    199 bool IsString1PrefixedByString2(const wchar_t *s1, const wchar_t *s2) throw();
    200 bool IsString1PrefixedByString2(const wchar_t *s1, const char *s2) throw();
    201 bool IsString1PrefixedByString2_NoCase_Ascii(const wchar_t *u, const char *a) throw();
    202 bool IsString1PrefixedByString2_NoCase(const wchar_t *s1, const wchar_t *s2) throw();
    203 
    204 #define MyStringCompare(s1, s2) wcscmp(s1, s2)
    205 int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2) throw();
    206 // int MyStringCompareNoCase_N(const wchar_t *s1, const wchar_t *s2, unsigned num) throw();
    207 
    208 // ---------- ASCII ----------
    209 // char values in ASCII strings must be less then 128
    210 bool StringsAreEqual_Ascii(const wchar_t *u, const char *a) throw();
    211 bool StringsAreEqualNoCase_Ascii(const char *s1, const char *s2) throw();
    212 bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const char *s2) throw();
    213 bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const wchar_t *s2) throw();
    214 
    215 #define MY_STRING_DELETE(_p_) delete []_p_;
    216 // #define MY_STRING_DELETE(_p_) my_delete(_p_);
    217 
    218 
    219 #define FORBID_STRING_OPS_2(cls, t) \
    220   void Find(t) const; \
    221   void Find(t, unsigned startIndex) const; \
    222   void ReverseFind(t) const; \
    223   void InsertAtFront(t); \
    224   void RemoveChar(t); \
    225   void Replace(t, t); \
    226 
    227 #define FORBID_STRING_OPS(cls, t) \
    228   explicit cls(t); \
    229   explicit cls(const t *); \
    230   cls &operator=(t); \
    231   cls &operator=(const t *); \
    232   cls &operator+=(t); \
    233   cls &operator+=(const t *); \
    234   FORBID_STRING_OPS_2(cls, t); \
    235 
    236 /*
    237   cls &operator+(t); \
    238   cls &operator+(const t *); \
    239 */
    240 
    241 #define FORBID_STRING_OPS_AString(t) FORBID_STRING_OPS(AString, t)
    242 #define FORBID_STRING_OPS_UString(t) FORBID_STRING_OPS(UString, t)
    243 #define FORBID_STRING_OPS_UString2(t) FORBID_STRING_OPS(UString2, t)
    244 
    245 class AString
    246 {
    247   char *_chars;
    248   unsigned _len;
    249   unsigned _limit;
    250 
    251   void MoveItems(unsigned dest, unsigned src)
    252   {
    253     memmove(_chars + dest, _chars + src, (size_t)(_len - src + 1) * sizeof(char));
    254   }
    255 
    256   void InsertSpace(unsigned &index, unsigned size);
    257 
    258   void ReAlloc(unsigned newLimit);
    259   void ReAlloc2(unsigned newLimit);
    260   void SetStartLen(unsigned len);
    261   void Grow_1();
    262   void Grow(unsigned n);
    263 
    264   AString(unsigned num, const char *s);
    265   AString(unsigned num, const AString &s);
    266   AString(const AString &s, char c); // it's for String + char
    267   AString(const char *s1, unsigned num1, const char *s2, unsigned num2);
    268 
    269   friend AString operator+(const AString &s, char c) { return AString(s, c); } ;
    270   // friend AString operator+(char c, const AString &s); // is not supported
    271 
    272   friend AString operator+(const AString &s1, const AString &s2);
    273   friend AString operator+(const AString &s1, const char    *s2);
    274   friend AString operator+(const char    *s1, const AString &s2);
    275 
    276   // ---------- forbidden functions ----------
    277 
    278   #ifdef MY_NATIVE_WCHAR_T_DEFINED
    279   FORBID_STRING_OPS_AString(wchar_t)
    280   #endif
    281 
    282   FORBID_STRING_OPS_AString(signed char)
    283   FORBID_STRING_OPS_AString(unsigned char)
    284   FORBID_STRING_OPS_AString(short)
    285   FORBID_STRING_OPS_AString(unsigned short)
    286   FORBID_STRING_OPS_AString(int)
    287   FORBID_STRING_OPS_AString(unsigned)
    288   FORBID_STRING_OPS_AString(long)
    289   FORBID_STRING_OPS_AString(unsigned long)
    290 
    291 public:
    292   explicit AString();
    293   explicit AString(char c);
    294   explicit AString(const char *s);
    295   AString(const AString &s);
    296   ~AString() { MY_STRING_DELETE(_chars); }
    297 
    298   unsigned Len() const { return _len; }
    299   bool IsEmpty() const { return _len == 0; }
    300   void Empty() { _len = 0; _chars[0] = 0; }
    301 
    302   operator const char *() const { return _chars; }
    303   const char *Ptr() const { return _chars; }
    304   const char *Ptr(unsigned pos) const { return _chars + pos; }
    305   const char *RightPtr(unsigned num) const { return _chars + _len - num; }
    306   char Back() const { return _chars[(size_t)_len - 1]; }
    307 
    308   void ReplaceOneCharAtPos(unsigned pos, char c) { _chars[pos] = c; }
    309 
    310   char *GetBuf() { return _chars; }
    311   /* GetBuf(minLen): provides the buffer that can store
    312      at least (minLen) characters and additional null terminator.
    313      9.35: GetBuf doesn't preserve old characters and terminator */
    314   char *GetBuf(unsigned minLen)
    315   {
    316     if (minLen > _limit)
    317       ReAlloc2(minLen);
    318     return _chars;
    319   }
    320   char *GetBuf_SetEnd(unsigned minLen)
    321   {
    322     if (minLen > _limit)
    323       ReAlloc2(minLen);
    324     char *chars = _chars;
    325     chars[minLen] = 0;
    326     _len = minLen;
    327     return chars;
    328   }
    329 
    330   void ReleaseBuf_SetLen(unsigned newLen) { _len = newLen; }
    331   void ReleaseBuf_SetEnd(unsigned newLen) { _len = newLen; _chars[newLen] = 0; }
    332   void ReleaseBuf_CalcLen(unsigned maxLen)
    333   {
    334     char *chars = _chars;
    335     chars[maxLen] = 0;
    336     _len = MyStringLen(chars);
    337   }
    338 
    339   AString &operator=(char c);
    340   AString &operator=(const char *s);
    341   AString &operator=(const AString &s);
    342   void SetFromWStr_if_Ascii(const wchar_t *s);
    343   // void SetFromBstr_if_Ascii(BSTR s);
    344 
    345   AString &operator+=(char c)
    346   {
    347     if (_limit == _len)
    348       Grow_1();
    349     unsigned len = _len;
    350     char *chars = _chars;
    351     chars[len++] = c;
    352     chars[len] = 0;
    353     _len = len;
    354     return *this;
    355   }
    356 
    357   void Add_Space();
    358   void Add_Space_if_NotEmpty();
    359   void Add_OptSpaced(const char *s);
    360   void Add_LF();
    361   void Add_PathSepar() { operator+=(CHAR_PATH_SEPARATOR); }
    362 
    363   AString &operator+=(const char *s);
    364   AString &operator+=(const AString &s);
    365 
    366   void Add_UInt32(UInt32 v);
    367 
    368   void SetFrom(const char *s, unsigned len); // no check
    369   void SetFrom_CalcLen(const char *s, unsigned len);
    370 
    371   AString Mid(unsigned startIndex, unsigned count) const { return AString(count, _chars + startIndex); }
    372   AString Left(unsigned count) const { return AString(count, *this); }
    373 
    374   // void MakeUpper() { MyStringUpper(_chars); }
    375   // void MakeLower() { MyStringLower(_chars); }
    376   void MakeLower_Ascii() { MyStringLower_Ascii(_chars); }
    377 
    378 
    379   bool IsEqualTo(const char *s) const { return strcmp(_chars, s) == 0; }
    380   bool IsEqualTo_Ascii_NoCase(const char *s) const { return StringsAreEqualNoCase_Ascii(_chars, s); }
    381   // int Compare(const char *s) const { return MyStringCompare(_chars, s); }
    382   // int Compare(const AString &s) const { return MyStringCompare(_chars, s._chars); }
    383   // int CompareNoCase(const char *s) const { return MyStringCompareNoCase(_chars, s); }
    384   // int CompareNoCase(const AString &s) const { return MyStringCompareNoCase(_chars, s._chars); }
    385   bool IsPrefixedBy(const char *s) const { return IsString1PrefixedByString2(_chars, s); }
    386   bool IsPrefixedBy_Ascii_NoCase(const char *s) const throw();
    387 
    388   bool IsAscii() const
    389   {
    390     unsigned len = Len();
    391     const char *s = _chars;
    392     for (unsigned i = 0; i < len; i++)
    393       if ((unsigned char)s[i] >= 0x80)
    394         return false;
    395     return true;
    396   }
    397   int Find(char c) const { return FindCharPosInString(_chars, c); }
    398   int Find(char c, unsigned startIndex) const
    399   {
    400     int pos = FindCharPosInString(_chars + startIndex, c);
    401     return pos < 0 ? -1 : (int)startIndex + pos;
    402   }
    403 
    404   int ReverseFind(char c) const throw();
    405   int ReverseFind_Dot() const throw() { return ReverseFind('.'); }
    406   int ReverseFind_PathSepar() const throw();
    407 
    408   int Find(const char *s) const { return Find(s, 0); }
    409   int Find(const char *s, unsigned startIndex) const throw();
    410 
    411   void TrimLeft() throw();
    412   void TrimRight() throw();
    413   void Trim()
    414   {
    415     TrimRight();
    416     TrimLeft();
    417   }
    418 
    419   void InsertAtFront(char c);
    420   // void Insert(unsigned index, char c);
    421   void Insert(unsigned index, const char *s);
    422   void Insert(unsigned index, const AString &s);
    423 
    424   void RemoveChar(char ch) throw();
    425 
    426   void Replace(char oldChar, char newChar) throw();
    427   void Replace(const AString &oldString, const AString &newString);
    428 
    429   void Delete(unsigned index) throw();
    430   void Delete(unsigned index, unsigned count) throw();
    431   void DeleteFrontal(unsigned num) throw();
    432   void DeleteBack() { _chars[--_len] = 0; }
    433   void DeleteFrom(unsigned index)
    434   {
    435     if (index < _len)
    436     {
    437       _len = index;
    438       _chars[index] = 0;
    439     }
    440   }
    441 };
    442 
    443 bool operator<(const AString &s1, const AString &s2);
    444 bool operator>(const AString &s1, const AString &s2);
    445 
    446 /*
    447 bool operator==(const AString &s1, const AString &s2);
    448 bool operator==(const AString &s1, const char    *s2);
    449 bool operator==(const char    *s1, const AString &s2);
    450 
    451 bool operator!=(const AString &s1, const AString &s2);
    452 bool operator!=(const AString &s1, const char    *s2);
    453 bool operator!=(const char    *s1, const AString &s2);
    454 */
    455 
    456 inline bool operator==(const AString &s1, const AString &s2) { return s1.Len() == s2.Len() && strcmp(s1, s2) == 0; }
    457 inline bool operator==(const AString &s1, const char    *s2) { return strcmp(s1, s2) == 0; }
    458 inline bool operator==(const char    *s1, const AString &s2) { return strcmp(s1, s2) == 0; }
    459 
    460 inline bool operator!=(const AString &s1, const AString &s2) { return s1.Len() != s2.Len() || strcmp(s1, s2) != 0; }
    461 inline bool operator!=(const AString &s1, const char    *s2) { return strcmp(s1, s2) != 0; }
    462 inline bool operator!=(const char    *s1, const AString &s2) { return strcmp(s1, s2) != 0; }
    463 
    464 // ---------- forbidden functions ----------
    465 
    466 void operator==(char c1, const AString &s2);
    467 void operator==(const AString &s1, char c2);
    468 
    469 void operator+(char c, const AString &s); // this function can be OK, but we don't use it
    470 
    471 void operator+(const AString &s, int c);
    472 void operator+(const AString &s, unsigned c);
    473 void operator+(int c, const AString &s);
    474 void operator+(unsigned c, const AString &s);
    475 void operator-(const AString &s, int c);
    476 void operator-(const AString &s, unsigned c);
    477 
    478 
    479 class UString
    480 {
    481   wchar_t *_chars;
    482   unsigned _len;
    483   unsigned _limit;
    484 
    485   void MoveItems(unsigned dest, unsigned src)
    486   {
    487     memmove(_chars + dest, _chars + src, (size_t)(_len - src + 1) * sizeof(wchar_t));
    488   }
    489 
    490   void InsertSpace(unsigned index, unsigned size);
    491 
    492   void ReAlloc(unsigned newLimit);
    493   void ReAlloc2(unsigned newLimit);
    494   void SetStartLen(unsigned len);
    495   void Grow_1();
    496   void Grow(unsigned n);
    497 
    498   UString(unsigned num, const wchar_t *s); // for Mid
    499   UString(unsigned num, const UString &s); // for Left
    500   UString(const UString &s, wchar_t c); // it's for String + char
    501   UString(const wchar_t *s1, unsigned num1, const wchar_t *s2, unsigned num2);
    502 
    503   friend UString operator+(const UString &s, wchar_t c) { return UString(s, c); } ;
    504   // friend UString operator+(wchar_t c, const UString &s); // is not supported
    505 
    506   friend UString operator+(const UString &s1, const UString &s2);
    507   friend UString operator+(const UString &s1, const wchar_t *s2);
    508   friend UString operator+(const wchar_t *s1, const UString &s2);
    509 
    510   // ---------- forbidden functions ----------
    511 
    512   FORBID_STRING_OPS_UString(signed char)
    513   FORBID_STRING_OPS_UString(unsigned char)
    514   FORBID_STRING_OPS_UString(short)
    515 
    516   #ifdef MY_NATIVE_WCHAR_T_DEFINED
    517   FORBID_STRING_OPS_UString(unsigned short)
    518   #endif
    519 
    520   FORBID_STRING_OPS_UString(int)
    521   FORBID_STRING_OPS_UString(unsigned)
    522   FORBID_STRING_OPS_UString(long)
    523   FORBID_STRING_OPS_UString(unsigned long)
    524 
    525   FORBID_STRING_OPS_2(UString, char)
    526 
    527 public:
    528   UString();
    529   explicit UString(wchar_t c);
    530   explicit UString(char c);
    531   explicit UString(const char *s);
    532   // UString(const AString &s);
    533   UString(const wchar_t *s);
    534   UString(const UString &s);
    535   ~UString() { MY_STRING_DELETE(_chars); }
    536 
    537   unsigned Len() const { return _len; }
    538   bool IsEmpty() const { return _len == 0; }
    539   void Empty() { _len = 0; _chars[0] = 0; }
    540 
    541   operator const wchar_t *() const { return _chars; }
    542   const wchar_t *Ptr() const { return _chars; }
    543   const wchar_t *Ptr(unsigned pos) const { return _chars + pos; }
    544   const wchar_t *RightPtr(unsigned num) const { return _chars + _len - num; }
    545   wchar_t Back() const { return _chars[(size_t)_len - 1]; }
    546 
    547   void ReplaceOneCharAtPos(unsigned pos, wchar_t c) { _chars[pos] = c; }
    548 
    549   wchar_t *GetBuf() { return _chars; }
    550 
    551   wchar_t *GetBuf(unsigned minLen)
    552   {
    553     if (minLen > _limit)
    554       ReAlloc2(minLen);
    555     return _chars;
    556   }
    557   wchar_t *GetBuf_SetEnd(unsigned minLen)
    558   {
    559     if (minLen > _limit)
    560       ReAlloc2(minLen);
    561     wchar_t *chars = _chars;
    562     chars[minLen] = 0;
    563     _len = minLen;
    564     return chars;
    565   }
    566 
    567   void ReleaseBuf_SetLen(unsigned newLen) { _len = newLen; }
    568   void ReleaseBuf_SetEnd(unsigned newLen) { _len = newLen; _chars[newLen] = 0; }
    569   void ReleaseBuf_CalcLen(unsigned maxLen)
    570   {
    571     wchar_t *chars = _chars;
    572     chars[maxLen] = 0;
    573     _len = MyStringLen(chars);
    574   }
    575 
    576   UString &operator=(wchar_t c);
    577   UString &operator=(char c) { return (*this)=((wchar_t)(unsigned char)c); }
    578   UString &operator=(const wchar_t *s);
    579   UString &operator=(const UString &s);
    580   void SetFrom(const wchar_t *s, unsigned len); // no check
    581   void SetFromBstr(BSTR s);
    582   UString &operator=(const char *s);
    583   UString &operator=(const AString &s) { return operator=(s.Ptr()); }
    584 
    585   UString &operator+=(wchar_t c)
    586   {
    587     if (_limit == _len)
    588       Grow_1();
    589     unsigned len = _len;
    590     wchar_t *chars = _chars;
    591     chars[len++] = c;
    592     chars[len] = 0;
    593     _len = len;
    594     return *this;
    595   }
    596 
    597   UString &operator+=(char c) { return (*this)+=((wchar_t)(unsigned char)c); }
    598 
    599   void Add_Space();
    600   void Add_Space_if_NotEmpty();
    601   void Add_LF();
    602   void Add_PathSepar() { operator+=(WCHAR_PATH_SEPARATOR); }
    603 
    604   UString &operator+=(const wchar_t *s);
    605   UString &operator+=(const UString &s);
    606   UString &operator+=(const char *s);
    607   UString &operator+=(const AString &s) { return operator+=(s.Ptr()); }
    608 
    609   void Add_UInt32(UInt32 v);
    610 
    611   UString Mid(unsigned startIndex, unsigned count) const { return UString(count, _chars + startIndex); }
    612   UString Left(unsigned count) const { return UString(count, *this); }
    613 
    614   // void MakeUpper() { MyStringUpper(_chars); }
    615   // void MakeUpper() { MyStringUpper_Ascii(_chars); }
    616   // void MakeUpper_Ascii() { MyStringUpper_Ascii(_chars); }
    617   void MakeLower_Ascii() { MyStringLower_Ascii(_chars); }
    618 
    619   bool IsEqualTo(const char *s) const { return StringsAreEqual_Ascii(_chars, s); }
    620   bool IsEqualTo_NoCase(const wchar_t *s) const { return StringsAreEqualNoCase(_chars, s); }
    621   bool IsEqualTo_Ascii_NoCase(const char *s) const { return StringsAreEqualNoCase_Ascii(_chars, s); }
    622   int Compare(const wchar_t *s) const { return wcscmp(_chars, s); }
    623   // int Compare(const UString &s) const { return MyStringCompare(_chars, s._chars); }
    624   // int CompareNoCase(const wchar_t *s) const { return MyStringCompareNoCase(_chars, s); }
    625   // int CompareNoCase(const UString &s) const { return MyStringCompareNoCase(_chars, s._chars); }
    626   bool IsPrefixedBy(const wchar_t *s) const { return IsString1PrefixedByString2(_chars, s); }
    627   bool IsPrefixedBy_NoCase(const wchar_t *s) const { return IsString1PrefixedByString2_NoCase(_chars, s); }
    628   bool IsPrefixedBy_Ascii_NoCase(const char *s) const throw();
    629 
    630   bool IsAscii() const
    631   {
    632     unsigned len = Len();
    633     const wchar_t *s = _chars;
    634     for (unsigned i = 0; i < len; i++)
    635       if (s[i] >= 0x80)
    636         return false;
    637     return true;
    638   }
    639   int Find(wchar_t c) const { return FindCharPosInString(_chars, c); }
    640   int Find(wchar_t c, unsigned startIndex) const
    641   {
    642     int pos = FindCharPosInString(_chars + startIndex, c);
    643     return pos < 0 ? -1 : (int)startIndex + pos;
    644   }
    645 
    646   int ReverseFind(wchar_t c) const throw();
    647   int ReverseFind_Dot() const throw() { return ReverseFind(L'.'); }
    648   int ReverseFind_PathSepar() const throw();
    649 
    650   int Find(const wchar_t *s) const { return Find(s, 0); }
    651   int Find(const wchar_t *s, unsigned startIndex) const throw();
    652 
    653   void TrimLeft() throw();
    654   void TrimRight() throw();
    655   void Trim()
    656   {
    657     TrimRight();
    658     TrimLeft();
    659   }
    660 
    661   void InsertAtFront(wchar_t c);
    662   // void Insert(unsigned index, wchar_t c);
    663   void Insert(unsigned index, const wchar_t *s);
    664   void Insert(unsigned index, const UString &s);
    665 
    666   void RemoveChar(wchar_t ch) throw();
    667 
    668   void Replace(wchar_t oldChar, wchar_t newChar) throw();
    669   void Replace(const UString &oldString, const UString &newString);
    670 
    671   void Delete(unsigned index) throw();
    672   void Delete(unsigned index, unsigned count) throw();
    673   void DeleteFrontal(unsigned num) throw();
    674   void DeleteBack() { _chars[--_len] = 0; }
    675   void DeleteFrom(unsigned index)
    676   {
    677     if (index < _len)
    678     {
    679       _len = index;
    680       _chars[index] = 0;
    681     }
    682   }
    683 };
    684 
    685 bool operator<(const UString &s1, const UString &s2);
    686 bool operator>(const UString &s1, const UString &s2);
    687 
    688 inline bool operator==(const UString &s1, const UString &s2) { return s1.Len() == s2.Len() && wcscmp(s1, s2) == 0; }
    689 inline bool operator==(const UString &s1, const wchar_t *s2) { return wcscmp(s1, s2) == 0; }
    690 inline bool operator==(const wchar_t *s1, const UString &s2) { return wcscmp(s1, s2) == 0; }
    691 
    692 inline bool operator!=(const UString &s1, const UString &s2) { return s1.Len() != s2.Len() || wcscmp(s1, s2) != 0; }
    693 inline bool operator!=(const UString &s1, const wchar_t *s2) { return wcscmp(s1, s2) != 0; }
    694 inline bool operator!=(const wchar_t *s1, const UString &s2) { return wcscmp(s1, s2) != 0; }
    695 
    696 
    697 // ---------- forbidden functions ----------
    698 
    699 void operator==(wchar_t c1, const UString &s2);
    700 void operator==(const UString &s1, wchar_t c2);
    701 
    702 void operator+(wchar_t c, const UString &s); // this function can be OK, but we don't use it
    703 
    704 void operator+(const AString &s1, const UString &s2);
    705 void operator+(const UString &s1, const AString &s2);
    706 
    707 void operator+(const UString &s1, const char *s2);
    708 void operator+(const char *s1, const UString &s2);
    709 
    710 void operator+(const UString &s, char c);
    711 void operator+(const UString &s, unsigned char c);
    712 void operator+(char c, const UString &s);
    713 void operator+(unsigned char c, const UString &s);
    714 void operator-(const UString &s1, wchar_t c);
    715 
    716 #ifdef _WIN32
    717 // can we forbid these functions, if wchar_t is 32-bit ?
    718 void operator+(const UString &s, int c);
    719 void operator+(const UString &s, unsigned c);
    720 void operator+(int c, const UString &s);
    721 void operator+(unsigned c, const UString &s);
    722 void operator-(const UString &s1, int c);
    723 void operator-(const UString &s1, unsigned c);
    724 #endif
    725 
    726 
    727 
    728 
    729 
    730 
    731 
    732 class UString2
    733 {
    734   wchar_t *_chars;
    735   unsigned _len;
    736 
    737   void ReAlloc2(unsigned newLimit);
    738   void SetStartLen(unsigned len);
    739 
    740   // ---------- forbidden functions ----------
    741 
    742   FORBID_STRING_OPS_UString2(char)
    743   FORBID_STRING_OPS_UString2(signed char)
    744   FORBID_STRING_OPS_UString2(unsigned char)
    745   FORBID_STRING_OPS_UString2(short)
    746 
    747   UString2 &operator=(wchar_t c);
    748   UString2(wchar_t c);
    749 
    750 public:
    751   UString2(): _chars(NULL), _len(0) {}
    752   UString2(const wchar_t *s);
    753   UString2(const UString2 &s);
    754   ~UString2() { if (_chars) MY_STRING_DELETE(_chars); }
    755 
    756   unsigned Len() const { return _len; }
    757   bool IsEmpty() const { return _len == 0; }
    758   // void Empty() { _len = 0; _chars[0] = 0; }
    759 
    760   // operator const wchar_t *() const { return _chars; }
    761   const wchar_t *GetRawPtr() const { return _chars; }
    762 
    763   int Compare(const wchar_t *s) const { return wcscmp(_chars, s); }
    764 
    765   wchar_t *GetBuf(unsigned minLen)
    766   {
    767     if (!_chars || minLen > _len)
    768       ReAlloc2(minLen);
    769     return _chars;
    770   }
    771   void ReleaseBuf_SetLen(unsigned newLen) { _len = newLen; }
    772 
    773   UString2 &operator=(const wchar_t *s);
    774   UString2 &operator=(const UString2 &s);
    775   void SetFromAscii(const char *s);
    776 };
    777 
    778 bool operator==(const UString2 &s1, const UString2 &s2);
    779 bool operator==(const UString2 &s1, const wchar_t *s2);
    780 bool operator==(const wchar_t *s1, const UString2 &s2);
    781 
    782 inline bool operator!=(const UString2 &s1, const UString2 &s2) { return !(s1 == s2); }
    783 inline bool operator!=(const UString2 &s1, const wchar_t *s2) { return !(s1 == s2); }
    784 inline bool operator!=(const wchar_t *s1, const UString2 &s2) { return !(s1 == s2); }
    785 
    786 
    787 // ---------- forbidden functions ----------
    788 
    789 void operator==(wchar_t c1, const UString2 &s2);
    790 void operator==(const UString2 &s1, wchar_t c2);
    791 bool operator<(const UString2 &s1, const UString2 &s2);
    792 bool operator>(const UString2 &s1, const UString2 &s2);
    793 
    794 void operator+(const UString2 &s1, const UString2 &s2);
    795 void operator+(const UString2 &s1, const wchar_t *s2);
    796 void operator+(const wchar_t *s1, const UString2 &s2);
    797 void operator+(wchar_t c, const UString2 &s);
    798 void operator+(const UString2 &s, wchar_t c);
    799 void operator+(const UString2 &s, char c);
    800 void operator+(const UString2 &s, unsigned char c);
    801 void operator+(char c, const UString2 &s);
    802 void operator+(unsigned char c, const UString2 &s);
    803 void operator-(const UString2 &s1, wchar_t c);
    804 
    805 
    806 
    807 
    808 
    809 
    810 typedef CObjectVector<AString> AStringVector;
    811 typedef CObjectVector<UString> UStringVector;
    812 
    813 #ifdef _UNICODE
    814   typedef UString CSysString;
    815 #else
    816   typedef AString CSysString;
    817 #endif
    818 
    819 typedef CObjectVector<CSysString> CSysStringVector;
    820 
    821 
    822 // ---------- FString ----------
    823 
    824 #ifdef _WIN32
    825   #define USE_UNICODE_FSTRING
    826 #endif
    827 
    828 #ifdef USE_UNICODE_FSTRING
    829 
    830   #define __FTEXT(quote) L##quote
    831 
    832   typedef wchar_t FChar;
    833   typedef UString FString;
    834 
    835   #define fs2us(_x_) (_x_)
    836   #define us2fs(_x_) (_x_)
    837   FString fas2fs(const char *s);
    838   FString fas2fs(const AString &s);
    839   AString fs2fas(const FChar *s);
    840 
    841 #else
    842 
    843   #define __FTEXT(quote) quote
    844 
    845   typedef char FChar;
    846   typedef AString FString;
    847 
    848   UString fs2us(const FChar *s);
    849   UString fs2us(const FString &s);
    850   FString us2fs(const wchar_t *s);
    851   #define fas2fs(_x_) (_x_)
    852   #define fs2fas(_x_) (_x_)
    853 
    854 #endif
    855 
    856 #define FTEXT(quote) __FTEXT(quote)
    857 
    858 #define FCHAR_PATH_SEPARATOR FTEXT(CHAR_PATH_SEPARATOR)
    859 #define FSTRING_PATH_SEPARATOR FTEXT(STRING_PATH_SEPARATOR)
    860 
    861 // #define FCHAR_ANY_MASK FTEXT('*')
    862 // #define FSTRING_ANY_MASK FTEXT("*")
    863 
    864 typedef const FChar *CFSTR;
    865 
    866 typedef CObjectVector<FString> FStringVector;
    867 
    868 #endif
    869