A port of the irrlicht XML parser library.

Committer:
hlipka
Date:
Wed Nov 17 20:19:41 2010 +0000
Revision:
0:41a49a73580c
initial version

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hlipka 0:41a49a73580c 1 // Copyright (C) 2002-2005 Nikolaus Gebhardt
hlipka 0:41a49a73580c 2 // This file is part of the "Irrlicht Engine" and the "irrXML" project.
hlipka 0:41a49a73580c 3 // For conditions of distribution and use, see copyright notice in irrlicht.h and irrXML.h
hlipka 0:41a49a73580c 4
hlipka 0:41a49a73580c 5 #ifndef __IRR_STRING_H_INCLUDED__
hlipka 0:41a49a73580c 6 #define __IRR_STRING_H_INCLUDED__
hlipka 0:41a49a73580c 7
hlipka 0:41a49a73580c 8 #include "irrTypes.h"
hlipka 0:41a49a73580c 9
hlipka 0:41a49a73580c 10 namespace irr
hlipka 0:41a49a73580c 11 {
hlipka 0:41a49a73580c 12 namespace core
hlipka 0:41a49a73580c 13 {
hlipka 0:41a49a73580c 14
hlipka 0:41a49a73580c 15 //! Very simple string class with some useful features.
hlipka 0:41a49a73580c 16 /** string<c8> and string<wchar_t> work both with unicode AND ascii,
hlipka 0:41a49a73580c 17 so you can assign unicode to string<c8> and ascii to string<wchar_t>
hlipka 0:41a49a73580c 18 (and the other way round) if your ever would want to.
hlipka 0:41a49a73580c 19 Note that the conversation between both is not done using an encoding.
hlipka 0:41a49a73580c 20
hlipka 0:41a49a73580c 21 Known bugs:
hlipka 0:41a49a73580c 22 Special characters like 'Ä', 'Ü' and 'Ö' are ignored in the
hlipka 0:41a49a73580c 23 methods make_upper, make_lower and equals_ignore_case.
hlipka 0:41a49a73580c 24 */
hlipka 0:41a49a73580c 25 template <class T>
hlipka 0:41a49a73580c 26 class string
hlipka 0:41a49a73580c 27 {
hlipka 0:41a49a73580c 28 public:
hlipka 0:41a49a73580c 29
hlipka 0:41a49a73580c 30 //! Default constructor
hlipka 0:41a49a73580c 31 string()
hlipka 0:41a49a73580c 32 : allocated(1), used(1), array(0)
hlipka 0:41a49a73580c 33 {
hlipka 0:41a49a73580c 34 array = new T[1];
hlipka 0:41a49a73580c 35 array[0] = 0x0;
hlipka 0:41a49a73580c 36 }
hlipka 0:41a49a73580c 37
hlipka 0:41a49a73580c 38
hlipka 0:41a49a73580c 39
hlipka 0:41a49a73580c 40 //! Constructor
hlipka 0:41a49a73580c 41 string(const string<T>& other)
hlipka 0:41a49a73580c 42 : allocated(0), used(0), array(0)
hlipka 0:41a49a73580c 43 {
hlipka 0:41a49a73580c 44 *this = other;
hlipka 0:41a49a73580c 45 }
hlipka 0:41a49a73580c 46
hlipka 0:41a49a73580c 47
hlipka 0:41a49a73580c 48 //! Constructs a string from an int
hlipka 0:41a49a73580c 49 string(int number)
hlipka 0:41a49a73580c 50 : allocated(0), used(0), array(0)
hlipka 0:41a49a73580c 51 {
hlipka 0:41a49a73580c 52 // store if negative and make positive
hlipka 0:41a49a73580c 53
hlipka 0:41a49a73580c 54 bool negative = false;
hlipka 0:41a49a73580c 55 if (number < 0)
hlipka 0:41a49a73580c 56 {
hlipka 0:41a49a73580c 57 number *= -1;
hlipka 0:41a49a73580c 58 negative = true;
hlipka 0:41a49a73580c 59 }
hlipka 0:41a49a73580c 60
hlipka 0:41a49a73580c 61 // temporary buffer for 16 numbers
hlipka 0:41a49a73580c 62
hlipka 0:41a49a73580c 63 c8 tmpbuf[16];
hlipka 0:41a49a73580c 64 tmpbuf[15] = 0;
hlipka 0:41a49a73580c 65 s32 idx = 15;
hlipka 0:41a49a73580c 66
hlipka 0:41a49a73580c 67 // special case '0'
hlipka 0:41a49a73580c 68
hlipka 0:41a49a73580c 69 if (!number)
hlipka 0:41a49a73580c 70 {
hlipka 0:41a49a73580c 71 tmpbuf[14] = '0';
hlipka 0:41a49a73580c 72 *this = &tmpbuf[14];
hlipka 0:41a49a73580c 73 return;
hlipka 0:41a49a73580c 74 }
hlipka 0:41a49a73580c 75
hlipka 0:41a49a73580c 76 // add numbers
hlipka 0:41a49a73580c 77
hlipka 0:41a49a73580c 78 while(number && idx)
hlipka 0:41a49a73580c 79 {
hlipka 0:41a49a73580c 80 idx--;
hlipka 0:41a49a73580c 81 tmpbuf[idx] = (c8)('0' + (number % 10));
hlipka 0:41a49a73580c 82 number = number / 10;
hlipka 0:41a49a73580c 83 }
hlipka 0:41a49a73580c 84
hlipka 0:41a49a73580c 85 // add sign
hlipka 0:41a49a73580c 86
hlipka 0:41a49a73580c 87 if (negative)
hlipka 0:41a49a73580c 88 {
hlipka 0:41a49a73580c 89 idx--;
hlipka 0:41a49a73580c 90 tmpbuf[idx] = '-';
hlipka 0:41a49a73580c 91 }
hlipka 0:41a49a73580c 92
hlipka 0:41a49a73580c 93 *this = &tmpbuf[idx];
hlipka 0:41a49a73580c 94 }
hlipka 0:41a49a73580c 95
hlipka 0:41a49a73580c 96
hlipka 0:41a49a73580c 97
hlipka 0:41a49a73580c 98 //! Constructor for copying a string from a pointer with a given lenght
hlipka 0:41a49a73580c 99 template <class B>
hlipka 0:41a49a73580c 100 string(const B* c, s32 lenght)
hlipka 0:41a49a73580c 101 : allocated(0), used(0), array(0)
hlipka 0:41a49a73580c 102 {
hlipka 0:41a49a73580c 103 if (!c)
hlipka 0:41a49a73580c 104 return;
hlipka 0:41a49a73580c 105
hlipka 0:41a49a73580c 106 allocated = used = lenght+1;
hlipka 0:41a49a73580c 107 array = new T[used];
hlipka 0:41a49a73580c 108
hlipka 0:41a49a73580c 109 for (s32 l = 0; l<lenght; ++l)
hlipka 0:41a49a73580c 110 array[l] = (T)c[l];
hlipka 0:41a49a73580c 111
hlipka 0:41a49a73580c 112 array[lenght] = 0;
hlipka 0:41a49a73580c 113 }
hlipka 0:41a49a73580c 114
hlipka 0:41a49a73580c 115
hlipka 0:41a49a73580c 116
hlipka 0:41a49a73580c 117 //! Constructor for unicode and ascii strings
hlipka 0:41a49a73580c 118 template <class B>
hlipka 0:41a49a73580c 119 string(const B* c)
hlipka 0:41a49a73580c 120 : allocated(0), used(0), array(0)
hlipka 0:41a49a73580c 121 {
hlipka 0:41a49a73580c 122 *this = c;
hlipka 0:41a49a73580c 123 }
hlipka 0:41a49a73580c 124
hlipka 0:41a49a73580c 125
hlipka 0:41a49a73580c 126
hlipka 0:41a49a73580c 127 //! destructor
hlipka 0:41a49a73580c 128 ~string()
hlipka 0:41a49a73580c 129 {
hlipka 0:41a49a73580c 130 delete [] array;
hlipka 0:41a49a73580c 131 }
hlipka 0:41a49a73580c 132
hlipka 0:41a49a73580c 133
hlipka 0:41a49a73580c 134
hlipka 0:41a49a73580c 135 //! Assignment operator
hlipka 0:41a49a73580c 136 string<T>& operator=(const string<T>& other)
hlipka 0:41a49a73580c 137 {
hlipka 0:41a49a73580c 138 if (this == &other)
hlipka 0:41a49a73580c 139 return *this;
hlipka 0:41a49a73580c 140
hlipka 0:41a49a73580c 141 delete [] array;
hlipka 0:41a49a73580c 142 allocated = used = other.size()+1;
hlipka 0:41a49a73580c 143 array = new T[used];
hlipka 0:41a49a73580c 144
hlipka 0:41a49a73580c 145 const T* p = other.c_str();
hlipka 0:41a49a73580c 146 for (s32 i=0; i<used; ++i, ++p)
hlipka 0:41a49a73580c 147 array[i] = *p;
hlipka 0:41a49a73580c 148
hlipka 0:41a49a73580c 149 return *this;
hlipka 0:41a49a73580c 150 }
hlipka 0:41a49a73580c 151
hlipka 0:41a49a73580c 152
hlipka 0:41a49a73580c 153
hlipka 0:41a49a73580c 154 //! Assignment operator for strings, ascii and unicode
hlipka 0:41a49a73580c 155 template <class B>
hlipka 0:41a49a73580c 156 string<T>& operator=(const B* c)
hlipka 0:41a49a73580c 157 {
hlipka 0:41a49a73580c 158 if (!c)
hlipka 0:41a49a73580c 159 {
hlipka 0:41a49a73580c 160 if (!array)
hlipka 0:41a49a73580c 161 {
hlipka 0:41a49a73580c 162 array = new T[1];
hlipka 0:41a49a73580c 163 allocated = 1;
hlipka 0:41a49a73580c 164 used = 1;
hlipka 0:41a49a73580c 165 }
hlipka 0:41a49a73580c 166 array[0] = 0x0;
hlipka 0:41a49a73580c 167 return *this;
hlipka 0:41a49a73580c 168 }
hlipka 0:41a49a73580c 169
hlipka 0:41a49a73580c 170 if ((void*)c == (void*)array)
hlipka 0:41a49a73580c 171 return *this;
hlipka 0:41a49a73580c 172
hlipka 0:41a49a73580c 173 s32 len = 0;
hlipka 0:41a49a73580c 174 const B* p = c;
hlipka 0:41a49a73580c 175 while(*p)
hlipka 0:41a49a73580c 176 {
hlipka 0:41a49a73580c 177 ++len;
hlipka 0:41a49a73580c 178 ++p;
hlipka 0:41a49a73580c 179 }
hlipka 0:41a49a73580c 180
hlipka 0:41a49a73580c 181 // we'll take the old string for a while, because the new string could be
hlipka 0:41a49a73580c 182 // a part of the current string.
hlipka 0:41a49a73580c 183 T* oldArray = array;
hlipka 0:41a49a73580c 184
hlipka 0:41a49a73580c 185 allocated = used = len+1;
hlipka 0:41a49a73580c 186 array = new T[used];
hlipka 0:41a49a73580c 187
hlipka 0:41a49a73580c 188 for (s32 l = 0; l<len+1; ++l)
hlipka 0:41a49a73580c 189 array[l] = (T)c[l];
hlipka 0:41a49a73580c 190
hlipka 0:41a49a73580c 191 delete [] oldArray;
hlipka 0:41a49a73580c 192 return *this;
hlipka 0:41a49a73580c 193 }
hlipka 0:41a49a73580c 194
hlipka 0:41a49a73580c 195 //! Add operator for other strings
hlipka 0:41a49a73580c 196 string<T> operator+(const string<T>& other)
hlipka 0:41a49a73580c 197 {
hlipka 0:41a49a73580c 198 string<T> str(*this);
hlipka 0:41a49a73580c 199 str.append(other);
hlipka 0:41a49a73580c 200
hlipka 0:41a49a73580c 201 return str;
hlipka 0:41a49a73580c 202 }
hlipka 0:41a49a73580c 203
hlipka 0:41a49a73580c 204 //! Add operator for strings, ascii and unicode
hlipka 0:41a49a73580c 205 template <class B>
hlipka 0:41a49a73580c 206 string<T> operator+(const B* c)
hlipka 0:41a49a73580c 207 {
hlipka 0:41a49a73580c 208 string<T> str(*this);
hlipka 0:41a49a73580c 209 str.append(c);
hlipka 0:41a49a73580c 210
hlipka 0:41a49a73580c 211 return str;
hlipka 0:41a49a73580c 212 }
hlipka 0:41a49a73580c 213
hlipka 0:41a49a73580c 214
hlipka 0:41a49a73580c 215
hlipka 0:41a49a73580c 216 //! Direct access operator
hlipka 0:41a49a73580c 217 T& operator [](const s32 index) const
hlipka 0:41a49a73580c 218 {
hlipka 0:41a49a73580c 219 _IRR_DEBUG_BREAK_IF(index>=used) // bad index
hlipka 0:41a49a73580c 220
hlipka 0:41a49a73580c 221 return array[index];
hlipka 0:41a49a73580c 222 }
hlipka 0:41a49a73580c 223
hlipka 0:41a49a73580c 224
hlipka 0:41a49a73580c 225 //! Comparison operator
hlipka 0:41a49a73580c 226 bool operator ==(const T* str) const
hlipka 0:41a49a73580c 227 {
hlipka 0:41a49a73580c 228 int i;
hlipka 0:41a49a73580c 229 for(i=0; array[i] && str[i]; ++i)
hlipka 0:41a49a73580c 230 if (array[i] != str[i])
hlipka 0:41a49a73580c 231 return false;
hlipka 0:41a49a73580c 232
hlipka 0:41a49a73580c 233 return !array[i] && !str[i];
hlipka 0:41a49a73580c 234 }
hlipka 0:41a49a73580c 235
hlipka 0:41a49a73580c 236
hlipka 0:41a49a73580c 237
hlipka 0:41a49a73580c 238 //! Comparison operator
hlipka 0:41a49a73580c 239 bool operator ==(const string<T>& other) const
hlipka 0:41a49a73580c 240 {
hlipka 0:41a49a73580c 241 for(s32 i=0; array[i] && other.array[i]; ++i)
hlipka 0:41a49a73580c 242 if (array[i] != other.array[i])
hlipka 0:41a49a73580c 243 return false;
hlipka 0:41a49a73580c 244
hlipka 0:41a49a73580c 245 return used == other.used;
hlipka 0:41a49a73580c 246 }
hlipka 0:41a49a73580c 247
hlipka 0:41a49a73580c 248
hlipka 0:41a49a73580c 249
hlipka 0:41a49a73580c 250 //! Is smaller operator
hlipka 0:41a49a73580c 251 bool operator <(const string<T>& other) const
hlipka 0:41a49a73580c 252 {
hlipka 0:41a49a73580c 253 for(s32 i=0; array[i] && other.array[i]; ++i)
hlipka 0:41a49a73580c 254 if (array[i] != other.array[i])
hlipka 0:41a49a73580c 255 return (array[i] < other.array[i]);
hlipka 0:41a49a73580c 256
hlipka 0:41a49a73580c 257 return used < other.used;
hlipka 0:41a49a73580c 258 }
hlipka 0:41a49a73580c 259
hlipka 0:41a49a73580c 260
hlipka 0:41a49a73580c 261
hlipka 0:41a49a73580c 262 //! Equals not operator
hlipka 0:41a49a73580c 263 bool operator !=(const string<T>& other) const
hlipka 0:41a49a73580c 264 {
hlipka 0:41a49a73580c 265 return !(*this == other);
hlipka 0:41a49a73580c 266 }
hlipka 0:41a49a73580c 267
hlipka 0:41a49a73580c 268
hlipka 0:41a49a73580c 269
hlipka 0:41a49a73580c 270 //! Returns length of string
hlipka 0:41a49a73580c 271 /** \return Returns length of the string in characters. */
hlipka 0:41a49a73580c 272 s32 size() const
hlipka 0:41a49a73580c 273 {
hlipka 0:41a49a73580c 274 return used-1;
hlipka 0:41a49a73580c 275 }
hlipka 0:41a49a73580c 276
hlipka 0:41a49a73580c 277
hlipka 0:41a49a73580c 278
hlipka 0:41a49a73580c 279 //! Returns character string
hlipka 0:41a49a73580c 280 /** \return Returns pointer to C-style zero terminated string. */
hlipka 0:41a49a73580c 281 const T* c_str() const
hlipka 0:41a49a73580c 282 {
hlipka 0:41a49a73580c 283 return array;
hlipka 0:41a49a73580c 284 }
hlipka 0:41a49a73580c 285
hlipka 0:41a49a73580c 286
hlipka 0:41a49a73580c 287
hlipka 0:41a49a73580c 288 //! Makes the string lower case.
hlipka 0:41a49a73580c 289 void make_lower()
hlipka 0:41a49a73580c 290 {
hlipka 0:41a49a73580c 291 const T A = (T)'A';
hlipka 0:41a49a73580c 292 const T Z = (T)'Z';
hlipka 0:41a49a73580c 293 const T diff = (T)'a' - A;
hlipka 0:41a49a73580c 294
hlipka 0:41a49a73580c 295 for (s32 i=0; i<used; ++i)
hlipka 0:41a49a73580c 296 {
hlipka 0:41a49a73580c 297 if (array[i]>=A && array[i]<=Z)
hlipka 0:41a49a73580c 298 array[i] += diff;
hlipka 0:41a49a73580c 299 }
hlipka 0:41a49a73580c 300 }
hlipka 0:41a49a73580c 301
hlipka 0:41a49a73580c 302
hlipka 0:41a49a73580c 303
hlipka 0:41a49a73580c 304 //! Makes the string upper case.
hlipka 0:41a49a73580c 305 void make_upper()
hlipka 0:41a49a73580c 306 {
hlipka 0:41a49a73580c 307 const T a = (T)'a';
hlipka 0:41a49a73580c 308 const T z = (T)'z';
hlipka 0:41a49a73580c 309 const T diff = (T)'A' - a;
hlipka 0:41a49a73580c 310
hlipka 0:41a49a73580c 311 for (s32 i=0; i<used; ++i)
hlipka 0:41a49a73580c 312 {
hlipka 0:41a49a73580c 313 if (array[i]>=a && array[i]<=z)
hlipka 0:41a49a73580c 314 array[i] += diff;
hlipka 0:41a49a73580c 315 }
hlipka 0:41a49a73580c 316 }
hlipka 0:41a49a73580c 317
hlipka 0:41a49a73580c 318
hlipka 0:41a49a73580c 319
hlipka 0:41a49a73580c 320 //! Compares the string ignoring case.
hlipka 0:41a49a73580c 321 /** \param other: Other string to compare.
hlipka 0:41a49a73580c 322 \return Returns true if the string are equal ignoring case. */
hlipka 0:41a49a73580c 323 bool equals_ignore_case(const string<T>& other) const
hlipka 0:41a49a73580c 324 {
hlipka 0:41a49a73580c 325 for(s32 i=0; array[i] && other[i]; ++i)
hlipka 0:41a49a73580c 326 if (toLower(array[i]) != toLower(other[i]))
hlipka 0:41a49a73580c 327 return false;
hlipka 0:41a49a73580c 328
hlipka 0:41a49a73580c 329 return used == other.used;
hlipka 0:41a49a73580c 330 }
hlipka 0:41a49a73580c 331
hlipka 0:41a49a73580c 332
hlipka 0:41a49a73580c 333 //! compares the first n characters of the strings
hlipka 0:41a49a73580c 334 bool equalsn(const string<T>& other, int len)
hlipka 0:41a49a73580c 335 {
hlipka 0:41a49a73580c 336 int i;
hlipka 0:41a49a73580c 337 for(i=0; array[i] && other[i] && i < len; ++i)
hlipka 0:41a49a73580c 338 if (array[i] != other[i])
hlipka 0:41a49a73580c 339 return false;
hlipka 0:41a49a73580c 340
hlipka 0:41a49a73580c 341 // if one (or both) of the strings was smaller then they
hlipka 0:41a49a73580c 342 // are only equal if they have the same lenght
hlipka 0:41a49a73580c 343 return (i == len) || (used == other.used);
hlipka 0:41a49a73580c 344 }
hlipka 0:41a49a73580c 345
hlipka 0:41a49a73580c 346
hlipka 0:41a49a73580c 347 //! compares the first n characters of the strings
hlipka 0:41a49a73580c 348 bool equalsn(const T* str, int len)
hlipka 0:41a49a73580c 349 {
hlipka 0:41a49a73580c 350 int i;
hlipka 0:41a49a73580c 351 for(i=0; array[i] && str[i] && i < len; ++i)
hlipka 0:41a49a73580c 352 if (array[i] != str[i])
hlipka 0:41a49a73580c 353 return false;
hlipka 0:41a49a73580c 354
hlipka 0:41a49a73580c 355 // if one (or both) of the strings was smaller then they
hlipka 0:41a49a73580c 356 // are only equal if they have the same lenght
hlipka 0:41a49a73580c 357 return (i == len) || (array[i] == 0 && str[i] == 0);
hlipka 0:41a49a73580c 358 }
hlipka 0:41a49a73580c 359
hlipka 0:41a49a73580c 360
hlipka 0:41a49a73580c 361 //! Appends a character to this string
hlipka 0:41a49a73580c 362 /** \param character: Character to append. */
hlipka 0:41a49a73580c 363 void append(T character)
hlipka 0:41a49a73580c 364 {
hlipka 0:41a49a73580c 365 if (used + 1 > allocated)
hlipka 0:41a49a73580c 366 reallocate((s32)used + 1);
hlipka 0:41a49a73580c 367
hlipka 0:41a49a73580c 368 used += 1;
hlipka 0:41a49a73580c 369
hlipka 0:41a49a73580c 370 array[used-2] = character;
hlipka 0:41a49a73580c 371 array[used-1] = 0;
hlipka 0:41a49a73580c 372 }
hlipka 0:41a49a73580c 373
hlipka 0:41a49a73580c 374 //! Appends a string to this string
hlipka 0:41a49a73580c 375 /** \param other: String to append. */
hlipka 0:41a49a73580c 376 void append(const string<T>& other)
hlipka 0:41a49a73580c 377 {
hlipka 0:41a49a73580c 378 --used;
hlipka 0:41a49a73580c 379
hlipka 0:41a49a73580c 380 s32 len = other.size();
hlipka 0:41a49a73580c 381
hlipka 0:41a49a73580c 382 if (used + len + 1 > allocated)
hlipka 0:41a49a73580c 383 reallocate((s32)used + (s32)len + 1);
hlipka 0:41a49a73580c 384
hlipka 0:41a49a73580c 385 for (s32 l=0; l<len+1; ++l)
hlipka 0:41a49a73580c 386 array[l+used] = other[l];
hlipka 0:41a49a73580c 387
hlipka 0:41a49a73580c 388 used = used + len + 1;
hlipka 0:41a49a73580c 389 }
hlipka 0:41a49a73580c 390
hlipka 0:41a49a73580c 391
hlipka 0:41a49a73580c 392 //! Appends a string of the length l to this string.
hlipka 0:41a49a73580c 393 /** \param other: other String to append to this string.
hlipka 0:41a49a73580c 394 \param length: How much characters of the other string to add to this one. */
hlipka 0:41a49a73580c 395 void append(const string<T>& other, s32 length)
hlipka 0:41a49a73580c 396 {
hlipka 0:41a49a73580c 397 s32 len = other.size();
hlipka 0:41a49a73580c 398
hlipka 0:41a49a73580c 399 if (len < length)
hlipka 0:41a49a73580c 400 {
hlipka 0:41a49a73580c 401 append(other);
hlipka 0:41a49a73580c 402 return;
hlipka 0:41a49a73580c 403 }
hlipka 0:41a49a73580c 404
hlipka 0:41a49a73580c 405 len = length;
hlipka 0:41a49a73580c 406 --used;
hlipka 0:41a49a73580c 407
hlipka 0:41a49a73580c 408 if (used + len > allocated)
hlipka 0:41a49a73580c 409 reallocate((s32)used + (s32)len);
hlipka 0:41a49a73580c 410
hlipka 0:41a49a73580c 411 for (s32 l=0; l<len; ++l)
hlipka 0:41a49a73580c 412 array[l+used] = other[l];
hlipka 0:41a49a73580c 413
hlipka 0:41a49a73580c 414 used = used + len;
hlipka 0:41a49a73580c 415 }
hlipka 0:41a49a73580c 416
hlipka 0:41a49a73580c 417
hlipka 0:41a49a73580c 418 //! Reserves some memory.
hlipka 0:41a49a73580c 419 /** \param count: Amount of characters to reserve. */
hlipka 0:41a49a73580c 420 void reserve(s32 count)
hlipka 0:41a49a73580c 421 {
hlipka 0:41a49a73580c 422 if (count < allocated)
hlipka 0:41a49a73580c 423 return;
hlipka 0:41a49a73580c 424
hlipka 0:41a49a73580c 425 reallocate(count);
hlipka 0:41a49a73580c 426 }
hlipka 0:41a49a73580c 427
hlipka 0:41a49a73580c 428
hlipka 0:41a49a73580c 429 //! finds first occurrence of character in string
hlipka 0:41a49a73580c 430 /** \param c: Character to search for.
hlipka 0:41a49a73580c 431 \return Returns position where the character has been found,
hlipka 0:41a49a73580c 432 or -1 if not found. */
hlipka 0:41a49a73580c 433 s32 findFirst(T c) const
hlipka 0:41a49a73580c 434 {
hlipka 0:41a49a73580c 435 for (s32 i=0; i<used; ++i)
hlipka 0:41a49a73580c 436 if (array[i] == c)
hlipka 0:41a49a73580c 437 return i;
hlipka 0:41a49a73580c 438
hlipka 0:41a49a73580c 439 return -1;
hlipka 0:41a49a73580c 440 }
hlipka 0:41a49a73580c 441
hlipka 0:41a49a73580c 442 //! finds first occurrence of a character of a list in string
hlipka 0:41a49a73580c 443 /** \param c: List of strings to find. For example if the method
hlipka 0:41a49a73580c 444 should find the first occurance of 'a' or 'b', this parameter should be "ab".
hlipka 0:41a49a73580c 445 \param count: Amount of characters in the list. Ususally,
hlipka 0:41a49a73580c 446 this should be strlen(ofParameter1)
hlipka 0:41a49a73580c 447 \return Returns position where one of the character has been found,
hlipka 0:41a49a73580c 448 or -1 if not found. */
hlipka 0:41a49a73580c 449 s32 findFirstChar(T* c, int count) const
hlipka 0:41a49a73580c 450 {
hlipka 0:41a49a73580c 451 for (s32 i=0; i<used; ++i)
hlipka 0:41a49a73580c 452 for (int j=0; j<count; ++j)
hlipka 0:41a49a73580c 453 if (array[i] == c[j])
hlipka 0:41a49a73580c 454 return i;
hlipka 0:41a49a73580c 455
hlipka 0:41a49a73580c 456 return -1;
hlipka 0:41a49a73580c 457 }
hlipka 0:41a49a73580c 458
hlipka 0:41a49a73580c 459
hlipka 0:41a49a73580c 460 //! Finds first position of a character not in a given list.
hlipka 0:41a49a73580c 461 /** \param c: List of characters not to find. For example if the method
hlipka 0:41a49a73580c 462 should find the first occurance of a character not 'a' or 'b', this parameter should be "ab".
hlipka 0:41a49a73580c 463 \param count: Amount of characters in the list. Ususally,
hlipka 0:41a49a73580c 464 this should be strlen(ofParameter1)
hlipka 0:41a49a73580c 465 \return Returns position where the character has been found,
hlipka 0:41a49a73580c 466 or -1 if not found. */
hlipka 0:41a49a73580c 467 template <class B>
hlipka 0:41a49a73580c 468 s32 findFirstCharNotInList(B* c, int count) const
hlipka 0:41a49a73580c 469 {
hlipka 0:41a49a73580c 470 for (int i=0; i<used; ++i)
hlipka 0:41a49a73580c 471 {
hlipka 0:41a49a73580c 472 int j;
hlipka 0:41a49a73580c 473 for (j=0; j<count; ++j)
hlipka 0:41a49a73580c 474 if (array[i] == c[j])
hlipka 0:41a49a73580c 475 break;
hlipka 0:41a49a73580c 476
hlipka 0:41a49a73580c 477 if (j==count)
hlipka 0:41a49a73580c 478 return i;
hlipka 0:41a49a73580c 479 }
hlipka 0:41a49a73580c 480
hlipka 0:41a49a73580c 481 return -1;
hlipka 0:41a49a73580c 482 }
hlipka 0:41a49a73580c 483
hlipka 0:41a49a73580c 484 //! Finds last position of a character not in a given list.
hlipka 0:41a49a73580c 485 /** \param c: List of characters not to find. For example if the method
hlipka 0:41a49a73580c 486 should find the first occurance of a character not 'a' or 'b', this parameter should be "ab".
hlipka 0:41a49a73580c 487 \param count: Amount of characters in the list. Ususally,
hlipka 0:41a49a73580c 488 this should be strlen(ofParameter1)
hlipka 0:41a49a73580c 489 \return Returns position where the character has been found,
hlipka 0:41a49a73580c 490 or -1 if not found. */
hlipka 0:41a49a73580c 491 template <class B>
hlipka 0:41a49a73580c 492 s32 findLastCharNotInList(B* c, int count) const
hlipka 0:41a49a73580c 493 {
hlipka 0:41a49a73580c 494 for (int i=used-2; i>=0; --i)
hlipka 0:41a49a73580c 495 {
hlipka 0:41a49a73580c 496 int j;
hlipka 0:41a49a73580c 497 for (j=0; j<count; ++j)
hlipka 0:41a49a73580c 498 if (array[i] == c[j])
hlipka 0:41a49a73580c 499 break;
hlipka 0:41a49a73580c 500
hlipka 0:41a49a73580c 501 if (j==count)
hlipka 0:41a49a73580c 502 return i;
hlipka 0:41a49a73580c 503 }
hlipka 0:41a49a73580c 504
hlipka 0:41a49a73580c 505 return -1;
hlipka 0:41a49a73580c 506 }
hlipka 0:41a49a73580c 507
hlipka 0:41a49a73580c 508 //! finds next occurrence of character in string
hlipka 0:41a49a73580c 509 /** \param c: Character to search for.
hlipka 0:41a49a73580c 510 \param startPos: Position in string to start searching.
hlipka 0:41a49a73580c 511 \return Returns position where the character has been found,
hlipka 0:41a49a73580c 512 or -1 if not found. */
hlipka 0:41a49a73580c 513 s32 findNext(T c, s32 startPos) const
hlipka 0:41a49a73580c 514 {
hlipka 0:41a49a73580c 515 for (s32 i=startPos; i<used; ++i)
hlipka 0:41a49a73580c 516 if (array[i] == c)
hlipka 0:41a49a73580c 517 return i;
hlipka 0:41a49a73580c 518
hlipka 0:41a49a73580c 519 return -1;
hlipka 0:41a49a73580c 520 }
hlipka 0:41a49a73580c 521
hlipka 0:41a49a73580c 522
hlipka 0:41a49a73580c 523 //! finds last occurrence of character in string
hlipka 0:41a49a73580c 524 //! \param c: Character to search for.
hlipka 0:41a49a73580c 525 //! \return Returns position where the character has been found,
hlipka 0:41a49a73580c 526 //! or -1 if not found.
hlipka 0:41a49a73580c 527 s32 findLast(T c) const
hlipka 0:41a49a73580c 528 {
hlipka 0:41a49a73580c 529 for (s32 i=used-1; i>=0; --i)
hlipka 0:41a49a73580c 530 if (array[i] == c)
hlipka 0:41a49a73580c 531 return i;
hlipka 0:41a49a73580c 532
hlipka 0:41a49a73580c 533 return -1;
hlipka 0:41a49a73580c 534 }
hlipka 0:41a49a73580c 535
hlipka 0:41a49a73580c 536
hlipka 0:41a49a73580c 537 //! Returns a substring
hlipka 0:41a49a73580c 538 //! \param begin: Start of substring.
hlipka 0:41a49a73580c 539 //! \param length: Length of substring.
hlipka 0:41a49a73580c 540 string<T> subString(s32 begin, s32 length)
hlipka 0:41a49a73580c 541 {
hlipka 0:41a49a73580c 542 if (length <= 0)
hlipka 0:41a49a73580c 543 return string<T>("");
hlipka 0:41a49a73580c 544
hlipka 0:41a49a73580c 545 string<T> o;
hlipka 0:41a49a73580c 546 o.reserve(length+1);
hlipka 0:41a49a73580c 547
hlipka 0:41a49a73580c 548 for (s32 i=0; i<length; ++i)
hlipka 0:41a49a73580c 549 o.array[i] = array[i+begin];
hlipka 0:41a49a73580c 550
hlipka 0:41a49a73580c 551 o.array[length] = 0;
hlipka 0:41a49a73580c 552 o.used = o.allocated;
hlipka 0:41a49a73580c 553
hlipka 0:41a49a73580c 554 return o;
hlipka 0:41a49a73580c 555 }
hlipka 0:41a49a73580c 556
hlipka 0:41a49a73580c 557
hlipka 0:41a49a73580c 558 void operator += (T c)
hlipka 0:41a49a73580c 559 {
hlipka 0:41a49a73580c 560 append(c);
hlipka 0:41a49a73580c 561 }
hlipka 0:41a49a73580c 562
hlipka 0:41a49a73580c 563 void operator += (const string<T>& other)
hlipka 0:41a49a73580c 564 {
hlipka 0:41a49a73580c 565 append(other);
hlipka 0:41a49a73580c 566 }
hlipka 0:41a49a73580c 567
hlipka 0:41a49a73580c 568 void operator += (int i)
hlipka 0:41a49a73580c 569 {
hlipka 0:41a49a73580c 570 append(string<T>(i));
hlipka 0:41a49a73580c 571 }
hlipka 0:41a49a73580c 572
hlipka 0:41a49a73580c 573 //! replaces all characters of a special type with another one
hlipka 0:41a49a73580c 574 void replace(T toReplace, T replaceWith)
hlipka 0:41a49a73580c 575 {
hlipka 0:41a49a73580c 576 for (s32 i=0; i<used; ++i)
hlipka 0:41a49a73580c 577 if (array[i] == toReplace)
hlipka 0:41a49a73580c 578 array[i] = replaceWith;
hlipka 0:41a49a73580c 579 }
hlipka 0:41a49a73580c 580
hlipka 0:41a49a73580c 581 //! trims the string.
hlipka 0:41a49a73580c 582 /** Removes whitespace from begin and end of the string. */
hlipka 0:41a49a73580c 583 void trim()
hlipka 0:41a49a73580c 584 {
hlipka 0:41a49a73580c 585 const char whitespace[] = " \t\n";
hlipka 0:41a49a73580c 586 const int whitespacecount = 3;
hlipka 0:41a49a73580c 587
hlipka 0:41a49a73580c 588 // find start and end of real string without whitespace
hlipka 0:41a49a73580c 589 int begin = findFirstCharNotInList(whitespace, whitespacecount);
hlipka 0:41a49a73580c 590 if (begin == -1)
hlipka 0:41a49a73580c 591 return;
hlipka 0:41a49a73580c 592
hlipka 0:41a49a73580c 593 int end = findLastCharNotInList(whitespace, whitespacecount);
hlipka 0:41a49a73580c 594 if (end == -1)
hlipka 0:41a49a73580c 595 return;
hlipka 0:41a49a73580c 596
hlipka 0:41a49a73580c 597 *this = subString(begin, (end +1) - begin);
hlipka 0:41a49a73580c 598 }
hlipka 0:41a49a73580c 599
hlipka 0:41a49a73580c 600
hlipka 0:41a49a73580c 601 //! Erases a character from the string. May be slow, because all elements
hlipka 0:41a49a73580c 602 //! following after the erased element have to be copied.
hlipka 0:41a49a73580c 603 //! \param index: Index of element to be erased.
hlipka 0:41a49a73580c 604 void erase(int index)
hlipka 0:41a49a73580c 605 {
hlipka 0:41a49a73580c 606 _IRR_DEBUG_BREAK_IF(index>=used || index<0) // access violation
hlipka 0:41a49a73580c 607
hlipka 0:41a49a73580c 608 for (int i=index+1; i<used; ++i)
hlipka 0:41a49a73580c 609 array[i-1] = array[i];
hlipka 0:41a49a73580c 610
hlipka 0:41a49a73580c 611 --used;
hlipka 0:41a49a73580c 612 }
hlipka 0:41a49a73580c 613
hlipka 0:41a49a73580c 614
hlipka 0:41a49a73580c 615
hlipka 0:41a49a73580c 616 private:
hlipka 0:41a49a73580c 617
hlipka 0:41a49a73580c 618 //! Returns a character converted to lower case
hlipka 0:41a49a73580c 619 T toLower(const T& t) const
hlipka 0:41a49a73580c 620 {
hlipka 0:41a49a73580c 621 if (t>=(T)'A' && t<=(T)'Z')
hlipka 0:41a49a73580c 622 return t + ((T)'a' - (T)'A');
hlipka 0:41a49a73580c 623 else
hlipka 0:41a49a73580c 624 return t;
hlipka 0:41a49a73580c 625 }
hlipka 0:41a49a73580c 626
hlipka 0:41a49a73580c 627 //! Reallocate the array, make it bigger or smaler
hlipka 0:41a49a73580c 628 void reallocate(s32 new_size)
hlipka 0:41a49a73580c 629 {
hlipka 0:41a49a73580c 630 T* old_array = array;
hlipka 0:41a49a73580c 631
hlipka 0:41a49a73580c 632 array = new T[new_size];
hlipka 0:41a49a73580c 633 allocated = new_size;
hlipka 0:41a49a73580c 634
hlipka 0:41a49a73580c 635 s32 amount = used < new_size ? used : new_size;
hlipka 0:41a49a73580c 636 for (s32 i=0; i<amount; ++i)
hlipka 0:41a49a73580c 637 array[i] = old_array[i];
hlipka 0:41a49a73580c 638
hlipka 0:41a49a73580c 639 if (allocated < used)
hlipka 0:41a49a73580c 640 used = allocated;
hlipka 0:41a49a73580c 641
hlipka 0:41a49a73580c 642 delete [] old_array;
hlipka 0:41a49a73580c 643 }
hlipka 0:41a49a73580c 644
hlipka 0:41a49a73580c 645
hlipka 0:41a49a73580c 646 //--- member variables
hlipka 0:41a49a73580c 647
hlipka 0:41a49a73580c 648 T* array;
hlipka 0:41a49a73580c 649 s32 allocated;
hlipka 0:41a49a73580c 650 s32 used;
hlipka 0:41a49a73580c 651 };
hlipka 0:41a49a73580c 652
hlipka 0:41a49a73580c 653
hlipka 0:41a49a73580c 654 //! Typedef for character strings
hlipka 0:41a49a73580c 655 typedef string<irr::c8> stringc;
hlipka 0:41a49a73580c 656
hlipka 0:41a49a73580c 657 //! Typedef for wide character strings
hlipka 0:41a49a73580c 658 typedef string<wchar_t> stringw;
hlipka 0:41a49a73580c 659
hlipka 0:41a49a73580c 660 } // end namespace core
hlipka 0:41a49a73580c 661 } // end namespace irr
hlipka 0:41a49a73580c 662
hlipka 0:41a49a73580c 663 #endif