Mercurial > vba-clojure
view src/win32/7zip/7z/CPP/Common/MyString.h @ 1:f9f4f1b99eed
importing src directory
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 03 Mar 2012 10:31:27 -0600 |
parents | |
children |
line wrap: on
line source
1 // Common/String.h3 #ifndef __COMMON_STRING_H4 #define __COMMON_STRING_H6 #include <string.h>7 // #include <wchar.h>9 #include "MyVector.h"11 #ifdef _WIN3212 #include "MyWindows.h"13 #endif15 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 }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 }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); }40 #ifdef _WIN3242 inline char* MyStringGetNextCharPointer(char *p)43 { return CharNextA(p); }44 inline const char* MyStringGetNextCharPointer(const char *p)45 { return CharNextA(p); }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); }52 inline char MyCharUpper(char c)53 { return (char)(unsigned int)(UINT_PTR)CharUpperA((LPSTR)(UINT_PTR)(unsigned int)(unsigned char)c); }54 #ifdef _UNICODE55 inline wchar_t MyCharUpper(wchar_t c)56 { return (wchar_t)(unsigned int)(UINT_PTR)CharUpperW((LPWSTR)(UINT_PTR)(unsigned int)c); }57 #else58 wchar_t MyCharUpper(wchar_t c);59 #endif61 inline char MyCharLower(char c)62 { return (char)(unsigned int)(UINT_PTR)CharLowerA((LPSTR)(UINT_PTR)(unsigned int)(unsigned char)c); }63 #ifdef _UNICODE64 inline wchar_t MyCharLower(wchar_t c)65 { return (wchar_t)(unsigned int)(UINT_PTR)CharLowerW((LPWSTR)(UINT_PTR)(unsigned int)c); }66 #else67 wchar_t MyCharLower(wchar_t c);68 #endif70 inline char * MyStringUpper(char *s) { return CharUpperA(s); }71 #ifdef _UNICODE72 inline wchar_t * MyStringUpper(wchar_t *s) { return CharUpperW(s); }73 #else74 wchar_t * MyStringUpper(wchar_t *s);75 #endif77 inline char * MyStringLower(char *s) { return CharLowerA(s); }78 #ifdef _UNICODE79 inline wchar_t * MyStringLower(wchar_t *s) { return CharLowerW(s); }80 #else81 wchar_t * MyStringLower(wchar_t *s);82 #endif84 #else // Standard-C85 wchar_t MyCharUpper(wchar_t c);86 #endif88 //////////////////////////////////////89 // Compare91 /*92 #ifndef _WIN32_WCE93 int MyStringCollate(const char *s1, const char *s2);94 int MyStringCollateNoCase(const char *s1, const char *s2);95 #endif96 int MyStringCollate(const wchar_t *s1, const wchar_t *s2);97 int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2);98 */100 int MyStringCompare(const char *s1, const char *s2);101 int MyStringCompare(const wchar_t *s1, const wchar_t *s2);103 #ifdef _WIN32104 int MyStringCompareNoCase(const char *s1, const char *s2);105 #endif107 int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2);109 template <class T>110 class CStringBase111 {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 else131 pLast = NULL;132 p = GetNextCharPointer(p);133 }134 if (pLast != NULL)135 {136 int i = (int)(pLast - _chars);137 Delete(i, _length - i);138 }140 }141 void MoveItems(int destIndex, int srcIndex)142 {143 memmove(_chars + destIndex, _chars + srcIndex,144 sizeof(T) * (_length - srcIndex + 1));145 }147 void InsertSpace(int &index, int size)148 {149 CorrectIndex(index);150 GrowLength(size);151 MoveItems(index + size, index);152 }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;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_WCE175 if (newCapacity > kMaxStringSize || newCapacity < _length)176 throw 1052337;177 #endif178 */179 T *newBuffer = new T[realCapacity];180 if (_capacity > 0)181 {182 for (int i = 0; i < _length; i++)183 newBuffer[i] = _chars[i];184 delete []_chars;185 }186 _chars = newBuffer;187 _chars[_length] = 0;188 _capacity = realCapacity;189 }191 void GrowLength(int n)192 {193 int freeSize = _capacity - _length - 1;194 if (n <= freeSize)195 return;196 int delta;197 if (_capacity > 64)198 delta = _capacity / 2;199 else if (_capacity > 8)200 delta = 16;201 else202 delta = 4;203 if (freeSize + delta < n)204 delta = n - freeSize;205 SetCapacity(_capacity + delta);206 }208 void CorrectIndex(int &index) const209 {210 if (index > _length)211 index = _length;212 }214 public:215 CStringBase(): _chars(0), _length(0), _capacity(0) { SetCapacity(3); }216 CStringBase(T c): _chars(0), _length(0), _capacity(0)217 {218 SetCapacity(1);219 _chars[0] = c;220 _chars[1] = 0;221 _length = 1;222 }223 CStringBase(const T *chars): _chars(0), _length(0), _capacity(0)224 {225 int length = MyStringLen(chars);226 SetCapacity(length);227 MyStringCopy(_chars, chars); // can be optimized by memove()228 _length = length;229 }230 CStringBase(const CStringBase &s): _chars(0), _length(0), _capacity(0)231 {232 SetCapacity(s._length);233 MyStringCopy(_chars, s._chars);234 _length = s._length;235 }236 ~CStringBase() { delete []_chars; }238 operator const T*() const { return _chars;}240 // The minimum size of the character buffer in characters.241 // This value does not include space for a null terminator.242 T* GetBuffer(int minBufLength)243 {244 if (minBufLength >= _capacity)245 SetCapacity(minBufLength);246 return _chars;247 }248 void ReleaseBuffer() { ReleaseBuffer(MyStringLen(_chars)); }249 void ReleaseBuffer(int newLength)250 {251 /*252 #ifndef _WIN32_WCE253 if (newLength >= _capacity)254 throw 282217;255 #endif256 */257 _chars[newLength] = 0;258 _length = newLength;259 }261 CStringBase& operator=(T c)262 {263 Empty();264 SetCapacity(1);265 _chars[0] = c;266 _chars[1] = 0;267 _length = 1;268 return *this;269 }270 CStringBase& operator=(const T *chars)271 {272 Empty();273 int length = MyStringLen(chars);274 SetCapacity(length);275 MyStringCopy(_chars, chars);276 _length = length;277 return *this;278 }279 CStringBase& operator=(const CStringBase& s)280 {281 if (&s == this)282 return *this;283 Empty();284 SetCapacity(s._length);285 MyStringCopy(_chars, s._chars);286 _length = s._length;287 return *this;288 }290 CStringBase& operator+=(T c)291 {292 GrowLength(1);293 _chars[_length] = c;294 _chars[++_length] = 0;295 return *this;296 }297 CStringBase& operator+=(const T *s)298 {299 int len = MyStringLen(s);300 GrowLength(len);301 MyStringCopy(_chars + _length, s);302 _length += len;303 return *this;304 }305 CStringBase& operator+=(const CStringBase &s)306 {307 GrowLength(s._length);308 MyStringCopy(_chars + _length, s._chars);309 _length += s._length;310 return *this;311 }312 void Empty()313 {314 _length = 0;315 _chars[0] = 0;316 }317 int Length() const { return _length; }318 bool IsEmpty() const { return (_length == 0); }320 CStringBase Mid(int startIndex) const321 { return Mid(startIndex, _length - startIndex); }322 CStringBase Mid(int startIndex, int count ) const323 {324 if (startIndex + count > _length)325 count = _length - startIndex;327 if (startIndex == 0 && startIndex + count == _length)328 return *this;330 CStringBase<T> result;331 result.SetCapacity(count);332 // MyStringNCopy(result._chars, _chars + startIndex, count);333 for (int i = 0; i < count; i++)334 result._chars[i] = _chars[startIndex + i];335 result._chars[count] = 0;336 result._length = count;337 return result;338 }339 CStringBase Left(int count) const340 { return Mid(0, count); }341 CStringBase Right(int count) const342 {343 if (count > _length)344 count = _length;345 return Mid(_length - count, count);346 }348 void MakeUpper()349 { MyStringUpper(_chars); }350 void MakeLower()351 { MyStringLower(_chars); }353 int Compare(const CStringBase& s) const354 { return MyStringCompare(_chars, s._chars); }356 int Compare(const T *s) const357 { return MyStringCompare(_chars, s); }359 int CompareNoCase(const CStringBase& s) const360 { return MyStringCompareNoCase(_chars, s._chars); }362 int CompareNoCase(const T *s) const363 { return MyStringCompareNoCase(_chars, s); }365 /*366 int Collate(const CStringBase& s) const367 { return MyStringCollate(_chars, s._chars); }368 int CollateNoCase(const CStringBase& s) const369 { return MyStringCollateNoCase(_chars, s._chars); }370 */372 int Find(T c) const { return Find(c, 0); }373 int Find(T c, int startIndex) const374 {375 T *p = _chars + startIndex;376 for (;;)377 {378 if (*p == c)379 return (int)(p - _chars);380 if (*p == 0)381 return -1;382 p = GetNextCharPointer(p);383 }384 }385 int Find(const CStringBase &s) const { return Find(s, 0); }386 int Find(const CStringBase &s, int startIndex) const387 {388 if (s.IsEmpty())389 return startIndex;390 for (; startIndex < _length; startIndex++)391 {392 int j;393 for (j = 0; j < s._length && startIndex + j < _length; j++)394 if (_chars[startIndex+j] != s._chars[j])395 break;396 if (j == s._length)397 return startIndex;398 }399 return -1;400 }401 int ReverseFind(T c) const402 {403 if (_length == 0)404 return -1;405 T *p = _chars + _length - 1;406 for (;;)407 {408 if (*p == c)409 return (int)(p - _chars);410 if (p == _chars)411 return -1;412 p = GetPrevCharPointer(_chars, p);413 }414 }415 int FindOneOf(const CStringBase &s) const416 {417 for (int i = 0; i < _length; i++)418 if (s.Find(_chars[i]) >= 0)419 return i;420 return -1;421 }423 void TrimLeft(T c)424 {425 const T *p = _chars;426 while (c == *p)427 p = GetNextCharPointer(p);428 Delete(0, p - _chars);429 }430 private:431 CStringBase GetTrimDefaultCharSet()432 {433 CStringBase<T> charSet;434 charSet += (T)' ';435 charSet += (T)'\n';436 charSet += (T)'\t';437 return charSet;438 }439 public:441 void TrimLeft()442 {443 TrimLeftWithCharSet(GetTrimDefaultCharSet());444 }445 void TrimRight()446 {447 TrimRightWithCharSet(GetTrimDefaultCharSet());448 }449 void TrimRight(T c)450 {451 const T *p = _chars;452 const T *pLast = NULL;453 while (*p != 0)454 {455 if (*p == c)456 {457 if (pLast == NULL)458 pLast = p;459 }460 else461 pLast = NULL;462 p = GetNextCharPointer(p);463 }464 if (pLast != NULL)465 {466 int i = pLast - _chars;467 Delete(i, _length - i);468 }469 }470 void Trim()471 {472 TrimRight();473 TrimLeft();474 }476 int Insert(int index, T c)477 {478 InsertSpace(index, 1);479 _chars[index] = c;480 _length++;481 return _length;482 }483 int Insert(int index, const CStringBase &s)484 {485 CorrectIndex(index);486 if (s.IsEmpty())487 return _length;488 int numInsertChars = s.Length();489 InsertSpace(index, numInsertChars);490 for (int i = 0; i < numInsertChars; i++)491 _chars[index + i] = s[i];492 _length += numInsertChars;493 return _length;494 }496 // !!!!!!!!!!!!!!! test it if newChar = '\0'497 int Replace(T oldChar, T newChar)498 {499 if (oldChar == newChar)500 return 0;501 int number = 0;502 int pos = 0;503 while (pos < Length())504 {505 pos = Find(oldChar, pos);506 if (pos < 0)507 break;508 _chars[pos] = newChar;509 pos++;510 number++;511 }512 return number;513 }514 int Replace(const CStringBase &oldString, const CStringBase &newString)515 {516 if (oldString.IsEmpty())517 return 0;518 if (oldString == newString)519 return 0;520 int oldStringLength = oldString.Length();521 int newStringLength = newString.Length();522 int number = 0;523 int pos = 0;524 while (pos < _length)525 {526 pos = Find(oldString, pos);527 if (pos < 0)528 break;529 Delete(pos, oldStringLength);530 Insert(pos, newString);531 pos += newStringLength;532 number++;533 }534 return number;535 }536 int Delete(int index, int count = 1 )537 {538 if (index + count > _length)539 count = _length - index;540 if (count > 0)541 {542 MoveItems(index, index + count);543 _length -= count;544 }545 return _length;546 }547 };549 template <class T>550 CStringBase<T> operator+(const CStringBase<T>& s1, const CStringBase<T>& s2)551 {552 CStringBase<T> result(s1);553 result += s2;554 return result;555 }557 template <class T>558 CStringBase<T> operator+(const CStringBase<T>& s, T c)559 {560 CStringBase<T> result(s);561 result += c;562 return result;563 }565 template <class T>566 CStringBase<T> operator+(T c, const CStringBase<T>& s)567 {568 CStringBase<T> result(c);569 result += s;570 return result;571 }573 template <class T>574 CStringBase<T> operator+(const CStringBase<T>& s, const T * chars)575 {576 CStringBase<T> result(s);577 result += chars;578 return result;579 }581 template <class T>582 CStringBase<T> operator+(const T * chars, const CStringBase<T>& s)583 {584 CStringBase<T> result(chars);585 result += s;586 return result;587 }589 template <class T>590 bool operator==(const CStringBase<T>& s1, const CStringBase<T>& s2)591 { return (s1.Compare(s2) == 0); }593 template <class T>594 bool operator<(const CStringBase<T>& s1, const CStringBase<T>& s2)595 { return (s1.Compare(s2) < 0); }597 template <class T>598 bool operator==(const T *s1, const CStringBase<T>& s2)599 { return (s2.Compare(s1) == 0); }601 template <class T>602 bool operator==(const CStringBase<T>& s1, const T *s2)603 { return (s1.Compare(s2) == 0); }605 template <class T>606 bool operator!=(const CStringBase<T>& s1, const CStringBase<T>& s2)607 { return (s1.Compare(s2) != 0); }609 template <class T>610 bool operator!=(const T *s1, const CStringBase<T>& s2)611 { return (s2.Compare(s1) != 0); }613 template <class T>614 bool operator!=(const CStringBase<T>& s1, const T *s2)615 { return (s1.Compare(s2) != 0); }617 typedef CStringBase<char> AString;618 typedef CStringBase<wchar_t> UString;620 typedef CObjectVector<AString> AStringVector;621 typedef CObjectVector<UString> UStringVector;623 #ifdef _UNICODE624 typedef UString CSysString;625 #else626 typedef AString CSysString;627 #endif629 typedef CObjectVector<CSysString> CSysStringVector;631 #endif