tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

MyString.h (26238B)


      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  /* GetBuf(minLen): provides the buffer that can store
    311     at least (minLen) characters and additional null terminator.
    312     9.35: GetBuf doesn't preserve old characters and terminator */
    313  char *GetBuf(unsigned minLen)
    314  {
    315    if (minLen > _limit)
    316      ReAlloc2(minLen);
    317    return _chars;
    318  }
    319  char *GetBuf_SetEnd(unsigned minLen)
    320  {
    321    if (minLen > _limit)
    322      ReAlloc2(minLen);
    323    char *chars = _chars;
    324    chars[minLen] = 0;
    325    _len = minLen;
    326    return chars;
    327  }
    328 
    329  void ReleaseBuf_SetLen(unsigned newLen) { _len = newLen; }
    330  void ReleaseBuf_SetEnd(unsigned newLen) { _len = newLen; _chars[newLen] = 0; }
    331  void ReleaseBuf_CalcLen(unsigned maxLen)
    332  {
    333    char *chars = _chars;
    334    chars[maxLen] = 0;
    335    _len = MyStringLen(chars);
    336  }
    337 
    338  AString &operator=(char c);
    339  AString &operator=(const char *s);
    340  AString &operator=(const AString &s);
    341  void SetFromWStr_if_Ascii(const wchar_t *s);
    342  // void SetFromBstr_if_Ascii(BSTR s);
    343 
    344  AString &operator+=(char c)
    345  {
    346    if (_limit == _len)
    347      Grow_1();
    348    unsigned len = _len;
    349    char *chars = _chars;
    350    chars[len++] = c;
    351    chars[len] = 0;
    352    _len = len;
    353    return *this;
    354  }
    355  
    356  void Add_Space();
    357  void Add_Space_if_NotEmpty();
    358  void Add_OptSpaced(const char *s);
    359  void Add_LF();
    360  void Add_PathSepar() { operator+=(CHAR_PATH_SEPARATOR); }
    361 
    362  AString &operator+=(const char *s);
    363  AString &operator+=(const AString &s);
    364 
    365  void Add_UInt32(UInt32 v);
    366 
    367  void SetFrom(const char *s, unsigned len); // no check
    368  void SetFrom_CalcLen(const char *s, unsigned len);
    369 
    370  AString Mid(unsigned startIndex, unsigned count) const { return AString(count, _chars + startIndex); }
    371  AString Left(unsigned count) const { return AString(count, *this); }
    372 
    373  // void MakeUpper() { MyStringUpper(_chars); }
    374  // void MakeLower() { MyStringLower(_chars); }
    375  void MakeLower_Ascii() { MyStringLower_Ascii(_chars); }
    376 
    377 
    378  bool IsEqualTo(const char *s) const { return strcmp(_chars, s) == 0; }
    379  bool IsEqualTo_Ascii_NoCase(const char *s) const { return StringsAreEqualNoCase_Ascii(_chars, s); }
    380  // int Compare(const char *s) const { return MyStringCompare(_chars, s); }
    381  // int Compare(const AString &s) const { return MyStringCompare(_chars, s._chars); }
    382  // int CompareNoCase(const char *s) const { return MyStringCompareNoCase(_chars, s); }
    383  // int CompareNoCase(const AString &s) const { return MyStringCompareNoCase(_chars, s._chars); }
    384  bool IsPrefixedBy(const char *s) const { return IsString1PrefixedByString2(_chars, s); }
    385  bool IsPrefixedBy_Ascii_NoCase(const char *s) const throw();
    386 
    387  bool IsAscii() const
    388  {
    389    unsigned len = Len();
    390    const char *s = _chars;
    391    for (unsigned i = 0; i < len; i++)
    392      if ((unsigned char)s[i] >= 0x80)
    393        return false;
    394    return true;
    395  }
    396  int Find(char c) const { return FindCharPosInString(_chars, c); }
    397  int Find(char c, unsigned startIndex) const
    398  {
    399    int pos = FindCharPosInString(_chars + startIndex, c);
    400    return pos < 0 ? -1 : (int)startIndex + pos;
    401  }
    402  
    403  int ReverseFind(char c) const throw();
    404  int ReverseFind_Dot() const throw() { return ReverseFind('.'); }
    405  int ReverseFind_PathSepar() const throw();
    406 
    407  int Find(const char *s) const { return Find(s, 0); }
    408  int Find(const char *s, unsigned startIndex) const throw();
    409  
    410  void TrimLeft() throw();
    411  void TrimRight() throw();
    412  void Trim()
    413  {
    414    TrimRight();
    415    TrimLeft();
    416  }
    417 
    418  void InsertAtFront(char c);
    419  // void Insert(unsigned index, char c);
    420  void Insert(unsigned index, const char *s);
    421  void Insert(unsigned index, const AString &s);
    422 
    423  void RemoveChar(char ch) throw();
    424  
    425  void Replace(char oldChar, char newChar) throw();
    426  void Replace(const AString &oldString, const AString &newString);
    427 
    428  void Delete(unsigned index) throw();
    429  void Delete(unsigned index, unsigned count) throw();
    430  void DeleteFrontal(unsigned num) throw();
    431  void DeleteBack() { _chars[--_len] = 0; }
    432  void DeleteFrom(unsigned index)
    433  {
    434    if (index < _len)
    435    {
    436      _len = index;
    437      _chars[index] = 0;
    438    }
    439  }
    440 };
    441 
    442 bool operator<(const AString &s1, const AString &s2);
    443 bool operator>(const AString &s1, const AString &s2);
    444 
    445 /*
    446 bool operator==(const AString &s1, const AString &s2);
    447 bool operator==(const AString &s1, const char    *s2);
    448 bool operator==(const char    *s1, const AString &s2);
    449 
    450 bool operator!=(const AString &s1, const AString &s2);
    451 bool operator!=(const AString &s1, const char    *s2);
    452 bool operator!=(const char    *s1, const AString &s2);
    453 */
    454 
    455 inline bool operator==(const AString &s1, const AString &s2) { return s1.Len() == s2.Len() && strcmp(s1, s2) == 0; }
    456 inline bool operator==(const AString &s1, const char    *s2) { return strcmp(s1, s2) == 0; }
    457 inline bool operator==(const char    *s1, const AString &s2) { return strcmp(s1, s2) == 0; }
    458 
    459 inline bool operator!=(const AString &s1, const AString &s2) { return s1.Len() != s2.Len() || strcmp(s1, s2) != 0; }
    460 inline bool operator!=(const AString &s1, const char    *s2) { return strcmp(s1, s2) != 0; }
    461 inline bool operator!=(const char    *s1, const AString &s2) { return strcmp(s1, s2) != 0; }
    462 
    463 // ---------- forbidden functions ----------
    464 
    465 void operator==(char c1, const AString &s2);
    466 void operator==(const AString &s1, char c2);
    467 
    468 void operator+(char c, const AString &s); // this function can be OK, but we don't use it
    469 
    470 void operator+(const AString &s, int c);
    471 void operator+(const AString &s, unsigned c);
    472 void operator+(int c, const AString &s);
    473 void operator+(unsigned c, const AString &s);
    474 void operator-(const AString &s, int c);
    475 void operator-(const AString &s, unsigned c);
    476 
    477 
    478 class UString
    479 {
    480  wchar_t *_chars;
    481  unsigned _len;
    482  unsigned _limit;
    483 
    484  void MoveItems(unsigned dest, unsigned src)
    485  {
    486    memmove(_chars + dest, _chars + src, (size_t)(_len - src + 1) * sizeof(wchar_t));
    487  }
    488  
    489  void InsertSpace(unsigned index, unsigned size);
    490  
    491  void ReAlloc(unsigned newLimit);
    492  void ReAlloc2(unsigned newLimit);
    493  void SetStartLen(unsigned len);
    494  void Grow_1();
    495  void Grow(unsigned n);
    496 
    497  UString(unsigned num, const wchar_t *s); // for Mid
    498  UString(unsigned num, const UString &s); // for Left
    499  UString(const UString &s, wchar_t c); // it's for String + char
    500  UString(const wchar_t *s1, unsigned num1, const wchar_t *s2, unsigned num2);
    501 
    502  friend UString operator+(const UString &s, wchar_t c) { return UString(s, c); } ;
    503  // friend UString operator+(wchar_t c, const UString &s); // is not supported
    504 
    505  friend UString operator+(const UString &s1, const UString &s2);
    506  friend UString operator+(const UString &s1, const wchar_t *s2);
    507  friend UString operator+(const wchar_t *s1, const UString &s2);
    508 
    509  // ---------- forbidden functions ----------
    510  
    511  FORBID_STRING_OPS_UString(signed char)
    512  FORBID_STRING_OPS_UString(unsigned char)
    513  FORBID_STRING_OPS_UString(short)
    514  
    515  #ifdef MY_NATIVE_WCHAR_T_DEFINED
    516  FORBID_STRING_OPS_UString(unsigned short)
    517  #endif
    518 
    519  FORBID_STRING_OPS_UString(int)
    520  FORBID_STRING_OPS_UString(unsigned)
    521  FORBID_STRING_OPS_UString(long)
    522  FORBID_STRING_OPS_UString(unsigned long)
    523 
    524  FORBID_STRING_OPS_2(UString, char)
    525 
    526 public:
    527  UString();
    528  explicit UString(wchar_t c);
    529  explicit UString(char c);
    530  explicit UString(const char *s);
    531  // UString(const AString &s);
    532  UString(const wchar_t *s);
    533  UString(const UString &s);
    534  ~UString() { MY_STRING_DELETE(_chars); }
    535 
    536  unsigned Len() const { return _len; }
    537  bool IsEmpty() const { return _len == 0; }
    538  void Empty() { _len = 0; _chars[0] = 0; }
    539 
    540  operator const wchar_t *() const { return _chars; }
    541  const wchar_t *Ptr() const { return _chars; }
    542  const wchar_t *Ptr(unsigned pos) const { return _chars + pos; }
    543  const wchar_t *RightPtr(unsigned num) const { return _chars + _len - num; }
    544  wchar_t Back() const { return _chars[(size_t)_len - 1]; }
    545 
    546  void ReplaceOneCharAtPos(unsigned pos, wchar_t c) { _chars[pos] = c; }
    547 
    548  wchar_t *GetBuf() { return _chars; }
    549 
    550  wchar_t *GetBuf(unsigned minLen)
    551  {
    552    if (minLen > _limit)
    553      ReAlloc2(minLen);
    554    return _chars;
    555  }
    556  wchar_t *GetBuf_SetEnd(unsigned minLen)
    557  {
    558    if (minLen > _limit)
    559      ReAlloc2(minLen);
    560    wchar_t *chars = _chars;
    561    chars[minLen] = 0;
    562    _len = minLen;
    563    return chars;
    564  }
    565 
    566  void ReleaseBuf_SetLen(unsigned newLen) { _len = newLen; }
    567  void ReleaseBuf_SetEnd(unsigned newLen) { _len = newLen; _chars[newLen] = 0; }
    568  void ReleaseBuf_CalcLen(unsigned maxLen)
    569  {
    570    wchar_t *chars = _chars;
    571    chars[maxLen] = 0;
    572    _len = MyStringLen(chars);
    573  }
    574 
    575  UString &operator=(wchar_t c);
    576  UString &operator=(char c) { return (*this)=((wchar_t)(unsigned char)c); }
    577  UString &operator=(const wchar_t *s);
    578  UString &operator=(const UString &s);
    579  void SetFrom(const wchar_t *s, unsigned len); // no check
    580  void SetFromBstr(BSTR s);
    581  UString &operator=(const char *s);
    582  UString &operator=(const AString &s) { return operator=(s.Ptr()); }
    583 
    584  UString &operator+=(wchar_t c)
    585  {
    586    if (_limit == _len)
    587      Grow_1();
    588    unsigned len = _len;
    589    wchar_t *chars = _chars;
    590    chars[len++] = c;
    591    chars[len] = 0;
    592    _len = len;
    593    return *this;
    594  }
    595 
    596  UString &operator+=(char c) { return (*this)+=((wchar_t)(unsigned char)c); }
    597 
    598  void Add_Space();
    599  void Add_Space_if_NotEmpty();
    600  void Add_LF();
    601  void Add_PathSepar() { operator+=(WCHAR_PATH_SEPARATOR); }
    602 
    603  UString &operator+=(const wchar_t *s);
    604  UString &operator+=(const UString &s);
    605  UString &operator+=(const char *s);
    606  UString &operator+=(const AString &s) { return operator+=(s.Ptr()); }
    607 
    608  void Add_UInt32(UInt32 v);
    609 
    610  UString Mid(unsigned startIndex, unsigned count) const { return UString(count, _chars + startIndex); }
    611  UString Left(unsigned count) const { return UString(count, *this); }
    612 
    613  // void MakeUpper() { MyStringUpper(_chars); }
    614  // void MakeUpper() { MyStringUpper_Ascii(_chars); }
    615  // void MakeUpper_Ascii() { MyStringUpper_Ascii(_chars); }
    616  void MakeLower_Ascii() { MyStringLower_Ascii(_chars); }
    617 
    618  bool IsEqualTo(const char *s) const { return StringsAreEqual_Ascii(_chars, s); }
    619  bool IsEqualTo_NoCase(const wchar_t *s) const { return StringsAreEqualNoCase(_chars, s); }
    620  bool IsEqualTo_Ascii_NoCase(const char *s) const { return StringsAreEqualNoCase_Ascii(_chars, s); }
    621  int Compare(const wchar_t *s) const { return wcscmp(_chars, s); }
    622  // int Compare(const UString &s) const { return MyStringCompare(_chars, s._chars); }
    623  // int CompareNoCase(const wchar_t *s) const { return MyStringCompareNoCase(_chars, s); }
    624  // int CompareNoCase(const UString &s) const { return MyStringCompareNoCase(_chars, s._chars); }
    625  bool IsPrefixedBy(const wchar_t *s) const { return IsString1PrefixedByString2(_chars, s); }
    626  bool IsPrefixedBy_NoCase(const wchar_t *s) const { return IsString1PrefixedByString2_NoCase(_chars, s); }
    627  bool IsPrefixedBy_Ascii_NoCase(const char *s) const throw();
    628 
    629  bool IsAscii() const
    630  {
    631    unsigned len = Len();
    632    const wchar_t *s = _chars;
    633    for (unsigned i = 0; i < len; i++)
    634      if (s[i] >= 0x80)
    635        return false;
    636    return true;
    637  }
    638  int Find(wchar_t c) const { return FindCharPosInString(_chars, c); }
    639  int Find(wchar_t c, unsigned startIndex) const
    640  {
    641    int pos = FindCharPosInString(_chars + startIndex, c);
    642    return pos < 0 ? -1 : (int)startIndex + pos;
    643  }
    644 
    645  int ReverseFind(wchar_t c) const throw();
    646  int ReverseFind_Dot() const throw() { return ReverseFind(L'.'); }
    647  int ReverseFind_PathSepar() const throw();
    648 
    649  int Find(const wchar_t *s) const { return Find(s, 0); }
    650  int Find(const wchar_t *s, unsigned startIndex) const throw();
    651 
    652  void TrimLeft() throw();
    653  void TrimRight() throw();
    654  void Trim()
    655  {
    656    TrimRight();
    657    TrimLeft();
    658  }
    659 
    660  void InsertAtFront(wchar_t c);
    661  // void Insert(unsigned index, wchar_t c);
    662  void Insert(unsigned index, const wchar_t *s);
    663  void Insert(unsigned index, const UString &s);
    664 
    665  void RemoveChar(wchar_t ch) throw();
    666  
    667  void Replace(wchar_t oldChar, wchar_t newChar) throw();
    668  void Replace(const UString &oldString, const UString &newString);
    669 
    670  void Delete(unsigned index) throw();
    671  void Delete(unsigned index, unsigned count) throw();
    672  void DeleteFrontal(unsigned num) throw();
    673  void DeleteBack() { _chars[--_len] = 0; }
    674  void DeleteFrom(unsigned index)
    675  {
    676    if (index < _len)
    677    {
    678      _len = index;
    679      _chars[index] = 0;
    680    }
    681  }
    682 };
    683 
    684 bool operator<(const UString &s1, const UString &s2);
    685 bool operator>(const UString &s1, const UString &s2);
    686 
    687 inline bool operator==(const UString &s1, const UString &s2) { return s1.Len() == s2.Len() && wcscmp(s1, s2) == 0; }
    688 inline bool operator==(const UString &s1, const wchar_t *s2) { return wcscmp(s1, s2) == 0; }
    689 inline bool operator==(const wchar_t *s1, const UString &s2) { return wcscmp(s1, s2) == 0; }
    690 
    691 inline bool operator!=(const UString &s1, const UString &s2) { return s1.Len() != s2.Len() || wcscmp(s1, s2) != 0; }
    692 inline bool operator!=(const UString &s1, const wchar_t *s2) { return wcscmp(s1, s2) != 0; }
    693 inline bool operator!=(const wchar_t *s1, const UString &s2) { return wcscmp(s1, s2) != 0; }
    694 
    695 
    696 // ---------- forbidden functions ----------
    697 
    698 void operator==(wchar_t c1, const UString &s2);
    699 void operator==(const UString &s1, wchar_t c2);
    700 
    701 void operator+(wchar_t c, const UString &s); // this function can be OK, but we don't use it
    702 
    703 void operator+(const AString &s1, const UString &s2);
    704 void operator+(const UString &s1, const AString &s2);
    705 
    706 void operator+(const UString &s1, const char *s2);
    707 void operator+(const char *s1, const UString &s2);
    708 
    709 void operator+(const UString &s, char c);
    710 void operator+(const UString &s, unsigned char c);
    711 void operator+(char c, const UString &s);
    712 void operator+(unsigned char c, const UString &s);
    713 void operator-(const UString &s1, wchar_t c);
    714 
    715 #ifdef _WIN32
    716 // can we forbid these functions, if wchar_t is 32-bit ?
    717 void operator+(const UString &s, int c);
    718 void operator+(const UString &s, unsigned c);
    719 void operator+(int c, const UString &s);
    720 void operator+(unsigned c, const UString &s);
    721 void operator-(const UString &s1, int c);
    722 void operator-(const UString &s1, unsigned c);
    723 #endif
    724 
    725 
    726 
    727 
    728 
    729 
    730 
    731 class UString2
    732 {
    733  wchar_t *_chars;
    734  unsigned _len;
    735 
    736  void ReAlloc2(unsigned newLimit);
    737  void SetStartLen(unsigned len);
    738 
    739  // ---------- forbidden functions ----------
    740  
    741  FORBID_STRING_OPS_UString2(char)
    742  FORBID_STRING_OPS_UString2(signed char)
    743  FORBID_STRING_OPS_UString2(unsigned char)
    744  FORBID_STRING_OPS_UString2(short)
    745 
    746  UString2 &operator=(wchar_t c);
    747  UString2(wchar_t c);
    748 
    749 public:
    750  UString2(): _chars(NULL), _len(0) {}
    751  UString2(const wchar_t *s);
    752  UString2(const UString2 &s);
    753  ~UString2() { if (_chars) MY_STRING_DELETE(_chars); }
    754 
    755  unsigned Len() const { return _len; }
    756  bool IsEmpty() const { return _len == 0; }
    757  // void Empty() { _len = 0; _chars[0] = 0; }
    758 
    759  // operator const wchar_t *() const { return _chars; }
    760  const wchar_t *GetRawPtr() const { return _chars; }
    761 
    762  int Compare(const wchar_t *s) const { return wcscmp(_chars, s); }
    763 
    764  wchar_t *GetBuf(unsigned minLen)
    765  {
    766    if (!_chars || minLen > _len)
    767      ReAlloc2(minLen);
    768    return _chars;
    769  }
    770  void ReleaseBuf_SetLen(unsigned newLen) { _len = newLen; }
    771 
    772  UString2 &operator=(const wchar_t *s);
    773  UString2 &operator=(const UString2 &s);
    774  void SetFromAscii(const char *s);
    775 };
    776 
    777 bool operator==(const UString2 &s1, const UString2 &s2);
    778 bool operator==(const UString2 &s1, const wchar_t *s2);
    779 bool operator==(const wchar_t *s1, const UString2 &s2);
    780 
    781 inline bool operator!=(const UString2 &s1, const UString2 &s2) { return !(s1 == s2); }
    782 inline bool operator!=(const UString2 &s1, const wchar_t *s2) { return !(s1 == s2); }
    783 inline bool operator!=(const wchar_t *s1, const UString2 &s2) { return !(s1 == s2); }
    784 
    785 
    786 // ---------- forbidden functions ----------
    787 
    788 void operator==(wchar_t c1, const UString2 &s2);
    789 void operator==(const UString2 &s1, wchar_t c2);
    790 bool operator<(const UString2 &s1, const UString2 &s2);
    791 bool operator>(const UString2 &s1, const UString2 &s2);
    792 
    793 void operator+(const UString2 &s1, const UString2 &s2);
    794 void operator+(const UString2 &s1, const wchar_t *s2);
    795 void operator+(const wchar_t *s1, const UString2 &s2);
    796 void operator+(wchar_t c, const UString2 &s);
    797 void operator+(const UString2 &s, wchar_t c);
    798 void operator+(const UString2 &s, char c);
    799 void operator+(const UString2 &s, unsigned char c);
    800 void operator+(char c, const UString2 &s);
    801 void operator+(unsigned char c, const UString2 &s);
    802 void operator-(const UString2 &s1, wchar_t c);
    803 
    804 
    805 
    806 
    807 
    808 
    809 typedef CObjectVector<AString> AStringVector;
    810 typedef CObjectVector<UString> UStringVector;
    811 
    812 #ifdef _UNICODE
    813  typedef UString CSysString;
    814 #else
    815  typedef AString CSysString;
    816 #endif
    817 
    818 typedef CObjectVector<CSysString> CSysStringVector;
    819 
    820 
    821 // ---------- FString ----------
    822 
    823 #ifdef _WIN32
    824  #define USE_UNICODE_FSTRING
    825 #endif
    826 
    827 #ifdef USE_UNICODE_FSTRING
    828 
    829  #define __FTEXT(quote) L##quote
    830 
    831  typedef wchar_t FChar;
    832  typedef UString FString;
    833 
    834  #define fs2us(_x_) (_x_)
    835  #define us2fs(_x_) (_x_)
    836  FString fas2fs(const char *s);
    837  FString fas2fs(const AString &s);
    838  AString fs2fas(const FChar *s);
    839 
    840 #else
    841 
    842  #define __FTEXT(quote) quote
    843 
    844  typedef char FChar;
    845  typedef AString FString;
    846 
    847  UString fs2us(const FChar *s);
    848  UString fs2us(const FString &s);
    849  FString us2fs(const wchar_t *s);
    850  #define fas2fs(_x_) (_x_)
    851  #define fs2fas(_x_) (_x_)
    852 
    853 #endif
    854 
    855 #define FTEXT(quote) __FTEXT(quote)
    856 
    857 #define FCHAR_PATH_SEPARATOR FTEXT(CHAR_PATH_SEPARATOR)
    858 #define FSTRING_PATH_SEPARATOR FTEXT(STRING_PATH_SEPARATOR)
    859 
    860 // #define FCHAR_ANY_MASK FTEXT('*')
    861 // #define FSTRING_ANY_MASK FTEXT("*")
    862 
    863 typedef const FChar *CFSTR;
    864 
    865 typedef CObjectVector<FString> FStringVector;
    866 
    867 #endif