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>