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>