misc/libphysfs/lzma/CPP/Common/MyString.h
changeset 12218 bb5522e88ab2
equal deleted inserted replaced
12217:ea891871f481 12218:bb5522e88ab2
       
     1 // Common/String.h
       
     2 
       
     3 #ifndef __COMMON_STRING_H
       
     4 #define __COMMON_STRING_H
       
     5 
       
     6 #include <string.h>
       
     7 // #include <wchar.h>
       
     8 
       
     9 #include "MyVector.h"
       
    10 
       
    11 #ifdef _WIN32
       
    12 #include "MyWindows.h"
       
    13 #endif
       
    14 
       
    15 template <class T>
       
    16 inline int MyStringLen(const T *s)
       
    17 { 
       
    18   int i;
       
    19   for (i = 0; s[i] != '\0'; i++);
       
    20   return i;
       
    21 }
       
    22 
       
    23 template <class T>
       
    24 inline T * MyStringCopy(T *dest, const T *src)
       
    25 { 
       
    26   T *destStart = dest;
       
    27   while((*dest++ = *src++) != 0);
       
    28   return destStart;
       
    29 }
       
    30 
       
    31 inline wchar_t* MyStringGetNextCharPointer(wchar_t *p)
       
    32   { return (p + 1); }
       
    33 inline const wchar_t* MyStringGetNextCharPointer(const wchar_t *p)
       
    34   { return (p + 1); }
       
    35 inline wchar_t* MyStringGetPrevCharPointer(const wchar_t *, wchar_t *p)
       
    36   { return (p - 1); }
       
    37 inline const wchar_t* MyStringGetPrevCharPointer(const wchar_t *, const wchar_t *p)
       
    38   { return (p - 1); }
       
    39 
       
    40 #ifdef _WIN32
       
    41 
       
    42 inline char* MyStringGetNextCharPointer(char *p)
       
    43   { return CharNextA(p); }
       
    44 inline const char* MyStringGetNextCharPointer(const char *p)
       
    45   { return CharNextA(p); }
       
    46 
       
    47 inline char* MyStringGetPrevCharPointer(char *base, char *p)
       
    48   { return CharPrevA(base, p); }
       
    49 inline const char* MyStringGetPrevCharPointer(const char *base, const char *p)
       
    50   { return CharPrevA(base, p); }
       
    51 
       
    52 inline char MyCharUpper(char c)
       
    53   { return (char)(unsigned int)(UINT_PTR)CharUpperA((LPSTR)(UINT_PTR)(unsigned int)(unsigned char)c); }
       
    54 #ifdef _UNICODE
       
    55 inline wchar_t MyCharUpper(wchar_t c)
       
    56   { return (wchar_t)(unsigned int)(UINT_PTR)CharUpperW((LPWSTR)(UINT_PTR)(unsigned int)c); }
       
    57 #else
       
    58 wchar_t MyCharUpper(wchar_t c);
       
    59 #endif
       
    60 
       
    61 inline char MyCharLower(char c)
       
    62   { return (char)(unsigned int)(UINT_PTR)CharLowerA((LPSTR)(UINT_PTR)(unsigned int)(unsigned char)c); }
       
    63 #ifdef _UNICODE
       
    64 inline wchar_t MyCharLower(wchar_t c)
       
    65   { return (wchar_t)(unsigned int)(UINT_PTR)CharLowerW((LPWSTR)(UINT_PTR)(unsigned int)c); }
       
    66 #else
       
    67 wchar_t MyCharLower(wchar_t c);
       
    68 #endif
       
    69 
       
    70 inline char * MyStringUpper(char *s) { return CharUpperA(s); }
       
    71 #ifdef _UNICODE
       
    72 inline wchar_t * MyStringUpper(wchar_t *s) { return CharUpperW(s); }
       
    73 #else
       
    74 wchar_t * MyStringUpper(wchar_t *s);
       
    75 #endif
       
    76 
       
    77 inline char * MyStringLower(char *s) { return CharLowerA(s); }
       
    78 #ifdef _UNICODE
       
    79 inline wchar_t * MyStringLower(wchar_t *s) { return CharLowerW(s); }
       
    80 #else
       
    81 wchar_t * MyStringLower(wchar_t *s);
       
    82 #endif
       
    83 
       
    84 #else // Standard-C
       
    85 wchar_t MyCharUpper(wchar_t c);
       
    86 #endif
       
    87 
       
    88 //////////////////////////////////////
       
    89 // Compare
       
    90 
       
    91 /*
       
    92 #ifndef _WIN32_WCE
       
    93 int MyStringCollate(const char *s1, const char *s2);
       
    94 int MyStringCollateNoCase(const char *s1, const char *s2);
       
    95 #endif
       
    96 int MyStringCollate(const wchar_t *s1, const wchar_t *s2);
       
    97 int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2);
       
    98 */
       
    99 
       
   100 int MyStringCompare(const char *s1, const char  *s2);
       
   101 int MyStringCompare(const wchar_t *s1, const wchar_t *s2);
       
   102 
       
   103 #ifdef _WIN32
       
   104 int MyStringCompareNoCase(const char *s1, const char  *s2);
       
   105 #endif
       
   106 
       
   107 int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2);
       
   108 
       
   109 template <class T>
       
   110 class CStringBase
       
   111 {
       
   112   void TrimLeftWithCharSet(const CStringBase &charSet)
       
   113   {
       
   114     const T *p = _chars;
       
   115     while (charSet.Find(*p) >= 0 && (*p != 0))
       
   116       p = GetNextCharPointer(p);
       
   117     Delete(0, (int)(p - _chars));
       
   118   }
       
   119   void TrimRightWithCharSet(const CStringBase &charSet)
       
   120   {
       
   121     const T *p = _chars;
       
   122     const T *pLast = NULL;
       
   123     while (*p != 0)
       
   124     {
       
   125       if (charSet.Find(*p) >= 0)
       
   126       {
       
   127         if (pLast == NULL)
       
   128           pLast = p;
       
   129       }
       
   130       else
       
   131         pLast = NULL;
       
   132       p = GetNextCharPointer(p);
       
   133     }
       
   134     if(pLast != NULL)
       
   135     {
       
   136       int i = (int)(pLast - _chars);
       
   137       Delete(i, _length - i);
       
   138     }
       
   139 
       
   140   }
       
   141   void MoveItems(int destIndex, int srcIndex)
       
   142   {
       
   143     memmove(_chars + destIndex, _chars + srcIndex, 
       
   144         sizeof(T) * (_length - srcIndex + 1));
       
   145   }
       
   146   
       
   147   void InsertSpace(int &index, int size)
       
   148   {
       
   149     CorrectIndex(index);
       
   150     GrowLength(size);
       
   151     MoveItems(index + size, index);
       
   152   }
       
   153 
       
   154   static T *GetNextCharPointer(T *p)
       
   155     { return MyStringGetNextCharPointer(p); }
       
   156   static const T *GetNextCharPointer(const T *p)
       
   157     { return MyStringGetNextCharPointer(p); }
       
   158   static T *GetPrevCharPointer(T *base, T *p)
       
   159     { return MyStringGetPrevCharPointer(base, p); }
       
   160   static const T *GetPrevCharPointer(const T *base, const T *p)
       
   161     { return MyStringGetPrevCharPointer(base, p); }
       
   162 protected:
       
   163   T *_chars;
       
   164   int _length;
       
   165   int _capacity;
       
   166   
       
   167   void SetCapacity(int newCapacity)
       
   168   {
       
   169     int realCapacity = newCapacity + 1;
       
   170     if(realCapacity == _capacity)
       
   171       return;
       
   172     /*
       
   173     const int kMaxStringSize = 0x20000000;
       
   174     #ifndef _WIN32_WCE
       
   175     if(newCapacity > kMaxStringSize || newCapacity < _length)
       
   176       throw 1052337;
       
   177     #endif
       
   178     */
       
   179     T *newBuffer = new T[realCapacity];
       
   180     if(_capacity > 0)
       
   181     {
       
   182       for (int i = 0; i < (_length + 1); i++)
       
   183         newBuffer[i] = _chars[i];
       
   184       delete []_chars;
       
   185       _chars = newBuffer;
       
   186     }
       
   187     else
       
   188     {
       
   189       _chars = newBuffer;
       
   190       _chars[0] = 0;
       
   191     }
       
   192     _capacity = realCapacity;
       
   193   }
       
   194 
       
   195   void GrowLength(int n)
       
   196   {
       
   197     int freeSize = _capacity - _length - 1;
       
   198     if (n <= freeSize) 
       
   199       return;
       
   200     int delta;
       
   201     if (_capacity > 64)
       
   202       delta = _capacity / 2;
       
   203     else if (_capacity > 8)
       
   204       delta = 16;
       
   205     else
       
   206       delta = 4;
       
   207     if (freeSize + delta < n)
       
   208       delta = n - freeSize;
       
   209     SetCapacity(_capacity + delta);
       
   210   }
       
   211 
       
   212   void CorrectIndex(int &index) const
       
   213   {
       
   214     if (index > _length)
       
   215       index = _length;
       
   216   }
       
   217 
       
   218 public:
       
   219   CStringBase(): _chars(0), _length(0), _capacity(0)
       
   220     { SetCapacity(16 - 1); }
       
   221   CStringBase(T c):  _chars(0), _length(0), _capacity(0)
       
   222   {
       
   223     SetCapacity(1);
       
   224     _chars[0] = c;
       
   225     _chars[1] = 0;
       
   226     _length = 1;
       
   227   }
       
   228   CStringBase(const T *chars): _chars(0), _length(0), _capacity(0)
       
   229   {
       
   230     int length = MyStringLen(chars);
       
   231     SetCapacity(length);
       
   232     MyStringCopy(_chars, chars); // can be optimized by memove()
       
   233     _length = length;
       
   234   }
       
   235   CStringBase(const CStringBase &s):  _chars(0), _length(0), _capacity(0)
       
   236   {
       
   237     SetCapacity(s._length);
       
   238     MyStringCopy(_chars, s._chars);
       
   239     _length = s._length;
       
   240   }
       
   241   ~CStringBase() {  delete []_chars; }
       
   242 
       
   243   operator const T*() const { return _chars;} 
       
   244 
       
   245   // The minimum size of the character buffer in characters. 
       
   246   // This value does not include space for a null terminator.
       
   247   T* GetBuffer(int minBufLength)
       
   248   {
       
   249     if(minBufLength >= _capacity)
       
   250       SetCapacity(minBufLength + 1);
       
   251     return _chars;
       
   252   }
       
   253   void ReleaseBuffer() { ReleaseBuffer(MyStringLen(_chars)); }
       
   254   void ReleaseBuffer(int newLength)
       
   255   {
       
   256     /*
       
   257     #ifndef _WIN32_WCE
       
   258     if(newLength >= _capacity)
       
   259       throw 282217;
       
   260     #endif
       
   261     */
       
   262     _chars[newLength] = 0;
       
   263     _length = newLength;
       
   264   }
       
   265 
       
   266   CStringBase& operator=(T c)
       
   267   {
       
   268     Empty();
       
   269     SetCapacity(1);
       
   270     _chars[0] = c;
       
   271     _chars[1] = 0;
       
   272     _length = 1;
       
   273     return *this;
       
   274   }
       
   275   CStringBase& operator=(const T *chars)
       
   276   {
       
   277     Empty();
       
   278     int length = MyStringLen(chars);
       
   279     SetCapacity(length);
       
   280     MyStringCopy(_chars, chars);
       
   281     _length = length; 
       
   282     return *this;
       
   283   }  
       
   284   CStringBase& operator=(const CStringBase& s)
       
   285   {
       
   286     if(&s == this)
       
   287       return *this;
       
   288     Empty();
       
   289     SetCapacity(s._length);
       
   290     MyStringCopy(_chars, s._chars);
       
   291     _length = s._length;
       
   292     return *this;
       
   293   }
       
   294   
       
   295   CStringBase& operator+=(T c)
       
   296   {
       
   297     GrowLength(1);
       
   298     _chars[_length] = c;
       
   299     _chars[++_length] = 0;
       
   300     return *this;
       
   301   }
       
   302   CStringBase& operator+=(const T *s)
       
   303   {
       
   304     int len = MyStringLen(s);
       
   305     GrowLength(len);
       
   306     MyStringCopy(_chars + _length, s);
       
   307     _length += len;
       
   308     return *this;
       
   309   }
       
   310   CStringBase& operator+=(const CStringBase &s)
       
   311   {
       
   312     GrowLength(s._length);
       
   313     MyStringCopy(_chars + _length, s._chars);
       
   314     _length += s._length;
       
   315     return *this;
       
   316   }
       
   317   void Empty()
       
   318   {
       
   319     _length = 0;
       
   320     _chars[0] = 0;
       
   321   }
       
   322   int Length() const { return _length; }
       
   323   bool IsEmpty() const { return (_length == 0); }
       
   324 
       
   325   CStringBase Mid(int startIndex) const
       
   326     { return Mid(startIndex, _length - startIndex); }
       
   327   CStringBase Mid(int startIndex, int count ) const
       
   328   {
       
   329     if (startIndex + count > _length)
       
   330       count = _length - startIndex;
       
   331     
       
   332     if (startIndex == 0 && startIndex + count == _length)
       
   333       return *this;
       
   334     
       
   335     CStringBase<T> result;
       
   336     result.SetCapacity(count);
       
   337     // MyStringNCopy(result._chars, _chars + startIndex, count);
       
   338     for (int i = 0; i < count; i++)
       
   339       result._chars[i] = _chars[startIndex + i];
       
   340     result._chars[count] = 0;
       
   341     result._length = count;
       
   342     return result;
       
   343   }
       
   344   CStringBase Left(int count) const
       
   345     { return Mid(0, count); }
       
   346   CStringBase Right(int count) const
       
   347   {
       
   348     if (count > _length)
       
   349       count = _length;
       
   350     return Mid(_length - count, count);
       
   351   }
       
   352 
       
   353   void MakeUpper()
       
   354     { MyStringUpper(_chars); }
       
   355   void MakeLower()
       
   356     { MyStringLower(_chars); }
       
   357 
       
   358   int Compare(const CStringBase& s) const
       
   359     { return MyStringCompare(_chars, s._chars); }
       
   360 
       
   361   int Compare(const T *s) const
       
   362     { return MyStringCompare(_chars, s); }
       
   363 
       
   364   int CompareNoCase(const CStringBase& s) const
       
   365     { return MyStringCompareNoCase(_chars, s._chars); }
       
   366 
       
   367   int CompareNoCase(const T *s) const
       
   368     { return MyStringCompareNoCase(_chars, s); }
       
   369 
       
   370   /*
       
   371   int Collate(const CStringBase& s) const
       
   372     { return MyStringCollate(_chars, s._chars); }
       
   373   int CollateNoCase(const CStringBase& s) const
       
   374     { return MyStringCollateNoCase(_chars, s._chars); }
       
   375   */
       
   376 
       
   377   int Find(T c) const { return Find(c, 0); }
       
   378   int Find(T c, int startIndex) const
       
   379   {
       
   380     T *p = _chars + startIndex;
       
   381     for (;;)
       
   382     {
       
   383       if (*p == c)
       
   384         return (int)(p - _chars);
       
   385       if (*p == 0)
       
   386         return -1;
       
   387       p = GetNextCharPointer(p);
       
   388     }
       
   389   }
       
   390   int Find(const CStringBase &s) const { return Find(s, 0); }
       
   391   int Find(const CStringBase &s, int startIndex) const
       
   392   {
       
   393     if (s.IsEmpty())
       
   394       return startIndex;
       
   395     for (; startIndex < _length; startIndex++)
       
   396     {
       
   397       int j;
       
   398       for (j = 0; j < s._length && startIndex + j < _length; j++)
       
   399         if (_chars[startIndex+j] != s._chars[j])
       
   400           break;
       
   401       if (j == s._length)
       
   402         return startIndex;
       
   403     }
       
   404     return -1;
       
   405   }
       
   406   int ReverseFind(T c) const
       
   407   {
       
   408     if (_length == 0)
       
   409       return -1;
       
   410     T *p = _chars + _length - 1;
       
   411     for (;;)
       
   412     {
       
   413       if (*p == c)
       
   414         return (int)(p - _chars);
       
   415       if (p == _chars)
       
   416         return -1;
       
   417       p = GetPrevCharPointer(_chars, p);
       
   418     }
       
   419   }
       
   420   int FindOneOf(const CStringBase &s) const
       
   421   {
       
   422     for(int i = 0; i < _length; i++)
       
   423       if (s.Find(_chars[i]) >= 0)
       
   424         return i;
       
   425       return -1;
       
   426   }
       
   427 
       
   428   void TrimLeft(T c)
       
   429   {
       
   430     const T *p = _chars;
       
   431     while (c == *p)
       
   432       p = GetNextCharPointer(p);
       
   433     Delete(0, p - _chars);
       
   434   }
       
   435   private:
       
   436   CStringBase GetTrimDefaultCharSet()
       
   437   {
       
   438     CStringBase<T> charSet;
       
   439     charSet += (T)' ';
       
   440     charSet += (T)'\n';
       
   441     charSet += (T)'\t';
       
   442     return charSet;
       
   443   }
       
   444   public:
       
   445 
       
   446   void TrimLeft()
       
   447   {
       
   448     TrimLeftWithCharSet(GetTrimDefaultCharSet());
       
   449   }
       
   450   void TrimRight()
       
   451   {
       
   452     TrimRightWithCharSet(GetTrimDefaultCharSet());
       
   453   }
       
   454   void TrimRight(T c)
       
   455   {
       
   456     const T *p = _chars;
       
   457     const T *pLast = NULL;
       
   458     while (*p != 0)
       
   459     {
       
   460       if (*p == c)
       
   461       {
       
   462         if (pLast == NULL)
       
   463           pLast = p;
       
   464       }
       
   465       else
       
   466         pLast = NULL;
       
   467       p = GetNextCharPointer(p);
       
   468     }
       
   469     if(pLast != NULL)
       
   470     {
       
   471       int i = pLast - _chars;
       
   472       Delete(i, _length - i);
       
   473     }
       
   474   }
       
   475   void Trim()
       
   476   {
       
   477     TrimRight();
       
   478     TrimLeft();
       
   479   }
       
   480 
       
   481   int Insert(int index, T c)
       
   482   {
       
   483     InsertSpace(index, 1);
       
   484     _chars[index] = c;
       
   485     _length++;
       
   486     return _length;
       
   487   }
       
   488   int Insert(int index, const CStringBase &s)
       
   489   {
       
   490     CorrectIndex(index);
       
   491     if (s.IsEmpty())
       
   492       return _length;
       
   493     int numInsertChars = s.Length();
       
   494     InsertSpace(index, numInsertChars);
       
   495     for(int i = 0; i < numInsertChars; i++)
       
   496       _chars[index + i] = s[i];
       
   497     _length += numInsertChars;
       
   498     return _length;
       
   499   }
       
   500 
       
   501   // !!!!!!!!!!!!!!! test it if newChar = '\0'
       
   502   int Replace(T oldChar, T newChar)
       
   503   {
       
   504     if (oldChar == newChar)
       
   505       return 0;
       
   506     int number  = 0;
       
   507     int pos  = 0;
       
   508     while (pos < Length())
       
   509     {
       
   510       pos = Find(oldChar, pos);
       
   511       if (pos < 0) 
       
   512         break;
       
   513       _chars[pos] = newChar;
       
   514       pos++;
       
   515       number++;
       
   516     }
       
   517     return number;
       
   518   }
       
   519   int Replace(const CStringBase &oldString, const CStringBase &newString)
       
   520   {
       
   521     if (oldString.IsEmpty())
       
   522       return 0;
       
   523     if (oldString == newString)
       
   524       return 0;
       
   525     int oldStringLength = oldString.Length();
       
   526     int newStringLength = newString.Length();
       
   527     int number  = 0;
       
   528     int pos  = 0;
       
   529     while (pos < _length)
       
   530     {
       
   531       pos = Find(oldString, pos);
       
   532       if (pos < 0) 
       
   533         break;
       
   534       Delete(pos, oldStringLength);
       
   535       Insert(pos, newString);
       
   536       pos += newStringLength;
       
   537       number++;
       
   538     }
       
   539     return number;
       
   540   }
       
   541   int Delete(int index, int count = 1 )
       
   542   {
       
   543     if (index + count > _length)
       
   544       count = _length - index;
       
   545     if (count > 0)
       
   546     {
       
   547       MoveItems(index, index + count);
       
   548       _length -= count;
       
   549     }
       
   550     return _length;
       
   551   }
       
   552 };
       
   553 
       
   554 template <class T>
       
   555 CStringBase<T> operator+(const CStringBase<T>& s1, const CStringBase<T>& s2)
       
   556 {
       
   557   CStringBase<T> result(s1);
       
   558   result += s2;
       
   559   return result; 
       
   560 }
       
   561 
       
   562 template <class T>
       
   563 CStringBase<T> operator+(const CStringBase<T>& s, T c)
       
   564 {
       
   565   CStringBase<T> result(s);
       
   566   result += c;
       
   567   return result; 
       
   568 }
       
   569 
       
   570 template <class T>
       
   571 CStringBase<T> operator+(T c, const CStringBase<T>& s)
       
   572 {
       
   573   CStringBase<T> result(c);
       
   574   result += s;
       
   575   return result; 
       
   576 }
       
   577 
       
   578 template <class T>
       
   579 CStringBase<T> operator+(const CStringBase<T>& s, const T * chars)
       
   580 {
       
   581   CStringBase<T> result(s);
       
   582   result += chars;
       
   583   return result; 
       
   584 }
       
   585 
       
   586 template <class T>
       
   587 CStringBase<T> operator+(const T * chars, const CStringBase<T>& s)
       
   588 {
       
   589   CStringBase<T> result(chars);
       
   590   result += s;
       
   591   return result; 
       
   592 }
       
   593 
       
   594 template <class T>
       
   595 bool operator==(const CStringBase<T>& s1, const CStringBase<T>& s2)
       
   596   { return (s1.Compare(s2) == 0); }
       
   597 
       
   598 template <class T>
       
   599 bool operator<(const CStringBase<T>& s1, const CStringBase<T>& s2)
       
   600   { return (s1.Compare(s2) < 0); }
       
   601 
       
   602 template <class T>
       
   603 bool operator==(const T *s1, const CStringBase<T>& s2)
       
   604   { return (s2.Compare(s1) == 0); }
       
   605 
       
   606 template <class T>
       
   607 bool operator==(const CStringBase<T>& s1, const T *s2)
       
   608   { return (s1.Compare(s2) == 0); }
       
   609 
       
   610 template <class T>
       
   611 bool operator!=(const CStringBase<T>& s1, const CStringBase<T>& s2)
       
   612   { return (s1.Compare(s2) != 0); }
       
   613 
       
   614 template <class T>
       
   615 bool operator!=(const T *s1, const CStringBase<T>& s2)
       
   616   { return (s2.Compare(s1) != 0); }
       
   617 
       
   618 template <class T>
       
   619 bool operator!=(const CStringBase<T>& s1, const T *s2)
       
   620   { return (s1.Compare(s2) != 0); }
       
   621 
       
   622 typedef CStringBase<char> AString;
       
   623 typedef CStringBase<wchar_t> UString;
       
   624 
       
   625 typedef CObjectVector<AString> AStringVector;
       
   626 typedef CObjectVector<UString> UStringVector;
       
   627 
       
   628 #ifdef _UNICODE
       
   629   typedef UString CSysString;
       
   630 #else
       
   631   typedef AString CSysString;
       
   632 #endif
       
   633 
       
   634 typedef CObjectVector<CSysString> CSysStringVector;
       
   635 
       
   636 #endif