Annotation of elwix/tools/oldlzma/SRC/Common/String.h, revision 1.1.1.1

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>