00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef _NPT_STRINGS_H_
00011 #define _NPT_STRINGS_H_
00012
00013
00014
00015
00016 #include "NptConfig.h"
00017 #if defined(NPT_CONFIG_HAVE_NEW_H)
00018 #include <new>
00019 #endif
00020 #include "NptTypes.h"
00021 #include "NptConstants.h"
00022 #include "NptDebug.h"
00023
00024
00025
00026
00027 const int NPT_STRING_SEARCH_FAILED = -1;
00028
00029
00030
00031
00032 class NPT_String
00033 {
00034 public:
00035
00036 static NPT_String FromInteger(long value);
00037 static NPT_String FromIntegerU(unsigned long value);
00038
00039
00040 NPT_String(const NPT_String& str);
00041 NPT_String(const char* str);
00042 NPT_String(const char* str, NPT_Size length);
00043 NPT_String(const char* str, NPT_Ordinal first, NPT_Size length);
00044 NPT_String(char c, NPT_Cardinal repeat = 1);
00045 NPT_String() : m_Chars(NULL) {}
00046 ~NPT_String() { if (m_Chars) delete GetBuffer(); }
00047
00048
00049 bool IsEmpty() const { return m_Chars == NULL || GetBuffer()->GetLength() == 0; }
00050 NPT_Size GetLength() const { return m_Chars ? GetBuffer()->GetLength() : 0; }
00051 NPT_Size GetCapacity() const { return m_Chars ? GetBuffer()->GetAllocated() : 0; }
00052 NPT_Result SetLength(NPT_Size length);
00053 void Assign(const char* chars, NPT_Size size);
00054 void Append(const char* chars, NPT_Size size);
00055 void Append(const char* s) { Append(s, StringLength(s)); }
00056 int Compare(const char* s, bool ignore_case = false) const;
00057 static int Compare(const char* s1, const char* s2, bool ignore_case = false);
00058 int CompareN(const char* s, NPT_Size count, bool ignore_case = false) const;
00059 static int CompareN(const char* s1, const char* s2, NPT_Size count, bool ignore_case = false);
00060
00061
00062 NPT_String SubString(NPT_Ordinal first, NPT_Size length) const;
00063 NPT_String SubString(NPT_Ordinal first) const {
00064 return SubString(first, GetLength());
00065 }
00066 NPT_String Left(NPT_Size length) const {
00067 return SubString(0, length);
00068 }
00069 NPT_String Right(NPT_Size length) const {
00070 return length >= GetLength() ?
00071 *this :
00072 SubString(GetLength()-length, length);
00073 }
00074
00075
00076 void Reserve(NPT_Size length);
00077
00078
00079 NPT_String ToLowercase() const;
00080 NPT_String ToUppercase() const;
00081 NPT_Result ToInteger(long& value, bool relaxed = true) const;
00082 NPT_Result ToInteger(unsigned long& value, bool relaxed = true) const;
00083 NPT_Result ToFloat(float& value, bool relaxed = true) const;
00084
00085
00086 void MakeLowercase();
00087 void MakeUppercase();
00088 void Replace(char a, char b);
00089
00090
00091 int Find(char c, NPT_Ordinal start = 0, bool ignore_case = false) const;
00092 int Find(const char* s, NPT_Ordinal start = 0, bool ignore_case = false) const;
00093 int ReverseFind(char c, NPT_Ordinal start = 0, bool ignore_case = false) const;
00094 int ReverseFind(const char* s, NPT_Ordinal start = 0, bool ignore_case = false) const;
00095 bool StartsWith(const char* s, bool ignore_case = false) const;
00096 bool EndsWith(const char* s, bool ignore_case = false) const;
00097
00098
00099 void Insert(const char* s, NPT_Ordinal where = 0);
00100 void Erase(NPT_Ordinal start, NPT_Cardinal count = 1);
00101 void Replace(NPT_Ordinal start, NPT_Cardinal count, const char* s);
00102 void TrimLeft();
00103 void TrimLeft(char c);
00104 void TrimLeft(const char* chars);
00105 void TrimRight();
00106 void TrimRight(char c);
00107 void TrimRight(const char* chars);
00108 void Trim();
00109 void Trim(char c);
00110 void Trim(const char* chars);
00111
00112
00113 operator char*() const { return m_Chars ? m_Chars: &EmptyString; }
00114 operator const char* () const { return m_Chars ? m_Chars: &EmptyString; }
00115 const char* GetChars() const { return m_Chars ? m_Chars: &EmptyString; }
00116 char* UseChars() { return m_Chars ? m_Chars: &EmptyString; }
00117
00118
00119 NPT_String& operator=(const char* str);
00120 NPT_String& operator=(const NPT_String& str);
00121 NPT_String& operator=(char c);
00122 const NPT_String& operator+=(const NPT_String& s) {
00123 Append(s.GetChars(), s.GetLength());
00124 return *this;
00125 }
00126 const NPT_String& operator+=(const char* s) {
00127 Append(s);
00128 return *this;
00129 }
00130 const NPT_String& operator+=(char c) {
00131 Append(&c, 1);
00132 return *this;
00133 }
00134 char operator[](int index) const {
00135 NPT_ASSERT((unsigned int)index < GetLength());
00136 return GetChars()[index];
00137 }
00138 char& operator[](int index) {
00139 NPT_ASSERT((unsigned int)index < GetLength());
00140 return UseChars()[index];
00141 }
00142
00143
00144 friend NPT_String operator+(const NPT_String& s1, const NPT_String& s2) {
00145 return s1+s2.GetChars();
00146 }
00147 friend NPT_String operator+(const NPT_String& s1, const char* s2);
00148 friend NPT_String operator+(const char* s1, const NPT_String& s2);
00149 friend NPT_String operator+(const NPT_String& s, char c);
00150 friend NPT_String operator+(char c, const NPT_String& s);
00151
00152 protected:
00153
00154 class Buffer {
00155 public:
00156
00157 static Buffer* Allocate(NPT_Size allocated, NPT_Size length) {
00158 void* mem = ::operator new(sizeof(Buffer)+allocated+1);
00159 return new(mem) Buffer(allocated, length);
00160 }
00161 static char* Create(NPT_Size allocated, NPT_Size length=0) {
00162 Buffer* shared = Allocate(allocated, length);
00163 return shared->GetChars();
00164 }
00165 static char* Create(const char* copy) {
00166 NPT_Size length = StringLength(copy);
00167 Buffer* shared = Allocate(length, length);
00168 CopyString(shared->GetChars(), copy);
00169 return shared->GetChars();
00170 }
00171 static char* Create(const char* copy, NPT_Size length) {
00172 Buffer* shared = Allocate(length, length);
00173 CopyBuffer(shared->GetChars(), copy, length);
00174 shared->GetChars()[length] = '\0';
00175 return shared->GetChars();
00176 }
00177 static char* Create(char c, NPT_Cardinal repeat) {
00178 Buffer* shared = Allocate(repeat, repeat);
00179 char* s = shared->GetChars();
00180 while (repeat--) {
00181 *s++ = c;
00182 }
00183 *s = '\0';
00184 return shared->GetChars();
00185 }
00186
00187
00188 char* GetChars() {
00189
00190 return reinterpret_cast<char*>(this+1);
00191 }
00192 NPT_Size GetLength() const { return m_Length; }
00193 void SetLength(NPT_Size length) { m_Length = length; }
00194 NPT_Size GetAllocated() const { return m_Allocated; }
00195
00196 private:
00197
00198 Buffer(NPT_Size allocated, NPT_Size length = 0) :
00199 m_Length(length),
00200 m_Allocated(allocated) {}
00201
00202
00203 NPT_Cardinal m_Length;
00204 NPT_Cardinal m_Allocated;
00205
00206
00207 };
00208
00209
00210 char* m_Chars;
00211
00212 private:
00213
00214 friend class Buffer;
00215
00216
00217 static char EmptyString;
00218
00219
00220 Buffer* GetBuffer() const {
00221 return reinterpret_cast<Buffer*>(m_Chars)-1;
00222 }
00223 void Reset() {
00224 if (m_Chars != NULL) {
00225 delete GetBuffer();
00226 m_Chars = NULL;
00227 }
00228 }
00229 char* PrepareToWrite(NPT_Size length);
00230 void PrepareToAppend(NPT_Size length, NPT_Size allocate);
00231
00232
00233 static void CopyString(char* dst, const char* src) {
00234 while ((*dst++ = *src++)){}
00235 }
00236
00237 static void CopyBuffer(char* dst, const char* src, NPT_Size size) {
00238 while (size--) *dst++ = *src++;
00239 }
00240
00241 static NPT_Size StringLength(const char* str) {
00242 NPT_Size length = 0;
00243 while (*str++) length++;
00244 return length;
00245 }
00246 };
00247
00248
00249
00250
00251 inline bool operator==(const NPT_String& s1, const NPT_String& s2) {
00252 return s1.Compare(s2) == 0;
00253 }
00254 inline bool operator==(const NPT_String& s1, const char* s2) {
00255 return s1.Compare(s2) == 0;
00256 }
00257 inline bool operator==(const char* s1, const NPT_String& s2) {
00258 return s2.Compare(s1) == 0;
00259 }
00260 inline bool operator!=(const NPT_String& s1, const NPT_String& s2) {
00261 return s1.Compare(s2) != 0;
00262 }
00263 inline bool operator!=(const NPT_String& s1, const char* s2) {
00264 return s1.Compare(s2) != 0;
00265 }
00266 inline bool operator!=(const char* s1, const NPT_String& s2) {
00267 return s2.Compare(s1) != 0;
00268 }
00269 inline bool operator<(const NPT_String& s1, const NPT_String& s2) {
00270 return s1.Compare(s2) < 0;
00271 }
00272 inline bool operator<(const NPT_String& s1, const char* s2) {
00273 return s1.Compare(s2) < 0;
00274 }
00275 inline bool operator<(const char* s1, const NPT_String& s2) {
00276 return s2.Compare(s1) > 0;
00277 }
00278 inline bool operator>(const NPT_String& s1, const NPT_String& s2) {
00279 return s1.Compare(s2) > 0;
00280 }
00281 inline bool operator>(const NPT_String& s1, const char* s2) {
00282 return s1.Compare(s2) > 0;
00283 }
00284 inline bool operator>(const char* s1, const NPT_String& s2) {
00285 return s2.Compare(s1) < 0;
00286 }
00287 inline bool operator<=(const NPT_String& s1, const NPT_String& s2) {
00288 return s1.Compare(s2) <= 0;
00289 }
00290 inline bool operator<=(const NPT_String& s1, const char* s2) {
00291 return s1.Compare(s2) <= 0;
00292 }
00293 inline bool operator<=(const char* s1, const NPT_String& s2) {
00294 return s2.Compare(s1) >= 0;
00295 }
00296 inline bool operator>=(const NPT_String& s1, const NPT_String& s2) {
00297 return s1.Compare(s2) >= 0;
00298 }
00299 inline bool operator>=(const NPT_String& s1, const char* s2) {
00300 return s1.Compare(s2) >= 0;
00301 }
00302 inline bool operator>=(const char* s1, const NPT_String& s2) {
00303 return s2.Compare(s1) <= 0;
00304 }
00305
00306 #endif // _NPT_STRINGS_H_