Upload 2.0.2
[physicsfs] / lzma / CPP / Common / MyString.h
diff --git a/lzma/CPP/Common/MyString.h b/lzma/CPP/Common/MyString.h
new file mode 100644 (file)
index 0000000..c46ca54
--- /dev/null
@@ -0,0 +1,636 @@
+// Common/String.h
+
+#ifndef __COMMON_STRING_H
+#define __COMMON_STRING_H
+
+#include <string.h>
+// #include <wchar.h>
+
+#include "MyVector.h"
+
+#ifdef _WIN32
+#include "MyWindows.h"
+#endif
+
+template <class T>
+inline int MyStringLen(const T *s)
+{ 
+  int i;
+  for (i = 0; s[i] != '\0'; i++);
+  return i;
+}
+
+template <class T>
+inline T * MyStringCopy(T *dest, const T *src)
+{ 
+  T *destStart = dest;
+  while((*dest++ = *src++) != 0);
+  return destStart;
+}
+
+inline wchar_t* MyStringGetNextCharPointer(wchar_t *p)
+  { return (p + 1); }
+inline const wchar_t* MyStringGetNextCharPointer(const wchar_t *p)
+  { return (p + 1); }
+inline wchar_t* MyStringGetPrevCharPointer(const wchar_t *, wchar_t *p)
+  { return (p - 1); }
+inline const wchar_t* MyStringGetPrevCharPointer(const wchar_t *, const wchar_t *p)
+  { return (p - 1); }
+
+#ifdef _WIN32
+
+inline char* MyStringGetNextCharPointer(char *p)
+  { return CharNextA(p); }
+inline const char* MyStringGetNextCharPointer(const char *p)
+  { return CharNextA(p); }
+
+inline char* MyStringGetPrevCharPointer(char *base, char *p)
+  { return CharPrevA(base, p); }
+inline const char* MyStringGetPrevCharPointer(const char *base, const char *p)
+  { return CharPrevA(base, p); }
+
+inline char MyCharUpper(char c)
+  { return (char)(unsigned int)(UINT_PTR)CharUpperA((LPSTR)(UINT_PTR)(unsigned int)(unsigned char)c); }
+#ifdef _UNICODE
+inline wchar_t MyCharUpper(wchar_t c)
+  { return (wchar_t)(unsigned int)(UINT_PTR)CharUpperW((LPWSTR)(UINT_PTR)(unsigned int)c); }
+#else
+wchar_t MyCharUpper(wchar_t c);
+#endif
+
+inline char MyCharLower(char c)
+  { return (char)(unsigned int)(UINT_PTR)CharLowerA((LPSTR)(UINT_PTR)(unsigned int)(unsigned char)c); }
+#ifdef _UNICODE
+inline wchar_t MyCharLower(wchar_t c)
+  { return (wchar_t)(unsigned int)(UINT_PTR)CharLowerW((LPWSTR)(UINT_PTR)(unsigned int)c); }
+#else
+wchar_t MyCharLower(wchar_t c);
+#endif
+
+inline char * MyStringUpper(char *s) { return CharUpperA(s); }
+#ifdef _UNICODE
+inline wchar_t * MyStringUpper(wchar_t *s) { return CharUpperW(s); }
+#else
+wchar_t * MyStringUpper(wchar_t *s);
+#endif
+
+inline char * MyStringLower(char *s) { return CharLowerA(s); }
+#ifdef _UNICODE
+inline wchar_t * MyStringLower(wchar_t *s) { return CharLowerW(s); }
+#else
+wchar_t * MyStringLower(wchar_t *s);
+#endif
+
+#else // Standard-C
+wchar_t MyCharUpper(wchar_t c);
+#endif
+
+//////////////////////////////////////
+// Compare
+
+/*
+#ifndef _WIN32_WCE
+int MyStringCollate(const char *s1, const char *s2);
+int MyStringCollateNoCase(const char *s1, const char *s2);
+#endif
+int MyStringCollate(const wchar_t *s1, const wchar_t *s2);
+int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2);
+*/
+
+int MyStringCompare(const char *s1, const char  *s2);
+int MyStringCompare(const wchar_t *s1, const wchar_t *s2);
+
+#ifdef _WIN32
+int MyStringCompareNoCase(const char *s1, const char  *s2);
+#endif
+
+int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2);
+
+template <class T>
+class CStringBase
+{
+  void TrimLeftWithCharSet(const CStringBase &charSet)
+  {
+    const T *p = _chars;
+    while (charSet.Find(*p) >= 0 && (*p != 0))
+      p = GetNextCharPointer(p);
+    Delete(0, (int)(p - _chars));
+  }
+  void TrimRightWithCharSet(const CStringBase &charSet)
+  {
+    const T *p = _chars;
+    const T *pLast = NULL;
+    while (*p != 0)
+    {
+      if (charSet.Find(*p) >= 0)
+      {
+        if (pLast == NULL)
+          pLast = p;
+      }
+      else
+        pLast = NULL;
+      p = GetNextCharPointer(p);
+    }
+    if(pLast != NULL)
+    {
+      int i = (int)(pLast - _chars);
+      Delete(i, _length - i);
+    }
+
+  }
+  void MoveItems(int destIndex, int srcIndex)
+  {
+    memmove(_chars + destIndex, _chars + srcIndex, 
+        sizeof(T) * (_length - srcIndex + 1));
+  }
+  
+  void InsertSpace(int &index, int size)
+  {
+    CorrectIndex(index);
+    GrowLength(size);
+    MoveItems(index + size, index);
+  }
+
+  static T *GetNextCharPointer(T *p)
+    { return MyStringGetNextCharPointer(p); }
+  static const T *GetNextCharPointer(const T *p)
+    { return MyStringGetNextCharPointer(p); }
+  static T *GetPrevCharPointer(T *base, T *p)
+    { return MyStringGetPrevCharPointer(base, p); }
+  static const T *GetPrevCharPointer(const T *base, const T *p)
+    { return MyStringGetPrevCharPointer(base, p); }
+protected:
+  T *_chars;
+  int _length;
+  int _capacity;
+  
+  void SetCapacity(int newCapacity)
+  {
+    int realCapacity = newCapacity + 1;
+    if(realCapacity == _capacity)
+      return;
+    /*
+    const int kMaxStringSize = 0x20000000;
+    #ifndef _WIN32_WCE
+    if(newCapacity > kMaxStringSize || newCapacity < _length)
+      throw 1052337;
+    #endif
+    */
+    T *newBuffer = new T[realCapacity];
+    if(_capacity > 0)
+    {
+      for (int i = 0; i < (_length + 1); i++)
+        newBuffer[i] = _chars[i];
+      delete []_chars;
+      _chars = newBuffer;
+    }
+    else
+    {
+      _chars = newBuffer;
+      _chars[0] = 0;
+    }
+    _capacity = realCapacity;
+  }
+
+  void GrowLength(int n)
+  {
+    int freeSize = _capacity - _length - 1;
+    if (n <= freeSize) 
+      return;
+    int delta;
+    if (_capacity > 64)
+      delta = _capacity / 2;
+    else if (_capacity > 8)
+      delta = 16;
+    else
+      delta = 4;
+    if (freeSize + delta < n)
+      delta = n - freeSize;
+    SetCapacity(_capacity + delta);
+  }
+
+  void CorrectIndex(int &index) const
+  {
+    if (index > _length)
+      index = _length;
+  }
+
+public:
+  CStringBase(): _chars(0), _length(0), _capacity(0)
+    { SetCapacity(16 - 1); }
+  CStringBase(T c):  _chars(0), _length(0), _capacity(0)
+  {
+    SetCapacity(1);
+    _chars[0] = c;
+    _chars[1] = 0;
+    _length = 1;
+  }
+  CStringBase(const T *chars): _chars(0), _length(0), _capacity(0)
+  {
+    int length = MyStringLen(chars);
+    SetCapacity(length);
+    MyStringCopy(_chars, chars); // can be optimized by memove()
+    _length = length;
+  }
+  CStringBase(const CStringBase &s):  _chars(0), _length(0), _capacity(0)
+  {
+    SetCapacity(s._length);
+    MyStringCopy(_chars, s._chars);
+    _length = s._length;
+  }
+  ~CStringBase() {  delete []_chars; }
+
+  operator const T*() const { return _chars;} 
+
+  // The minimum size of the character buffer in characters. 
+  // This value does not include space for a null terminator.
+  T* GetBuffer(int minBufLength)
+  {
+    if(minBufLength >= _capacity)
+      SetCapacity(minBufLength + 1);
+    return _chars;
+  }
+  void ReleaseBuffer() { ReleaseBuffer(MyStringLen(_chars)); }
+  void ReleaseBuffer(int newLength)
+  {
+    /*
+    #ifndef _WIN32_WCE
+    if(newLength >= _capacity)
+      throw 282217;
+    #endif
+    */
+    _chars[newLength] = 0;
+    _length = newLength;
+  }
+
+  CStringBase& operator=(T c)
+  {
+    Empty();
+    SetCapacity(1);
+    _chars[0] = c;
+    _chars[1] = 0;
+    _length = 1;
+    return *this;
+  }
+  CStringBase& operator=(const T *chars)
+  {
+    Empty();
+    int length = MyStringLen(chars);
+    SetCapacity(length);
+    MyStringCopy(_chars, chars);
+    _length = length; 
+    return *this;
+  }  
+  CStringBase& operator=(const CStringBase& s)
+  {
+    if(&s == this)
+      return *this;
+    Empty();
+    SetCapacity(s._length);
+    MyStringCopy(_chars, s._chars);
+    _length = s._length;
+    return *this;
+  }
+  
+  CStringBase& operator+=(T c)
+  {
+    GrowLength(1);
+    _chars[_length] = c;
+    _chars[++_length] = 0;
+    return *this;
+  }
+  CStringBase& operator+=(const T *s)
+  {
+    int len = MyStringLen(s);
+    GrowLength(len);
+    MyStringCopy(_chars + _length, s);
+    _length += len;
+    return *this;
+  }
+  CStringBase& operator+=(const CStringBase &s)
+  {
+    GrowLength(s._length);
+    MyStringCopy(_chars + _length, s._chars);
+    _length += s._length;
+    return *this;
+  }
+  void Empty()
+  {
+    _length = 0;
+    _chars[0] = 0;
+  }
+  int Length() const { return _length; }
+  bool IsEmpty() const { return (_length == 0); }
+
+  CStringBase Mid(int startIndex) const
+    { return Mid(startIndex, _length - startIndex); }
+  CStringBase Mid(int startIndex, int count ) const
+  {
+    if (startIndex + count > _length)
+      count = _length - startIndex;
+    
+    if (startIndex == 0 && startIndex + count == _length)
+      return *this;
+    
+    CStringBase<T> result;
+    result.SetCapacity(count);
+    // MyStringNCopy(result._chars, _chars + startIndex, count);
+    for (int i = 0; i < count; i++)
+      result._chars[i] = _chars[startIndex + i];
+    result._chars[count] = 0;
+    result._length = count;
+    return result;
+  }
+  CStringBase Left(int count) const
+    { return Mid(0, count); }
+  CStringBase Right(int count) const
+  {
+    if (count > _length)
+      count = _length;
+    return Mid(_length - count, count);
+  }
+
+  void MakeUpper()
+    { MyStringUpper(_chars); }
+  void MakeLower()
+    { MyStringLower(_chars); }
+
+  int Compare(const CStringBase& s) const
+    { return MyStringCompare(_chars, s._chars); }
+
+  int Compare(const T *s) const
+    { return MyStringCompare(_chars, s); }
+
+  int CompareNoCase(const CStringBase& s) const
+    { return MyStringCompareNoCase(_chars, s._chars); }
+
+  int CompareNoCase(const T *s) const
+    { return MyStringCompareNoCase(_chars, s); }
+
+  /*
+  int Collate(const CStringBase& s) const
+    { return MyStringCollate(_chars, s._chars); }
+  int CollateNoCase(const CStringBase& s) const
+    { return MyStringCollateNoCase(_chars, s._chars); }
+  */
+
+  int Find(T c) const { return Find(c, 0); }
+  int Find(T c, int startIndex) const
+  {
+    T *p = _chars + startIndex;
+    for (;;)
+    {
+      if (*p == c)
+        return (int)(p - _chars);
+      if (*p == 0)
+        return -1;
+      p = GetNextCharPointer(p);
+    }
+  }
+  int Find(const CStringBase &s) const { return Find(s, 0); }
+  int Find(const CStringBase &s, int startIndex) const
+  {
+    if (s.IsEmpty())
+      return startIndex;
+    for (; startIndex < _length; startIndex++)
+    {
+      int j;
+      for (j = 0; j < s._length && startIndex + j < _length; j++)
+        if (_chars[startIndex+j] != s._chars[j])
+          break;
+      if (j == s._length)
+        return startIndex;
+    }
+    return -1;
+  }
+  int ReverseFind(T c) const
+  {
+    if (_length == 0)
+      return -1;
+    T *p = _chars + _length - 1;
+    for (;;)
+    {
+      if (*p == c)
+        return (int)(p - _chars);
+      if (p == _chars)
+        return -1;
+      p = GetPrevCharPointer(_chars, p);
+    }
+  }
+  int FindOneOf(const CStringBase &s) const
+  {
+    for(int i = 0; i < _length; i++)
+      if (s.Find(_chars[i]) >= 0)
+        return i;
+      return -1;
+  }
+
+  void TrimLeft(T c)
+  {
+    const T *p = _chars;
+    while (c == *p)
+      p = GetNextCharPointer(p);
+    Delete(0, p - _chars);
+  }
+  private:
+  CStringBase GetTrimDefaultCharSet()
+  {
+    CStringBase<T> charSet;
+    charSet += (T)' ';
+    charSet += (T)'\n';
+    charSet += (T)'\t';
+    return charSet;
+  }
+  public:
+
+  void TrimLeft()
+  {
+    TrimLeftWithCharSet(GetTrimDefaultCharSet());
+  }
+  void TrimRight()
+  {
+    TrimRightWithCharSet(GetTrimDefaultCharSet());
+  }
+  void TrimRight(T c)
+  {
+    const T *p = _chars;
+    const T *pLast = NULL;
+    while (*p != 0)
+    {
+      if (*p == c)
+      {
+        if (pLast == NULL)
+          pLast = p;
+      }
+      else
+        pLast = NULL;
+      p = GetNextCharPointer(p);
+    }
+    if(pLast != NULL)
+    {
+      int i = pLast - _chars;
+      Delete(i, _length - i);
+    }
+  }
+  void Trim()
+  {
+    TrimRight();
+    TrimLeft();
+  }
+
+  int Insert(int index, T c)
+  {
+    InsertSpace(index, 1);
+    _chars[index] = c;
+    _length++;
+    return _length;
+  }
+  int Insert(int index, const CStringBase &s)
+  {
+    CorrectIndex(index);
+    if (s.IsEmpty())
+      return _length;
+    int numInsertChars = s.Length();
+    InsertSpace(index, numInsertChars);
+    for(int i = 0; i < numInsertChars; i++)
+      _chars[index + i] = s[i];
+    _length += numInsertChars;
+    return _length;
+  }
+
+  // !!!!!!!!!!!!!!! test it if newChar = '\0'
+  int Replace(T oldChar, T newChar)
+  {
+    if (oldChar == newChar)
+      return 0;
+    int number  = 0;
+    int pos  = 0;
+    while (pos < Length())
+    {
+      pos = Find(oldChar, pos);
+      if (pos < 0) 
+        break;
+      _chars[pos] = newChar;
+      pos++;
+      number++;
+    }
+    return number;
+  }
+  int Replace(const CStringBase &oldString, const CStringBase &newString)
+  {
+    if (oldString.IsEmpty())
+      return 0;
+    if (oldString == newString)
+      return 0;
+    int oldStringLength = oldString.Length();
+    int newStringLength = newString.Length();
+    int number  = 0;
+    int pos  = 0;
+    while (pos < _length)
+    {
+      pos = Find(oldString, pos);
+      if (pos < 0) 
+        break;
+      Delete(pos, oldStringLength);
+      Insert(pos, newString);
+      pos += newStringLength;
+      number++;
+    }
+    return number;
+  }
+  int Delete(int index, int count = 1 )
+  {
+    if (index + count > _length)
+      count = _length - index;
+    if (count > 0)
+    {
+      MoveItems(index, index + count);
+      _length -= count;
+    }
+    return _length;
+  }
+};
+
+template <class T>
+CStringBase<T> operator+(const CStringBase<T>& s1, const CStringBase<T>& s2)
+{
+  CStringBase<T> result(s1);
+  result += s2;
+  return result; 
+}
+
+template <class T>
+CStringBase<T> operator+(const CStringBase<T>& s, T c)
+{
+  CStringBase<T> result(s);
+  result += c;
+  return result; 
+}
+
+template <class T>
+CStringBase<T> operator+(T c, const CStringBase<T>& s)
+{
+  CStringBase<T> result(c);
+  result += s;
+  return result; 
+}
+
+template <class T>
+CStringBase<T> operator+(const CStringBase<T>& s, const T * chars)
+{
+  CStringBase<T> result(s);
+  result += chars;
+  return result; 
+}
+
+template <class T>
+CStringBase<T> operator+(const T * chars, const CStringBase<T>& s)
+{
+  CStringBase<T> result(chars);
+  result += s;
+  return result; 
+}
+
+template <class T>
+bool operator==(const CStringBase<T>& s1, const CStringBase<T>& s2)
+  { return (s1.Compare(s2) == 0); }
+
+template <class T>
+bool operator<(const CStringBase<T>& s1, const CStringBase<T>& s2)
+  { return (s1.Compare(s2) < 0); }
+
+template <class T>
+bool operator==(const T *s1, const CStringBase<T>& s2)
+  { return (s2.Compare(s1) == 0); }
+
+template <class T>
+bool operator==(const CStringBase<T>& s1, const T *s2)
+  { return (s1.Compare(s2) == 0); }
+
+template <class T>
+bool operator!=(const CStringBase<T>& s1, const CStringBase<T>& s2)
+  { return (s1.Compare(s2) != 0); }
+
+template <class T>
+bool operator!=(const T *s1, const CStringBase<T>& s2)
+  { return (s2.Compare(s1) != 0); }
+
+template <class T>
+bool operator!=(const CStringBase<T>& s1, const T *s2)
+  { return (s1.Compare(s2) != 0); }
+
+typedef CStringBase<char> AString;
+typedef CStringBase<wchar_t> UString;
+
+typedef CObjectVector<AString> AStringVector;
+typedef CObjectVector<UString> UStringVector;
+
+#ifdef _UNICODE
+  typedef UString CSysString;
+#else
+  typedef AString CSysString;
+#endif
+
+typedef CObjectVector<CSysString> CSysStringVector;
+
+#endif