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