/* * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. * All rights reserved. */ /** \file * \ingroup string */ #ifndef __STR_STRING_H__ #define __STR_STRING_H__ #ifndef STR_NO_ASSERTD # undef assertd # define assertd(exp) ((void)NULL) #endif #include #include #include #include #ifdef WITH_CXX_GUARDEDALLOC # include "MEM_guardedalloc.h" #endif #ifdef _WIN32 # define stricmp _stricmp #endif class STR_String; typedef unsigned long dword; typedef const STR_String &rcSTR_String; typedef unsigned char byte; /** * Smart String Value class. Is used by parser when an expression tree is build containing string. */ class STR_String { public: // Initialization STR_String(); STR_String(char c); STR_String(char c, int len); STR_String(const char *str); STR_String(const char *str, int len); STR_String(const STR_String &str); STR_String(const STR_String &str, int len); STR_String(const char *src1, int src1_len, const char *src2, int src2_len); explicit STR_String(int val); explicit STR_String(dword val); explicit STR_String(float val); explicit STR_String(double val); inline ~STR_String() { delete[] this->m_data; } // Operations STR_String &Format(const char *fmt, ...) // Set formatted text to string #ifdef __GNUC__ __attribute__((format(printf, 2, 3))) #endif ; STR_String &FormatAdd(const char *fmt, ...) // Add formatted text to string #ifdef __GNUC__ __attribute__((format(printf, 2, 3))) #endif ; inline void Clear() { this->m_len = this->m_data[0] = 0; } inline const STR_String &Reverse() { for (int i1 = 0, i2 = this->m_len - 1; i1 < i2; i1++, i2--) { std::swap(this->m_data[i1], this->m_data[i2]); } return *this; } // Properties bool IsUpper() const; bool IsLower() const; inline bool IsEmpty() const { return this->m_len == 0; } inline int Length() const { return this->m_len; } // Data access inline STR_String &SetLength(int len) { AllocBuffer(len, true); this->m_len = len; this->m_data[len] = 0; return *this; } inline char GetAt(int pos) const { assertd(pos < this->m_len); return this->m_data[pos]; } inline void SetAt(int pos, char c) { assertd(pos < this->m_len); this->m_data[pos] = c; } inline void SetAt(int pos, rcSTR_String str); inline void SetAt(int pos, int num, rcSTR_String str); void Replace(int pos, rcSTR_String str); void Replace(int pos, int num, rcSTR_String str); // Substrings inline STR_String Left(int num) const { num = (num < this->m_len ? num : this->m_len); return STR_String(this->m_data, num); } inline STR_String Right(int num) const { num = (num < this->m_len ? num : this->m_len); return STR_String(this->m_data + this->m_len - num, num); } inline STR_String Mid(int pos, int num = INT_MAX) const { pos = (pos < this->m_len ? pos : this->m_len); num = (num < (this->m_len - pos) ? num : (this->m_len - pos)); return STR_String(this->m_data + pos, num); } // Comparison int Compare(rcSTR_String rhs) const; int CompareNoCase(rcSTR_String rhs) const; inline bool IsEqual(rcSTR_String rhs) const { return (Compare(rhs) == 0); } inline bool IsEqualNoCase(rcSTR_String rhs) const { return (CompareNoCase(rhs) == 0); } // Search/replace int Find(char c, int pos = 0) const; int Find(const char *str, int pos = 0) const; int Find(rcSTR_String str, int pos = 0) const; int RFind(char c) const; int FindOneOf(const char *set, int pos = 0) const; int RFindOneOf(const char *set, int pos = 0) const; std::vector Explode(char c) const; // Formatting STR_String &Upper(); STR_String &Lower(); STR_String &Capitalize(); STR_String &TrimLeft(); STR_String &TrimLeft(char *set); STR_String &TrimRight(); STR_String &TrimRight(char *set); STR_String &Trim(); STR_String &Trim(char *set); STR_String &TrimQuotes(); // Conversions // inline operator char*() { return this->m_data; } inline operator const char *() const { return this->m_data; } inline char *Ptr() { return this->m_data; } inline const char *ReadPtr() const { return this->m_data; } inline float ToFloat() const { float x = (float)(atof(this->m_data)); return x; } inline int ToInt() const { return atoi(this->m_data); } // Operators inline rcSTR_String operator=(const byte *rhs) { return Copy((const char *)rhs, strlen((const char *)rhs)); } inline rcSTR_String operator=(rcSTR_String rhs) { return Copy(rhs.ReadPtr(), rhs.Length()); } inline rcSTR_String operator=(char rhs) { return Copy(&rhs, 1); } inline rcSTR_String operator=(const char *rhs) { return Copy(rhs, strlen(rhs)); } inline rcSTR_String operator+=(const char *rhs) { return Concat(rhs, strlen(rhs)); } inline rcSTR_String operator+=(rcSTR_String rhs) { return Concat(rhs.ReadPtr(), rhs.Length()); } inline rcSTR_String operator+=(char rhs) { return Concat(&rhs, 1); } inline friend bool operator<(rcSTR_String lhs, rcSTR_String rhs) { return (strcmp(lhs, rhs) < 0); } inline friend bool operator<(rcSTR_String lhs, const char *rhs) { return (strcmp(lhs, rhs) < 0); } inline friend bool operator<(const char *lhs, rcSTR_String rhs) { return (strcmp(lhs, rhs) < 0); } inline friend bool operator>(rcSTR_String lhs, rcSTR_String rhs) { return (strcmp(lhs, rhs) > 0); } inline friend bool operator>(rcSTR_String lhs, const char *rhs) { return (strcmp(lhs, rhs) > 0); } inline friend bool operator>(const char *lhs, rcSTR_String rhs) { return (strcmp(lhs, rhs) > 0); } inline friend bool operator<=(rcSTR_String lhs, rcSTR_String rhs) { return (strcmp(lhs, rhs) <= 0); } inline friend bool operator<=(rcSTR_String lhs, const char *rhs) { return (strcmp(lhs, rhs) <= 0); } inline friend bool operator<=(const char *lhs, rcSTR_String rhs) { return (strcmp(lhs, rhs) <= 0); } inline friend bool operator>=(rcSTR_String lhs, rcSTR_String rhs) { return (strcmp(lhs, rhs) >= 0); } inline friend bool operator>=(rcSTR_String lhs, const char *rhs) { return (strcmp(lhs, rhs) >= 0); } inline friend bool operator>=(const char *lhs, rcSTR_String rhs) { return (strcmp(lhs, rhs) >= 0); } inline friend bool operator==(rcSTR_String lhs, rcSTR_String rhs) { return ((lhs.Length() == rhs.Length()) && (memcmp(lhs, rhs, lhs.Length()) == 0)); } inline friend bool operator==(rcSTR_String lhs, const char *rhs) { return (strncmp(lhs, rhs, lhs.Length() + 1) == 0); } inline friend bool operator==(const char *lhs, rcSTR_String rhs) { return (strncmp(lhs, rhs, rhs.Length() + 1) == 0); } inline friend bool operator!=(rcSTR_String lhs, rcSTR_String rhs) { return ((lhs.Length() != rhs.Length()) || (memcmp(lhs, rhs, lhs.Length()) != 0)); } inline friend bool operator!=(rcSTR_String lhs, const char *rhs) { return (strncmp(lhs, rhs, lhs.Length() + 1) != 0); } inline friend bool operator!=(const char *lhs, rcSTR_String rhs) { return (strncmp(lhs, rhs, rhs.Length() + 1) != 0); } // serializing // int Serialize(pCStream stream); protected: // Implementation void AllocBuffer(int len, bool keep_contents); rcSTR_String Copy(const char *src, int len); rcSTR_String Concat(const char *data, int len); static bool isLower(char c) { return !isUpper(c); } static bool isUpper(char c) { return (c >= 'A') && (c <= 'Z'); } static bool isSpace(char c) { return (c == ' ') || (c == '\t'); } char *m_data; // -> STR_String data int m_len; // z Data length int m_max; // Space in data buffer #ifdef WITH_CXX_GUARDEDALLOC MEM_CXX_CLASS_ALLOC_FUNCS("CXX:STR_String") #endif }; inline STR_String operator+(rcSTR_String lhs, rcSTR_String rhs) { return STR_String(lhs.ReadPtr(), lhs.Length(), rhs.ReadPtr(), rhs.Length()); } inline STR_String operator+(rcSTR_String lhs, char rhs) { return STR_String(lhs.ReadPtr(), lhs.Length(), &rhs, 1); } inline STR_String operator+(char lhs, rcSTR_String rhs) { return STR_String(&lhs, 1, rhs.ReadPtr(), rhs.Length()); } inline STR_String operator+(rcSTR_String lhs, const char *rhs) { return STR_String(lhs.ReadPtr(), lhs.Length(), rhs, strlen(rhs)); } inline STR_String operator+(const char *lhs, rcSTR_String rhs) { return STR_String(lhs, strlen(lhs), rhs.ReadPtr(), rhs.Length()); } #endif //__STR_STRING_H__