Annotation of elwix/tools/oldlzma/SRC/Common/String.h, revision 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>