aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/irrlicht-1.8/include/irrString.h
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/irrlicht-1.8/include/irrString.h')
-rw-r--r--libraries/irrlicht-1.8/include/irrString.h2736
1 files changed, 1368 insertions, 1368 deletions
diff --git a/libraries/irrlicht-1.8/include/irrString.h b/libraries/irrlicht-1.8/include/irrString.h
index 43557cd..752ea1a 100644
--- a/libraries/irrlicht-1.8/include/irrString.h
+++ b/libraries/irrlicht-1.8/include/irrString.h
@@ -1,1368 +1,1368 @@
1// Copyright (C) 2002-2012 Nikolaus Gebhardt 1// Copyright (C) 2002-2012 Nikolaus Gebhardt
2// This file is part of the "Irrlicht Engine" and the "irrXML" project. 2// This file is part of the "Irrlicht Engine" and the "irrXML" project.
3// For conditions of distribution and use, see copyright notice in irrlicht.h and irrXML.h 3// For conditions of distribution and use, see copyright notice in irrlicht.h and irrXML.h
4 4
5#ifndef __IRR_STRING_H_INCLUDED__ 5#ifndef __IRR_STRING_H_INCLUDED__
6#define __IRR_STRING_H_INCLUDED__ 6#define __IRR_STRING_H_INCLUDED__
7 7
8#include "irrTypes.h" 8#include "irrTypes.h"
9#include "irrAllocator.h" 9#include "irrAllocator.h"
10#include "irrMath.h" 10#include "irrMath.h"
11#include <stdio.h> 11#include <stdio.h>
12#include <string.h> 12#include <string.h>
13#include <stdlib.h> 13#include <stdlib.h>
14 14
15namespace irr 15namespace irr
16{ 16{
17namespace core 17namespace core
18{ 18{
19 19
20//! Very simple string class with some useful features. 20//! Very simple string class with some useful features.
21/** string<c8> and string<wchar_t> both accept Unicode AND ASCII/Latin-1, 21/** string<c8> and string<wchar_t> both accept Unicode AND ASCII/Latin-1,
22so you can assign Unicode to string<c8> and ASCII/Latin-1 to string<wchar_t> 22so you can assign Unicode to string<c8> and ASCII/Latin-1 to string<wchar_t>
23(and the other way round) if you want to. 23(and the other way round) if you want to.
24 24
25However, note that the conversation between both is not done using any encoding. 25However, note that the conversation between both is not done using any encoding.
26This means that c8 strings are treated as ASCII/Latin-1, not UTF-8, and 26This means that c8 strings are treated as ASCII/Latin-1, not UTF-8, and
27are simply expanded to the equivalent wchar_t, while Unicode/wchar_t 27are simply expanded to the equivalent wchar_t, while Unicode/wchar_t
28characters are truncated to 8-bit ASCII/Latin-1 characters, discarding all 28characters are truncated to 8-bit ASCII/Latin-1 characters, discarding all
29other information in the wchar_t. 29other information in the wchar_t.
30*/ 30*/
31 31
32enum eLocaleID 32enum eLocaleID
33{ 33{
34 IRR_LOCALE_ANSI = 0, 34 IRR_LOCALE_ANSI = 0,
35 IRR_LOCALE_GERMAN = 1 35 IRR_LOCALE_GERMAN = 1
36}; 36};
37 37
38static eLocaleID locale_current = IRR_LOCALE_ANSI; 38static eLocaleID locale_current = IRR_LOCALE_ANSI;
39static inline void locale_set ( eLocaleID id ) 39static inline void locale_set ( eLocaleID id )
40{ 40{
41 locale_current = id; 41 locale_current = id;
42} 42}
43 43
44//! Returns a character converted to lower case 44//! Returns a character converted to lower case
45static inline u32 locale_lower ( u32 x ) 45static inline u32 locale_lower ( u32 x )
46{ 46{
47 switch ( locale_current ) 47 switch ( locale_current )
48 { 48 {
49 case IRR_LOCALE_GERMAN: 49 case IRR_LOCALE_GERMAN:
50 case IRR_LOCALE_ANSI: 50 case IRR_LOCALE_ANSI:
51 break; 51 break;
52 } 52 }
53 // ansi 53 // ansi
54 return x >= 'A' && x <= 'Z' ? x + 0x20 : x; 54 return x >= 'A' && x <= 'Z' ? x + 0x20 : x;
55} 55}
56 56
57//! Returns a character converted to upper case 57//! Returns a character converted to upper case
58static inline u32 locale_upper ( u32 x ) 58static inline u32 locale_upper ( u32 x )
59{ 59{
60 switch ( locale_current ) 60 switch ( locale_current )
61 { 61 {
62 case IRR_LOCALE_GERMAN: 62 case IRR_LOCALE_GERMAN:
63 case IRR_LOCALE_ANSI: 63 case IRR_LOCALE_ANSI:
64 break; 64 break;
65 } 65 }
66 66
67 // ansi 67 // ansi
68 return x >= 'a' && x <= 'z' ? x + ( 'A' - 'a' ) : x; 68 return x >= 'a' && x <= 'z' ? x + ( 'A' - 'a' ) : x;
69} 69}
70 70
71 71
72template <typename T, typename TAlloc = irrAllocator<T> > 72template <typename T, typename TAlloc = irrAllocator<T> >
73class string 73class string
74{ 74{
75public: 75public:
76 76
77 typedef T char_type; 77 typedef T char_type;
78 78
79 //! Default constructor 79 //! Default constructor
80 string() 80 string()
81 : array(0), allocated(1), used(1) 81 : array(0), allocated(1), used(1)
82 { 82 {
83 array = allocator.allocate(1); // new T[1]; 83 array = allocator.allocate(1); // new T[1];
84 array[0] = 0; 84 array[0] = 0;
85 } 85 }
86 86
87 87
88 //! Constructor 88 //! Constructor
89 string(const string<T,TAlloc>& other) 89 string(const string<T,TAlloc>& other)
90 : array(0), allocated(0), used(0) 90 : array(0), allocated(0), used(0)
91 { 91 {
92 *this = other; 92 *this = other;
93 } 93 }
94 94
95 //! Constructor from other string types 95 //! Constructor from other string types
96 template <class B, class A> 96 template <class B, class A>
97 string(const string<B, A>& other) 97 string(const string<B, A>& other)
98 : array(0), allocated(0), used(0) 98 : array(0), allocated(0), used(0)
99 { 99 {
100 *this = other; 100 *this = other;
101 } 101 }
102 102
103 103
104 //! Constructs a string from a float 104 //! Constructs a string from a float
105 explicit string(const double number) 105 explicit string(const double number)
106 : array(0), allocated(0), used(0) 106 : array(0), allocated(0), used(0)
107 { 107 {
108 c8 tmpbuf[255]; 108 c8 tmpbuf[255];
109 snprintf(tmpbuf, 255, "%0.6f", number); 109 snprintf(tmpbuf, 255, "%0.6f", number);
110 *this = tmpbuf; 110 *this = tmpbuf;
111 } 111 }
112 112
113 113
114 //! Constructs a string from an int 114 //! Constructs a string from an int
115 explicit string(int number) 115 explicit string(int number)
116 : array(0), allocated(0), used(0) 116 : array(0), allocated(0), used(0)
117 { 117 {
118 // store if negative and make positive 118 // store if negative and make positive
119 119
120 bool negative = false; 120 bool negative = false;
121 if (number < 0) 121 if (number < 0)
122 { 122 {
123 number *= -1; 123 number *= -1;
124 negative = true; 124 negative = true;
125 } 125 }
126 126
127 // temporary buffer for 16 numbers 127 // temporary buffer for 16 numbers
128 128
129 c8 tmpbuf[16]={0}; 129 c8 tmpbuf[16]={0};
130 u32 idx = 15; 130 u32 idx = 15;
131 131
132 // special case '0' 132 // special case '0'
133 133
134 if (!number) 134 if (!number)
135 { 135 {
136 tmpbuf[14] = '0'; 136 tmpbuf[14] = '0';
137 *this = &tmpbuf[14]; 137 *this = &tmpbuf[14];
138 return; 138 return;
139 } 139 }
140 140
141 // add numbers 141 // add numbers
142 142
143 while(number && idx) 143 while(number && idx)
144 { 144 {
145 --idx; 145 --idx;
146 tmpbuf[idx] = (c8)('0' + (number % 10)); 146 tmpbuf[idx] = (c8)('0' + (number % 10));
147 number /= 10; 147 number /= 10;
148 } 148 }
149 149
150 // add sign 150 // add sign
151 151
152 if (negative) 152 if (negative)
153 { 153 {
154 --idx; 154 --idx;
155 tmpbuf[idx] = '-'; 155 tmpbuf[idx] = '-';
156 } 156 }
157 157
158 *this = &tmpbuf[idx]; 158 *this = &tmpbuf[idx];
159 } 159 }
160 160
161 161
162 //! Constructs a string from an unsigned int 162 //! Constructs a string from an unsigned int
163 explicit string(unsigned int number) 163 explicit string(unsigned int number)
164 : array(0), allocated(0), used(0) 164 : array(0), allocated(0), used(0)
165 { 165 {
166 // temporary buffer for 16 numbers 166 // temporary buffer for 16 numbers
167 167
168 c8 tmpbuf[16]={0}; 168 c8 tmpbuf[16]={0};
169 u32 idx = 15; 169 u32 idx = 15;
170 170
171 // special case '0' 171 // special case '0'
172 172
173 if (!number) 173 if (!number)
174 { 174 {
175 tmpbuf[14] = '0'; 175 tmpbuf[14] = '0';
176 *this = &tmpbuf[14]; 176 *this = &tmpbuf[14];
177 return; 177 return;
178 } 178 }
179 179
180 // add numbers 180 // add numbers
181 181
182 while(number && idx) 182 while(number && idx)
183 { 183 {
184 --idx; 184 --idx;
185 tmpbuf[idx] = (c8)('0' + (number % 10)); 185 tmpbuf[idx] = (c8)('0' + (number % 10));
186 number /= 10; 186 number /= 10;
187 } 187 }
188 188
189 *this = &tmpbuf[idx]; 189 *this = &tmpbuf[idx];
190 } 190 }
191 191
192 192
193 //! Constructs a string from a long 193 //! Constructs a string from a long
194 explicit string(long number) 194 explicit string(long number)
195 : array(0), allocated(0), used(0) 195 : array(0), allocated(0), used(0)
196 { 196 {
197 // store if negative and make positive 197 // store if negative and make positive
198 198
199 bool negative = false; 199 bool negative = false;
200 if (number < 0) 200 if (number < 0)
201 { 201 {
202 number *= -1; 202 number *= -1;
203 negative = true; 203 negative = true;
204 } 204 }
205 205
206 // temporary buffer for 16 numbers 206 // temporary buffer for 16 numbers
207 207
208 c8 tmpbuf[16]={0}; 208 c8 tmpbuf[16]={0};
209 u32 idx = 15; 209 u32 idx = 15;
210 210
211 // special case '0' 211 // special case '0'
212 212
213 if (!number) 213 if (!number)
214 { 214 {
215 tmpbuf[14] = '0'; 215 tmpbuf[14] = '0';
216 *this = &tmpbuf[14]; 216 *this = &tmpbuf[14];
217 return; 217 return;
218 } 218 }
219 219
220 // add numbers 220 // add numbers
221 221
222 while(number && idx) 222 while(number && idx)
223 { 223 {
224 --idx; 224 --idx;
225 tmpbuf[idx] = (c8)('0' + (number % 10)); 225 tmpbuf[idx] = (c8)('0' + (number % 10));
226 number /= 10; 226 number /= 10;
227 } 227 }
228 228
229 // add sign 229 // add sign
230 230
231 if (negative) 231 if (negative)
232 { 232 {
233 --idx; 233 --idx;
234 tmpbuf[idx] = '-'; 234 tmpbuf[idx] = '-';
235 } 235 }
236 236
237 *this = &tmpbuf[idx]; 237 *this = &tmpbuf[idx];
238 } 238 }
239 239
240 240
241 //! Constructs a string from an unsigned long 241 //! Constructs a string from an unsigned long
242 explicit string(unsigned long number) 242 explicit string(unsigned long number)
243 : array(0), allocated(0), used(0) 243 : array(0), allocated(0), used(0)
244 { 244 {
245 // temporary buffer for 16 numbers 245 // temporary buffer for 16 numbers
246 246
247 c8 tmpbuf[16]={0}; 247 c8 tmpbuf[16]={0};
248 u32 idx = 15; 248 u32 idx = 15;
249 249
250 // special case '0' 250 // special case '0'
251 251
252 if (!number) 252 if (!number)
253 { 253 {
254 tmpbuf[14] = '0'; 254 tmpbuf[14] = '0';
255 *this = &tmpbuf[14]; 255 *this = &tmpbuf[14];
256 return; 256 return;
257 } 257 }
258 258
259 // add numbers 259 // add numbers
260 260
261 while(number && idx) 261 while(number && idx)
262 { 262 {
263 --idx; 263 --idx;
264 tmpbuf[idx] = (c8)('0' + (number % 10)); 264 tmpbuf[idx] = (c8)('0' + (number % 10));
265 number /= 10; 265 number /= 10;
266 } 266 }
267 267
268 *this = &tmpbuf[idx]; 268 *this = &tmpbuf[idx];
269 } 269 }
270 270
271 271
272 //! Constructor for copying a string from a pointer with a given length 272 //! Constructor for copying a string from a pointer with a given length
273 template <class B> 273 template <class B>
274 string(const B* const c, u32 length) 274 string(const B* const c, u32 length)
275 : array(0), allocated(0), used(0) 275 : array(0), allocated(0), used(0)
276 { 276 {
277 if (!c) 277 if (!c)
278 { 278 {
279 // correctly init the string to an empty one 279 // correctly init the string to an empty one
280 *this=""; 280 *this="";
281 return; 281 return;
282 } 282 }
283 283
284 allocated = used = length+1; 284 allocated = used = length+1;
285 array = allocator.allocate(used); // new T[used]; 285 array = allocator.allocate(used); // new T[used];
286 286
287 for (u32 l = 0; l<length; ++l) 287 for (u32 l = 0; l<length; ++l)
288 array[l] = (T)c[l]; 288 array[l] = (T)c[l];
289 289
290 array[length] = 0; 290 array[length] = 0;
291 } 291 }
292 292
293 293
294 //! Constructor for unicode and ascii strings 294 //! Constructor for unicode and ascii strings
295 template <class B> 295 template <class B>
296 string(const B* const c) 296 string(const B* const c)
297 : array(0), allocated(0), used(0) 297 : array(0), allocated(0), used(0)
298 { 298 {
299 *this = c; 299 *this = c;
300 } 300 }
301 301
302 302
303 //! Destructor 303 //! Destructor
304 ~string() 304 ~string()
305 { 305 {
306 allocator.deallocate(array); // delete [] array; 306 allocator.deallocate(array); // delete [] array;
307 } 307 }
308 308
309 309
310 //! Assignment operator 310 //! Assignment operator
311 string<T,TAlloc>& operator=(const string<T,TAlloc>& other) 311 string<T,TAlloc>& operator=(const string<T,TAlloc>& other)
312 { 312 {
313 if (this == &other) 313 if (this == &other)
314 return *this; 314 return *this;
315 315
316 used = other.size()+1; 316 used = other.size()+1;
317 if (used>allocated) 317 if (used>allocated)
318 { 318 {
319 allocator.deallocate(array); // delete [] array; 319 allocator.deallocate(array); // delete [] array;
320 allocated = used; 320 allocated = used;
321 array = allocator.allocate(used); //new T[used]; 321 array = allocator.allocate(used); //new T[used];
322 } 322 }
323 323
324 const T* p = other.c_str(); 324 const T* p = other.c_str();
325 for (u32 i=0; i<used; ++i, ++p) 325 for (u32 i=0; i<used; ++i, ++p)
326 array[i] = *p; 326 array[i] = *p;
327 327
328 return *this; 328 return *this;
329 } 329 }
330 330
331 //! Assignment operator for other string types 331 //! Assignment operator for other string types
332 template <class B, class A> 332 template <class B, class A>
333 string<T,TAlloc>& operator=(const string<B,A>& other) 333 string<T,TAlloc>& operator=(const string<B,A>& other)
334 { 334 {
335 *this = other.c_str(); 335 *this = other.c_str();
336 return *this; 336 return *this;
337 } 337 }
338 338
339 339
340 //! Assignment operator for strings, ascii and unicode 340 //! Assignment operator for strings, ascii and unicode
341 template <class B> 341 template <class B>
342 string<T,TAlloc>& operator=(const B* const c) 342 string<T,TAlloc>& operator=(const B* const c)
343 { 343 {
344 if (!c) 344 if (!c)
345 { 345 {
346 if (!array) 346 if (!array)
347 { 347 {
348 array = allocator.allocate(1); //new T[1]; 348 array = allocator.allocate(1); //new T[1];
349 allocated = 1; 349 allocated = 1;
350 } 350 }
351 used = 1; 351 used = 1;
352 array[0] = 0x0; 352 array[0] = 0x0;
353 return *this; 353 return *this;
354 } 354 }
355 355
356 if ((void*)c == (void*)array) 356 if ((void*)c == (void*)array)
357 return *this; 357 return *this;
358 358
359 u32 len = 0; 359 u32 len = 0;
360 const B* p = c; 360 const B* p = c;
361 do 361 do
362 { 362 {
363 ++len; 363 ++len;
364 } while(*p++); 364 } while(*p++);
365 365
366 // we'll keep the old string for a while, because the new 366 // we'll keep the old string for a while, because the new
367 // string could be a part of the current string. 367 // string could be a part of the current string.
368 T* oldArray = array; 368 T* oldArray = array;
369 369
370 used = len; 370 used = len;
371 if (used>allocated) 371 if (used>allocated)
372 { 372 {
373 allocated = used; 373 allocated = used;
374 array = allocator.allocate(used); //new T[used]; 374 array = allocator.allocate(used); //new T[used];
375 } 375 }
376 376
377 for (u32 l = 0; l<len; ++l) 377 for (u32 l = 0; l<len; ++l)
378 array[l] = (T)c[l]; 378 array[l] = (T)c[l];
379 379
380 if (oldArray != array) 380 if (oldArray != array)
381 allocator.deallocate(oldArray); // delete [] oldArray; 381 allocator.deallocate(oldArray); // delete [] oldArray;
382 382
383 return *this; 383 return *this;
384 } 384 }
385 385
386 386
387 //! Append operator for other strings 387 //! Append operator for other strings
388 string<T,TAlloc> operator+(const string<T,TAlloc>& other) const 388 string<T,TAlloc> operator+(const string<T,TAlloc>& other) const
389 { 389 {
390 string<T,TAlloc> str(*this); 390 string<T,TAlloc> str(*this);
391 str.append(other); 391 str.append(other);
392 392
393 return str; 393 return str;
394 } 394 }
395 395
396 396
397 //! Append operator for strings, ascii and unicode 397 //! Append operator for strings, ascii and unicode
398 template <class B> 398 template <class B>
399 string<T,TAlloc> operator+(const B* const c) const 399 string<T,TAlloc> operator+(const B* const c) const
400 { 400 {
401 string<T,TAlloc> str(*this); 401 string<T,TAlloc> str(*this);
402 str.append(c); 402 str.append(c);
403 403
404 return str; 404 return str;
405 } 405 }
406 406
407 407
408 //! Direct access operator 408 //! Direct access operator
409 T& operator [](const u32 index) 409 T& operator [](const u32 index)
410 { 410 {
411 _IRR_DEBUG_BREAK_IF(index>=used) // bad index 411 _IRR_DEBUG_BREAK_IF(index>=used) // bad index
412 return array[index]; 412 return array[index];
413 } 413 }
414 414
415 415
416 //! Direct access operator 416 //! Direct access operator
417 const T& operator [](const u32 index) const 417 const T& operator [](const u32 index) const
418 { 418 {
419 _IRR_DEBUG_BREAK_IF(index>=used) // bad index 419 _IRR_DEBUG_BREAK_IF(index>=used) // bad index
420 return array[index]; 420 return array[index];
421 } 421 }
422 422
423 423
424 //! Equality operator 424 //! Equality operator
425 bool operator==(const T* const str) const 425 bool operator==(const T* const str) const
426 { 426 {
427 if (!str) 427 if (!str)
428 return false; 428 return false;
429 429
430 u32 i; 430 u32 i;
431 for (i=0; array[i] && str[i]; ++i) 431 for (i=0; array[i] && str[i]; ++i)
432 if (array[i] != str[i]) 432 if (array[i] != str[i])
433 return false; 433 return false;
434 434
435 return (!array[i] && !str[i]); 435 return (!array[i] && !str[i]);
436 } 436 }
437 437
438 438
439 //! Equality operator 439 //! Equality operator
440 bool operator==(const string<T,TAlloc>& other) const 440 bool operator==(const string<T,TAlloc>& other) const
441 { 441 {
442 for (u32 i=0; array[i] && other.array[i]; ++i) 442 for (u32 i=0; array[i] && other.array[i]; ++i)
443 if (array[i] != other.array[i]) 443 if (array[i] != other.array[i])
444 return false; 444 return false;
445 445
446 return used == other.used; 446 return used == other.used;
447 } 447 }
448 448
449 449
450 //! Is smaller comparator 450 //! Is smaller comparator
451 bool operator<(const string<T,TAlloc>& other) const 451 bool operator<(const string<T,TAlloc>& other) const
452 { 452 {
453 for (u32 i=0; array[i] && other.array[i]; ++i) 453 for (u32 i=0; array[i] && other.array[i]; ++i)
454 { 454 {
455 const s32 diff = array[i] - other.array[i]; 455 const s32 diff = array[i] - other.array[i];
456 if (diff) 456 if (diff)
457 return (diff < 0); 457 return (diff < 0);
458 } 458 }
459 459
460 return (used < other.used); 460 return (used < other.used);
461 } 461 }
462 462
463 463
464 //! Inequality operator 464 //! Inequality operator
465 bool operator!=(const T* const str) const 465 bool operator!=(const T* const str) const
466 { 466 {
467 return !(*this == str); 467 return !(*this == str);
468 } 468 }
469 469
470 470
471 //! Inequality operator 471 //! Inequality operator
472 bool operator!=(const string<T,TAlloc>& other) const 472 bool operator!=(const string<T,TAlloc>& other) const
473 { 473 {
474 return !(*this == other); 474 return !(*this == other);
475 } 475 }
476 476
477 477
478 //! Returns length of the string's content 478 //! Returns length of the string's content
479 /** \return Length of the string's content in characters, excluding 479 /** \return Length of the string's content in characters, excluding
480 the trailing NUL. */ 480 the trailing NUL. */
481 u32 size() const 481 u32 size() const
482 { 482 {
483 return used-1; 483 return used-1;
484 } 484 }
485 485
486 //! Informs if the string is empty or not. 486 //! Informs if the string is empty or not.
487 //! \return True if the string is empty, false if not. 487 //! \return True if the string is empty, false if not.
488 bool empty() const 488 bool empty() const
489 { 489 {
490 return (size() == 0); 490 return (size() == 0);
491 } 491 }
492 492
493 //! Returns character string 493 //! Returns character string
494 /** \return pointer to C-style NUL terminated string. */ 494 /** \return pointer to C-style NUL terminated string. */
495 const T* c_str() const 495 const T* c_str() const
496 { 496 {
497 return array; 497 return array;
498 } 498 }
499 499
500 500
501 //! Makes the string lower case. 501 //! Makes the string lower case.
502 string<T,TAlloc>& make_lower() 502 string<T,TAlloc>& make_lower()
503 { 503 {
504 for (u32 i=0; array[i]; ++i) 504 for (u32 i=0; array[i]; ++i)
505 array[i] = locale_lower ( array[i] ); 505 array[i] = locale_lower ( array[i] );
506 return *this; 506 return *this;
507 } 507 }
508 508
509 509
510 //! Makes the string upper case. 510 //! Makes the string upper case.
511 string<T,TAlloc>& make_upper() 511 string<T,TAlloc>& make_upper()
512 { 512 {
513 for (u32 i=0; array[i]; ++i) 513 for (u32 i=0; array[i]; ++i)
514 array[i] = locale_upper ( array[i] ); 514 array[i] = locale_upper ( array[i] );
515 return *this; 515 return *this;
516 } 516 }
517 517
518 518
519 //! Compares the strings ignoring case. 519 //! Compares the strings ignoring case.
520 /** \param other: Other string to compare. 520 /** \param other: Other string to compare.
521 \return True if the strings are equal ignoring case. */ 521 \return True if the strings are equal ignoring case. */
522 bool equals_ignore_case(const string<T,TAlloc>& other) const 522 bool equals_ignore_case(const string<T,TAlloc>& other) const
523 { 523 {
524 for(u32 i=0; array[i] && other[i]; ++i) 524 for(u32 i=0; array[i] && other[i]; ++i)
525 if (locale_lower( array[i]) != locale_lower(other[i])) 525 if (locale_lower( array[i]) != locale_lower(other[i]))
526 return false; 526 return false;
527 527
528 return used == other.used; 528 return used == other.used;
529 } 529 }
530 530
531 //! Compares the strings ignoring case. 531 //! Compares the strings ignoring case.
532 /** \param other: Other string to compare. 532 /** \param other: Other string to compare.
533 \param sourcePos: where to start to compare in the string 533 \param sourcePos: where to start to compare in the string
534 \return True if the strings are equal ignoring case. */ 534 \return True if the strings are equal ignoring case. */
535 bool equals_substring_ignore_case(const string<T,TAlloc>&other, const s32 sourcePos = 0 ) const 535 bool equals_substring_ignore_case(const string<T,TAlloc>&other, const s32 sourcePos = 0 ) const
536 { 536 {
537 if ( (u32) sourcePos >= used ) 537 if ( (u32) sourcePos >= used )
538 return false; 538 return false;
539 539
540 u32 i; 540 u32 i;
541 for( i=0; array[sourcePos + i] && other[i]; ++i) 541 for( i=0; array[sourcePos + i] && other[i]; ++i)
542 if (locale_lower( array[sourcePos + i]) != locale_lower(other[i])) 542 if (locale_lower( array[sourcePos + i]) != locale_lower(other[i]))
543 return false; 543 return false;
544 544
545 return array[sourcePos + i] == 0 && other[i] == 0; 545 return array[sourcePos + i] == 0 && other[i] == 0;
546 } 546 }
547 547
548 548
549 //! Compares the strings ignoring case. 549 //! Compares the strings ignoring case.
550 /** \param other: Other string to compare. 550 /** \param other: Other string to compare.
551 \return True if this string is smaller ignoring case. */ 551 \return True if this string is smaller ignoring case. */
552 bool lower_ignore_case(const string<T,TAlloc>& other) const 552 bool lower_ignore_case(const string<T,TAlloc>& other) const
553 { 553 {
554 for(u32 i=0; array[i] && other.array[i]; ++i) 554 for(u32 i=0; array[i] && other.array[i]; ++i)
555 { 555 {
556 s32 diff = (s32) locale_lower ( array[i] ) - (s32) locale_lower ( other.array[i] ); 556 s32 diff = (s32) locale_lower ( array[i] ) - (s32) locale_lower ( other.array[i] );
557 if ( diff ) 557 if ( diff )
558 return diff < 0; 558 return diff < 0;
559 } 559 }
560 560
561 return used < other.used; 561 return used < other.used;
562 } 562 }
563 563
564 564
565 //! compares the first n characters of the strings 565 //! compares the first n characters of the strings
566 /** \param other Other string to compare. 566 /** \param other Other string to compare.
567 \param n Number of characters to compare 567 \param n Number of characters to compare
568 \return True if the n first characters of both strings are equal. */ 568 \return True if the n first characters of both strings are equal. */
569 bool equalsn(const string<T,TAlloc>& other, u32 n) const 569 bool equalsn(const string<T,TAlloc>& other, u32 n) const
570 { 570 {
571 u32 i; 571 u32 i;
572 for(i=0; array[i] && other[i] && i < n; ++i) 572 for(i=0; array[i] && other[i] && i < n; ++i)
573 if (array[i] != other[i]) 573 if (array[i] != other[i])
574 return false; 574 return false;
575 575
576 // if one (or both) of the strings was smaller then they 576 // if one (or both) of the strings was smaller then they
577 // are only equal if they have the same length 577 // are only equal if they have the same length
578 return (i == n) || (used == other.used); 578 return (i == n) || (used == other.used);
579 } 579 }
580 580
581 581
582 //! compares the first n characters of the strings 582 //! compares the first n characters of the strings
583 /** \param str Other string to compare. 583 /** \param str Other string to compare.
584 \param n Number of characters to compare 584 \param n Number of characters to compare
585 \return True if the n first characters of both strings are equal. */ 585 \return True if the n first characters of both strings are equal. */
586 bool equalsn(const T* const str, u32 n) const 586 bool equalsn(const T* const str, u32 n) const
587 { 587 {
588 if (!str) 588 if (!str)
589 return false; 589 return false;
590 u32 i; 590 u32 i;
591 for(i=0; array[i] && str[i] && i < n; ++i) 591 for(i=0; array[i] && str[i] && i < n; ++i)
592 if (array[i] != str[i]) 592 if (array[i] != str[i])
593 return false; 593 return false;
594 594
595 // if one (or both) of the strings was smaller then they 595 // if one (or both) of the strings was smaller then they
596 // are only equal if they have the same length 596 // are only equal if they have the same length
597 return (i == n) || (array[i] == 0 && str[i] == 0); 597 return (i == n) || (array[i] == 0 && str[i] == 0);
598 } 598 }
599 599
600 600
601 //! Appends a character to this string 601 //! Appends a character to this string
602 /** \param character: Character to append. */ 602 /** \param character: Character to append. */
603 string<T,TAlloc>& append(T character) 603 string<T,TAlloc>& append(T character)
604 { 604 {
605 if (used + 1 > allocated) 605 if (used + 1 > allocated)
606 reallocate(used + 1); 606 reallocate(used + 1);
607 607
608 ++used; 608 ++used;
609 609
610 array[used-2] = character; 610 array[used-2] = character;
611 array[used-1] = 0; 611 array[used-1] = 0;
612 612
613 return *this; 613 return *this;
614 } 614 }
615 615
616 616
617 //! Appends a char string to this string 617 //! Appends a char string to this string
618 /** \param other: Char string to append. */ 618 /** \param other: Char string to append. */
619 /** \param length: The length of the string to append. */ 619 /** \param length: The length of the string to append. */
620 string<T,TAlloc>& append(const T* const other, u32 length=0xffffffff) 620 string<T,TAlloc>& append(const T* const other, u32 length=0xffffffff)
621 { 621 {
622 if (!other) 622 if (!other)
623 return *this; 623 return *this;
624 624
625 u32 len = 0; 625 u32 len = 0;
626 const T* p = other; 626 const T* p = other;
627 while(*p) 627 while(*p)
628 { 628 {
629 ++len; 629 ++len;
630 ++p; 630 ++p;
631 } 631 }
632 if (len > length) 632 if (len > length)
633 len = length; 633 len = length;
634 634
635 if (used + len > allocated) 635 if (used + len > allocated)
636 reallocate(used + len); 636 reallocate(used + len);
637 637
638 --used; 638 --used;
639 ++len; 639 ++len;
640 640
641 for (u32 l=0; l<len; ++l) 641 for (u32 l=0; l<len; ++l)
642 array[l+used] = *(other+l); 642 array[l+used] = *(other+l);
643 643
644 used += len; 644 used += len;
645 645
646 return *this; 646 return *this;
647 } 647 }
648 648
649 649
650 //! Appends a string to this string 650 //! Appends a string to this string
651 /** \param other: String to append. */ 651 /** \param other: String to append. */
652 string<T,TAlloc>& append(const string<T,TAlloc>& other) 652 string<T,TAlloc>& append(const string<T,TAlloc>& other)
653 { 653 {
654 if (other.size() == 0) 654 if (other.size() == 0)
655 return *this; 655 return *this;
656 656
657 --used; 657 --used;
658 u32 len = other.size()+1; 658 u32 len = other.size()+1;
659 659
660 if (used + len > allocated) 660 if (used + len > allocated)
661 reallocate(used + len); 661 reallocate(used + len);
662 662
663 for (u32 l=0; l<len; ++l) 663 for (u32 l=0; l<len; ++l)
664 array[used+l] = other[l]; 664 array[used+l] = other[l];
665 665
666 used += len; 666 used += len;
667 667
668 return *this; 668 return *this;
669 } 669 }
670 670
671 671
672 //! Appends a string of the length l to this string. 672 //! Appends a string of the length l to this string.
673 /** \param other: other String to append to this string. 673 /** \param other: other String to append to this string.
674 \param length: How much characters of the other string to add to this one. */ 674 \param length: How much characters of the other string to add to this one. */
675 string<T,TAlloc>& append(const string<T,TAlloc>& other, u32 length) 675 string<T,TAlloc>& append(const string<T,TAlloc>& other, u32 length)
676 { 676 {
677 if (other.size() == 0) 677 if (other.size() == 0)
678 return *this; 678 return *this;
679 679
680 if (other.size() < length) 680 if (other.size() < length)
681 { 681 {
682 append(other); 682 append(other);
683 return *this; 683 return *this;
684 } 684 }
685 685
686 if (used + length > allocated) 686 if (used + length > allocated)
687 reallocate(used + length); 687 reallocate(used + length);
688 688
689 --used; 689 --used;
690 690
691 for (u32 l=0; l<length; ++l) 691 for (u32 l=0; l<length; ++l)
692 array[l+used] = other[l]; 692 array[l+used] = other[l];
693 used += length; 693 used += length;
694 694
695 // ensure proper termination 695 // ensure proper termination
696 array[used]=0; 696 array[used]=0;
697 ++used; 697 ++used;
698 698
699 return *this; 699 return *this;
700 } 700 }
701 701
702 702
703 //! Reserves some memory. 703 //! Reserves some memory.
704 /** \param count: Amount of characters to reserve. */ 704 /** \param count: Amount of characters to reserve. */
705 void reserve(u32 count) 705 void reserve(u32 count)
706 { 706 {
707 if (count < allocated) 707 if (count < allocated)
708 return; 708 return;
709 709
710 reallocate(count); 710 reallocate(count);
711 } 711 }
712 712
713 713
714 //! finds first occurrence of character in string 714 //! finds first occurrence of character in string
715 /** \param c: Character to search for. 715 /** \param c: Character to search for.
716 \return Position where the character has been found, 716 \return Position where the character has been found,
717 or -1 if not found. */ 717 or -1 if not found. */
718 s32 findFirst(T c) const 718 s32 findFirst(T c) const
719 { 719 {
720 for (u32 i=0; i<used-1; ++i) 720 for (u32 i=0; i<used-1; ++i)
721 if (array[i] == c) 721 if (array[i] == c)
722 return i; 722 return i;
723 723
724 return -1; 724 return -1;
725 } 725 }
726 726
727 //! finds first occurrence of a character of a list in string 727 //! finds first occurrence of a character of a list in string
728 /** \param c: List of characters to find. For example if the method 728 /** \param c: List of characters to find. For example if the method
729 should find the first occurrence of 'a' or 'b', this parameter should be "ab". 729 should find the first occurrence of 'a' or 'b', this parameter should be "ab".
730 \param count: Amount of characters in the list. Usually, 730 \param count: Amount of characters in the list. Usually,
731 this should be strlen(c) 731 this should be strlen(c)
732 \return Position where one of the characters has been found, 732 \return Position where one of the characters has been found,
733 or -1 if not found. */ 733 or -1 if not found. */
734 s32 findFirstChar(const T* const c, u32 count=1) const 734 s32 findFirstChar(const T* const c, u32 count=1) const
735 { 735 {
736 if (!c || !count) 736 if (!c || !count)
737 return -1; 737 return -1;
738 738
739 for (u32 i=0; i<used-1; ++i) 739 for (u32 i=0; i<used-1; ++i)
740 for (u32 j=0; j<count; ++j) 740 for (u32 j=0; j<count; ++j)
741 if (array[i] == c[j]) 741 if (array[i] == c[j])
742 return i; 742 return i;
743 743
744 return -1; 744 return -1;
745 } 745 }
746 746
747 747
748 //! Finds first position of a character not in a given list. 748 //! Finds first position of a character not in a given list.
749 /** \param c: List of characters not to find. For example if the method 749 /** \param c: List of characters not to find. For example if the method
750 should find the first occurrence of a character not 'a' or 'b', this parameter should be "ab". 750 should find the first occurrence of a character not 'a' or 'b', this parameter should be "ab".
751 \param count: Amount of characters in the list. Usually, 751 \param count: Amount of characters in the list. Usually,
752 this should be strlen(c) 752 this should be strlen(c)
753 \return Position where the character has been found, 753 \return Position where the character has been found,
754 or -1 if not found. */ 754 or -1 if not found. */
755 template <class B> 755 template <class B>
756 s32 findFirstCharNotInList(const B* const c, u32 count=1) const 756 s32 findFirstCharNotInList(const B* const c, u32 count=1) const
757 { 757 {
758 if (!c || !count) 758 if (!c || !count)
759 return -1; 759 return -1;
760 760
761 for (u32 i=0; i<used-1; ++i) 761 for (u32 i=0; i<used-1; ++i)
762 { 762 {
763 u32 j; 763 u32 j;
764 for (j=0; j<count; ++j) 764 for (j=0; j<count; ++j)
765 if (array[i] == c[j]) 765 if (array[i] == c[j])
766 break; 766 break;
767 767
768 if (j==count) 768 if (j==count)
769 return i; 769 return i;
770 } 770 }
771 771
772 return -1; 772 return -1;
773 } 773 }
774 774
775 //! Finds last position of a character not in a given list. 775 //! Finds last position of a character not in a given list.
776 /** \param c: List of characters not to find. For example if the method 776 /** \param c: List of characters not to find. For example if the method
777 should find the first occurrence of a character not 'a' or 'b', this parameter should be "ab". 777 should find the first occurrence of a character not 'a' or 'b', this parameter should be "ab".
778 \param count: Amount of characters in the list. Usually, 778 \param count: Amount of characters in the list. Usually,
779 this should be strlen(c) 779 this should be strlen(c)
780 \return Position where the character has been found, 780 \return Position where the character has been found,
781 or -1 if not found. */ 781 or -1 if not found. */
782 template <class B> 782 template <class B>
783 s32 findLastCharNotInList(const B* const c, u32 count=1) const 783 s32 findLastCharNotInList(const B* const c, u32 count=1) const
784 { 784 {
785 if (!c || !count) 785 if (!c || !count)
786 return -1; 786 return -1;
787 787
788 for (s32 i=(s32)(used-2); i>=0; --i) 788 for (s32 i=(s32)(used-2); i>=0; --i)
789 { 789 {
790 u32 j; 790 u32 j;
791 for (j=0; j<count; ++j) 791 for (j=0; j<count; ++j)
792 if (array[i] == c[j]) 792 if (array[i] == c[j])
793 break; 793 break;
794 794
795 if (j==count) 795 if (j==count)
796 return i; 796 return i;
797 } 797 }
798 798
799 return -1; 799 return -1;
800 } 800 }
801 801
802 //! finds next occurrence of character in string 802 //! finds next occurrence of character in string
803 /** \param c: Character to search for. 803 /** \param c: Character to search for.
804 \param startPos: Position in string to start searching. 804 \param startPos: Position in string to start searching.
805 \return Position where the character has been found, 805 \return Position where the character has been found,
806 or -1 if not found. */ 806 or -1 if not found. */
807 s32 findNext(T c, u32 startPos) const 807 s32 findNext(T c, u32 startPos) const
808 { 808 {
809 for (u32 i=startPos; i<used-1; ++i) 809 for (u32 i=startPos; i<used-1; ++i)
810 if (array[i] == c) 810 if (array[i] == c)
811 return i; 811 return i;
812 812
813 return -1; 813 return -1;
814 } 814 }
815 815
816 816
817 //! finds last occurrence of character in string 817 //! finds last occurrence of character in string
818 /** \param c: Character to search for. 818 /** \param c: Character to search for.
819 \param start: start to search reverse ( default = -1, on end ) 819 \param start: start to search reverse ( default = -1, on end )
820 \return Position where the character has been found, 820 \return Position where the character has been found,
821 or -1 if not found. */ 821 or -1 if not found. */
822 s32 findLast(T c, s32 start = -1) const 822 s32 findLast(T c, s32 start = -1) const
823 { 823 {
824 start = core::clamp ( start < 0 ? (s32)(used) - 2 : start, 0, (s32)(used) - 2 ); 824 start = core::clamp ( start < 0 ? (s32)(used) - 2 : start, 0, (s32)(used) - 2 );
825 for (s32 i=start; i>=0; --i) 825 for (s32 i=start; i>=0; --i)
826 if (array[i] == c) 826 if (array[i] == c)
827 return i; 827 return i;
828 828
829 return -1; 829 return -1;
830 } 830 }
831 831
832 //! finds last occurrence of a character of a list in string 832 //! finds last occurrence of a character of a list in string
833 /** \param c: List of strings to find. For example if the method 833 /** \param c: List of strings to find. For example if the method
834 should find the last occurrence of 'a' or 'b', this parameter should be "ab". 834 should find the last occurrence of 'a' or 'b', this parameter should be "ab".
835 \param count: Amount of characters in the list. Usually, 835 \param count: Amount of characters in the list. Usually,
836 this should be strlen(c) 836 this should be strlen(c)
837 \return Position where one of the characters has been found, 837 \return Position where one of the characters has been found,
838 or -1 if not found. */ 838 or -1 if not found. */
839 s32 findLastChar(const T* const c, u32 count=1) const 839 s32 findLastChar(const T* const c, u32 count=1) const
840 { 840 {
841 if (!c || !count) 841 if (!c || !count)
842 return -1; 842 return -1;
843 843
844 for (s32 i=(s32)used-2; i>=0; --i) 844 for (s32 i=(s32)used-2; i>=0; --i)
845 for (u32 j=0; j<count; ++j) 845 for (u32 j=0; j<count; ++j)
846 if (array[i] == c[j]) 846 if (array[i] == c[j])
847 return i; 847 return i;
848 848
849 return -1; 849 return -1;
850 } 850 }
851 851
852 852
853 //! finds another string in this string 853 //! finds another string in this string
854 /** \param str: Another string 854 /** \param str: Another string
855 \param start: Start position of the search 855 \param start: Start position of the search
856 \return Positions where the string has been found, 856 \return Positions where the string has been found,
857 or -1 if not found. */ 857 or -1 if not found. */
858 template <class B> 858 template <class B>
859 s32 find(const B* const str, const u32 start = 0) const 859 s32 find(const B* const str, const u32 start = 0) const
860 { 860 {
861 if (str && *str) 861 if (str && *str)
862 { 862 {
863 u32 len = 0; 863 u32 len = 0;
864 864
865 while (str[len]) 865 while (str[len])
866 ++len; 866 ++len;
867 867
868 if (len > used-1) 868 if (len > used-1)
869 return -1; 869 return -1;
870 870
871 for (u32 i=start; i<used-len; ++i) 871 for (u32 i=start; i<used-len; ++i)
872 { 872 {
873 u32 j=0; 873 u32 j=0;
874 874
875 while(str[j] && array[i+j] == str[j]) 875 while(str[j] && array[i+j] == str[j])
876 ++j; 876 ++j;
877 877
878 if (!str[j]) 878 if (!str[j])
879 return i; 879 return i;
880 } 880 }
881 } 881 }
882 882
883 return -1; 883 return -1;
884 } 884 }
885 885
886 886
887 //! Returns a substring 887 //! Returns a substring
888 /** \param begin Start of substring. 888 /** \param begin Start of substring.
889 \param length Length of substring. 889 \param length Length of substring.
890 \param make_lower copy only lower case */ 890 \param make_lower copy only lower case */
891 string<T> subString(u32 begin, s32 length, bool make_lower = false ) const 891 string<T> subString(u32 begin, s32 length, bool make_lower = false ) const
892 { 892 {
893 // if start after string 893 // if start after string
894 // or no proper substring length 894 // or no proper substring length
895 if ((length <= 0) || (begin>=size())) 895 if ((length <= 0) || (begin>=size()))
896 return string<T>(""); 896 return string<T>("");
897 // clamp length to maximal value 897 // clamp length to maximal value
898 if ((length+begin) > size()) 898 if ((length+begin) > size())
899 length = size()-begin; 899 length = size()-begin;
900 900
901 string<T> o; 901 string<T> o;
902 o.reserve(length+1); 902 o.reserve(length+1);
903 903
904 s32 i; 904 s32 i;
905 if ( !make_lower ) 905 if ( !make_lower )
906 { 906 {
907 for (i=0; i<length; ++i) 907 for (i=0; i<length; ++i)
908 o.array[i] = array[i+begin]; 908 o.array[i] = array[i+begin];
909 } 909 }
910 else 910 else
911 { 911 {
912 for (i=0; i<length; ++i) 912 for (i=0; i<length; ++i)
913 o.array[i] = locale_lower ( array[i+begin] ); 913 o.array[i] = locale_lower ( array[i+begin] );
914 } 914 }
915 915
916 o.array[length] = 0; 916 o.array[length] = 0;
917 o.used = length + 1; 917 o.used = length + 1;
918 918
919 return o; 919 return o;
920 } 920 }
921 921
922 922
923 //! Appends a character to this string 923 //! Appends a character to this string
924 /** \param c Character to append. */ 924 /** \param c Character to append. */
925 string<T,TAlloc>& operator += (T c) 925 string<T,TAlloc>& operator += (T c)
926 { 926 {
927 append(c); 927 append(c);
928 return *this; 928 return *this;
929 } 929 }
930 930
931 931
932 //! Appends a char string to this string 932 //! Appends a char string to this string
933 /** \param c Char string to append. */ 933 /** \param c Char string to append. */
934 string<T,TAlloc>& operator += (const T* const c) 934 string<T,TAlloc>& operator += (const T* const c)
935 { 935 {
936 append(c); 936 append(c);
937 return *this; 937 return *this;
938 } 938 }
939 939
940 940
941 //! Appends a string to this string 941 //! Appends a string to this string
942 /** \param other String to append. */ 942 /** \param other String to append. */
943 string<T,TAlloc>& operator += (const string<T,TAlloc>& other) 943 string<T,TAlloc>& operator += (const string<T,TAlloc>& other)
944 { 944 {
945 append(other); 945 append(other);
946 return *this; 946 return *this;
947 } 947 }
948 948
949 949
950 //! Appends a string representation of a number to this string 950 //! Appends a string representation of a number to this string
951 /** \param i Number to append. */ 951 /** \param i Number to append. */
952 string<T,TAlloc>& operator += (const int i) 952 string<T,TAlloc>& operator += (const int i)
953 { 953 {
954 append(string<T,TAlloc>(i)); 954 append(string<T,TAlloc>(i));
955 return *this; 955 return *this;
956 } 956 }
957 957
958 958
959 //! Appends a string representation of a number to this string 959 //! Appends a string representation of a number to this string
960 /** \param i Number to append. */ 960 /** \param i Number to append. */
961 string<T,TAlloc>& operator += (const unsigned int i) 961 string<T,TAlloc>& operator += (const unsigned int i)
962 { 962 {
963 append(string<T,TAlloc>(i)); 963 append(string<T,TAlloc>(i));
964 return *this; 964 return *this;
965 } 965 }
966 966
967 967
968 //! Appends a string representation of a number to this string 968 //! Appends a string representation of a number to this string
969 /** \param i Number to append. */ 969 /** \param i Number to append. */
970 string<T,TAlloc>& operator += (const long i) 970 string<T,TAlloc>& operator += (const long i)
971 { 971 {
972 append(string<T,TAlloc>(i)); 972 append(string<T,TAlloc>(i));
973 return *this; 973 return *this;
974 } 974 }
975 975
976 976
977 //! Appends a string representation of a number to this string 977 //! Appends a string representation of a number to this string
978 /** \param i Number to append. */ 978 /** \param i Number to append. */
979 string<T,TAlloc>& operator += (const unsigned long i) 979 string<T,TAlloc>& operator += (const unsigned long i)
980 { 980 {
981 append(string<T,TAlloc>(i)); 981 append(string<T,TAlloc>(i));
982 return *this; 982 return *this;
983 } 983 }
984 984
985 985
986 //! Appends a string representation of a number to this string 986 //! Appends a string representation of a number to this string
987 /** \param i Number to append. */ 987 /** \param i Number to append. */
988 string<T,TAlloc>& operator += (const double i) 988 string<T,TAlloc>& operator += (const double i)
989 { 989 {
990 append(string<T,TAlloc>(i)); 990 append(string<T,TAlloc>(i));
991 return *this; 991 return *this;
992 } 992 }
993 993
994 994
995 //! Appends a string representation of a number to this string 995 //! Appends a string representation of a number to this string
996 /** \param i Number to append. */ 996 /** \param i Number to append. */
997 string<T,TAlloc>& operator += (const float i) 997 string<T,TAlloc>& operator += (const float i)
998 { 998 {
999 append(string<T,TAlloc>(i)); 999 append(string<T,TAlloc>(i));
1000 return *this; 1000 return *this;
1001 } 1001 }
1002 1002
1003 1003
1004 //! Replaces all characters of a special type with another one 1004 //! Replaces all characters of a special type with another one
1005 /** \param toReplace Character to replace. 1005 /** \param toReplace Character to replace.
1006 \param replaceWith Character replacing the old one. */ 1006 \param replaceWith Character replacing the old one. */
1007 string<T,TAlloc>& replace(T toReplace, T replaceWith) 1007 string<T,TAlloc>& replace(T toReplace, T replaceWith)
1008 { 1008 {
1009 for (u32 i=0; i<used-1; ++i) 1009 for (u32 i=0; i<used-1; ++i)
1010 if (array[i] == toReplace) 1010 if (array[i] == toReplace)
1011 array[i] = replaceWith; 1011 array[i] = replaceWith;
1012 return *this; 1012 return *this;
1013 } 1013 }
1014 1014
1015 1015
1016 //! Replaces all instances of a string with another one. 1016 //! Replaces all instances of a string with another one.
1017 /** \param toReplace The string to replace. 1017 /** \param toReplace The string to replace.
1018 \param replaceWith The string replacing the old one. */ 1018 \param replaceWith The string replacing the old one. */
1019 string<T,TAlloc>& replace(const string<T,TAlloc>& toReplace, const string<T,TAlloc>& replaceWith) 1019 string<T,TAlloc>& replace(const string<T,TAlloc>& toReplace, const string<T,TAlloc>& replaceWith)
1020 { 1020 {
1021 if (toReplace.size() == 0) 1021 if (toReplace.size() == 0)
1022 return *this; 1022 return *this;
1023 1023
1024 const T* other = toReplace.c_str(); 1024 const T* other = toReplace.c_str();
1025 const T* replace = replaceWith.c_str(); 1025 const T* replace = replaceWith.c_str();
1026 const u32 other_size = toReplace.size(); 1026 const u32 other_size = toReplace.size();
1027 const u32 replace_size = replaceWith.size(); 1027 const u32 replace_size = replaceWith.size();
1028 1028
1029 // Determine the delta. The algorithm will change depending on the delta. 1029 // Determine the delta. The algorithm will change depending on the delta.
1030 s32 delta = replace_size - other_size; 1030 s32 delta = replace_size - other_size;
1031 1031
1032 // A character for character replace. The string will not shrink or grow. 1032 // A character for character replace. The string will not shrink or grow.
1033 if (delta == 0) 1033 if (delta == 0)
1034 { 1034 {
1035 s32 pos = 0; 1035 s32 pos = 0;
1036 while ((pos = find(other, pos)) != -1) 1036 while ((pos = find(other, pos)) != -1)
1037 { 1037 {
1038 for (u32 i = 0; i < replace_size; ++i) 1038 for (u32 i = 0; i < replace_size; ++i)
1039 array[pos + i] = replace[i]; 1039 array[pos + i] = replace[i];
1040 ++pos; 1040 ++pos;
1041 } 1041 }
1042 return *this; 1042 return *this;
1043 } 1043 }
1044 1044
1045 // We are going to be removing some characters. The string will shrink. 1045 // We are going to be removing some characters. The string will shrink.
1046 if (delta < 0) 1046 if (delta < 0)
1047 { 1047 {
1048 u32 i = 0; 1048 u32 i = 0;
1049 for (u32 pos = 0; pos < used; ++i, ++pos) 1049 for (u32 pos = 0; pos < used; ++i, ++pos)
1050 { 1050 {
1051 // Is this potentially a match? 1051 // Is this potentially a match?
1052 if (array[pos] == *other) 1052 if (array[pos] == *other)
1053 { 1053 {
1054 // Check to see if we have a match. 1054 // Check to see if we have a match.
1055 u32 j; 1055 u32 j;
1056 for (j = 0; j < other_size; ++j) 1056 for (j = 0; j < other_size; ++j)
1057 { 1057 {
1058 if (array[pos + j] != other[j]) 1058 if (array[pos + j] != other[j])
1059 break; 1059 break;
1060 } 1060 }
1061 1061
1062 // If we have a match, replace characters. 1062 // If we have a match, replace characters.
1063 if (j == other_size) 1063 if (j == other_size)
1064 { 1064 {
1065 for (j = 0; j < replace_size; ++j) 1065 for (j = 0; j < replace_size; ++j)
1066 array[i + j] = replace[j]; 1066 array[i + j] = replace[j];
1067 i += replace_size - 1; 1067 i += replace_size - 1;
1068 pos += other_size - 1; 1068 pos += other_size - 1;
1069 continue; 1069 continue;
1070 } 1070 }
1071 } 1071 }
1072 1072
1073 // No match found, just copy characters. 1073 // No match found, just copy characters.
1074 array[i] = array[pos]; 1074 array[i] = array[pos];
1075 } 1075 }
1076 array[i-1] = 0; 1076 array[i-1] = 0;
1077 used = i; 1077 used = i;
1078 1078
1079 return *this; 1079 return *this;
1080 } 1080 }
1081 1081
1082 // We are going to be adding characters, so the string size will increase. 1082 // We are going to be adding characters, so the string size will increase.
1083 // Count the number of times toReplace exists in the string so we can allocate the new size. 1083 // Count the number of times toReplace exists in the string so we can allocate the new size.
1084 u32 find_count = 0; 1084 u32 find_count = 0;
1085 s32 pos = 0; 1085 s32 pos = 0;
1086 while ((pos = find(other, pos)) != -1) 1086 while ((pos = find(other, pos)) != -1)
1087 { 1087 {
1088 ++find_count; 1088 ++find_count;
1089 ++pos; 1089 ++pos;
1090 } 1090 }
1091 1091
1092 // Re-allocate the string now, if needed. 1092 // Re-allocate the string now, if needed.
1093 u32 len = delta * find_count; 1093 u32 len = delta * find_count;
1094 if (used + len > allocated) 1094 if (used + len > allocated)
1095 reallocate(used + len); 1095 reallocate(used + len);
1096 1096
1097 // Start replacing. 1097 // Start replacing.
1098 pos = 0; 1098 pos = 0;
1099 while ((pos = find(other, pos)) != -1) 1099 while ((pos = find(other, pos)) != -1)
1100 { 1100 {
1101 T* start = array + pos + other_size - 1; 1101 T* start = array + pos + other_size - 1;
1102 T* ptr = array + used - 1; 1102 T* ptr = array + used - 1;
1103 T* end = array + delta + used -1; 1103 T* end = array + delta + used -1;
1104 1104
1105 // Shift characters to make room for the string. 1105 // Shift characters to make room for the string.
1106 while (ptr != start) 1106 while (ptr != start)
1107 { 1107 {
1108 *end = *ptr; 1108 *end = *ptr;
1109 --ptr; 1109 --ptr;
1110 --end; 1110 --end;
1111 } 1111 }
1112 1112
1113 // Add the new string now. 1113 // Add the new string now.
1114 for (u32 i = 0; i < replace_size; ++i) 1114 for (u32 i = 0; i < replace_size; ++i)
1115 array[pos + i] = replace[i]; 1115 array[pos + i] = replace[i];
1116 1116
1117 pos += replace_size; 1117 pos += replace_size;
1118 used += delta; 1118 used += delta;
1119 } 1119 }
1120 1120
1121 return *this; 1121 return *this;
1122 } 1122 }
1123 1123
1124 1124
1125 //! Removes characters from a string. 1125 //! Removes characters from a string.
1126 /** \param c: Character to remove. */ 1126 /** \param c: Character to remove. */
1127 string<T,TAlloc>& remove(T c) 1127 string<T,TAlloc>& remove(T c)
1128 { 1128 {
1129 u32 pos = 0; 1129 u32 pos = 0;
1130 u32 found = 0; 1130 u32 found = 0;
1131 for (u32 i=0; i<used-1; ++i) 1131 for (u32 i=0; i<used-1; ++i)
1132 { 1132 {
1133 if (array[i] == c) 1133 if (array[i] == c)
1134 { 1134 {
1135 ++found; 1135 ++found;
1136 continue; 1136 continue;
1137 } 1137 }
1138 1138
1139 array[pos++] = array[i]; 1139 array[pos++] = array[i];
1140 } 1140 }
1141 used -= found; 1141 used -= found;
1142 array[used-1] = 0; 1142 array[used-1] = 0;
1143 return *this; 1143 return *this;
1144 } 1144 }
1145 1145
1146 1146
1147 //! Removes a string from the string. 1147 //! Removes a string from the string.
1148 /** \param toRemove: String to remove. */ 1148 /** \param toRemove: String to remove. */
1149 string<T,TAlloc>& remove(const string<T,TAlloc>& toRemove) 1149 string<T,TAlloc>& remove(const string<T,TAlloc>& toRemove)
1150 { 1150 {
1151 u32 size = toRemove.size(); 1151 u32 size = toRemove.size();
1152 if ( size == 0 ) 1152 if ( size == 0 )
1153 return *this; 1153 return *this;
1154 u32 pos = 0; 1154 u32 pos = 0;
1155 u32 found = 0; 1155 u32 found = 0;
1156 for (u32 i=0; i<used-1; ++i) 1156 for (u32 i=0; i<used-1; ++i)
1157 { 1157 {
1158 u32 j = 0; 1158 u32 j = 0;
1159 while (j < size) 1159 while (j < size)
1160 { 1160 {
1161 if (array[i + j] != toRemove[j]) 1161 if (array[i + j] != toRemove[j])
1162 break; 1162 break;
1163 ++j; 1163 ++j;
1164 } 1164 }
1165 if (j == size) 1165 if (j == size)
1166 { 1166 {
1167 found += size; 1167 found += size;
1168 i += size - 1; 1168 i += size - 1;
1169 continue; 1169 continue;
1170 } 1170 }
1171 1171
1172 array[pos++] = array[i]; 1172 array[pos++] = array[i];
1173 } 1173 }
1174 used -= found; 1174 used -= found;
1175 array[used-1] = 0; 1175 array[used-1] = 0;
1176 return *this; 1176 return *this;
1177 } 1177 }
1178 1178
1179 1179
1180 //! Removes characters from a string. 1180 //! Removes characters from a string.
1181 /** \param characters: Characters to remove. */ 1181 /** \param characters: Characters to remove. */
1182 string<T,TAlloc>& removeChars(const string<T,TAlloc> & characters) 1182 string<T,TAlloc>& removeChars(const string<T,TAlloc> & characters)
1183 { 1183 {
1184 if (characters.size() == 0) 1184 if (characters.size() == 0)
1185 return *this; 1185 return *this;
1186 1186
1187 u32 pos = 0; 1187 u32 pos = 0;
1188 u32 found = 0; 1188 u32 found = 0;
1189 for (u32 i=0; i<used-1; ++i) 1189 for (u32 i=0; i<used-1; ++i)
1190 { 1190 {
1191 // Don't use characters.findFirst as it finds the \0, 1191 // Don't use characters.findFirst as it finds the \0,
1192 // causing used to become incorrect. 1192 // causing used to become incorrect.
1193 bool docontinue = false; 1193 bool docontinue = false;
1194 for (u32 j=0; j<characters.size(); ++j) 1194 for (u32 j=0; j<characters.size(); ++j)
1195 { 1195 {
1196 if (characters[j] == array[i]) 1196 if (characters[j] == array[i])
1197 { 1197 {
1198 ++found; 1198 ++found;
1199 docontinue = true; 1199 docontinue = true;
1200 break; 1200 break;
1201 } 1201 }
1202 } 1202 }
1203 if (docontinue) 1203 if (docontinue)
1204 continue; 1204 continue;
1205 1205
1206 array[pos++] = array[i]; 1206 array[pos++] = array[i];
1207 } 1207 }
1208 used -= found; 1208 used -= found;
1209 array[used-1] = 0; 1209 array[used-1] = 0;
1210 1210
1211 return *this; 1211 return *this;
1212 } 1212 }
1213 1213
1214 1214
1215 //! Trims the string. 1215 //! Trims the string.
1216 /** Removes the specified characters (by default, Latin-1 whitespace) 1216 /** Removes the specified characters (by default, Latin-1 whitespace)
1217 from the begining and the end of the string. */ 1217 from the begining and the end of the string. */
1218 string<T,TAlloc>& trim(const string<T,TAlloc> & whitespace = " \t\n\r") 1218 string<T,TAlloc>& trim(const string<T,TAlloc> & whitespace = " \t\n\r")
1219 { 1219 {
1220 // find start and end of the substring without the specified characters 1220 // find start and end of the substring without the specified characters
1221 const s32 begin = findFirstCharNotInList(whitespace.c_str(), whitespace.used); 1221 const s32 begin = findFirstCharNotInList(whitespace.c_str(), whitespace.used);
1222 if (begin == -1) 1222 if (begin == -1)
1223 return (*this=""); 1223 return (*this="");
1224 1224
1225 const s32 end = findLastCharNotInList(whitespace.c_str(), whitespace.used); 1225 const s32 end = findLastCharNotInList(whitespace.c_str(), whitespace.used);
1226 1226
1227 return (*this = subString(begin, (end +1) - begin)); 1227 return (*this = subString(begin, (end +1) - begin));
1228 } 1228 }
1229 1229
1230 1230
1231 //! Erases a character from the string. 1231 //! Erases a character from the string.
1232 /** May be slow, because all elements 1232 /** May be slow, because all elements
1233 following after the erased element have to be copied. 1233 following after the erased element have to be copied.
1234 \param index: Index of element to be erased. */ 1234 \param index: Index of element to be erased. */
1235 string<T,TAlloc>& erase(u32 index) 1235 string<T,TAlloc>& erase(u32 index)
1236 { 1236 {
1237 _IRR_DEBUG_BREAK_IF(index>=used) // access violation 1237 _IRR_DEBUG_BREAK_IF(index>=used) // access violation
1238 1238
1239 for (u32 i=index+1; i<used; ++i) 1239 for (u32 i=index+1; i<used; ++i)
1240 array[i-1] = array[i]; 1240 array[i-1] = array[i];
1241 1241
1242 --used; 1242 --used;
1243 return *this; 1243 return *this;
1244 } 1244 }
1245 1245
1246 //! verify the existing string. 1246 //! verify the existing string.
1247 string<T,TAlloc>& validate() 1247 string<T,TAlloc>& validate()
1248 { 1248 {
1249 // terminate on existing null 1249 // terminate on existing null
1250 for (u32 i=0; i<allocated; ++i) 1250 for (u32 i=0; i<allocated; ++i)
1251 { 1251 {
1252 if (array[i] == 0) 1252 if (array[i] == 0)
1253 { 1253 {
1254 used = i + 1; 1254 used = i + 1;
1255 return *this; 1255 return *this;
1256 } 1256 }
1257 } 1257 }
1258 1258
1259 // terminate 1259 // terminate
1260 if ( allocated > 0 ) 1260 if ( allocated > 0 )
1261 { 1261 {
1262 used = allocated; 1262 used = allocated;
1263 array[used-1] = 0; 1263 array[used-1] = 0;
1264 } 1264 }
1265 else 1265 else
1266 { 1266 {
1267 used = 0; 1267 used = 0;
1268 } 1268 }
1269 1269
1270 return *this; 1270 return *this;
1271 } 1271 }
1272 1272
1273 //! gets the last char of a string or null 1273 //! gets the last char of a string or null
1274 T lastChar() const 1274 T lastChar() const
1275 { 1275 {
1276 return used > 1 ? array[used-2] : 0; 1276 return used > 1 ? array[used-2] : 0;
1277 } 1277 }
1278 1278
1279 //! split string into parts. 1279 //! split string into parts.
1280 /** This method will split a string at certain delimiter characters 1280 /** This method will split a string at certain delimiter characters
1281 into the container passed in as reference. The type of the container 1281 into the container passed in as reference. The type of the container
1282 has to be given as template parameter. It must provide a push_back and 1282 has to be given as template parameter. It must provide a push_back and
1283 a size method. 1283 a size method.
1284 \param ret The result container 1284 \param ret The result container
1285 \param c C-style string of delimiter characters 1285 \param c C-style string of delimiter characters
1286 \param count Number of delimiter characters 1286 \param count Number of delimiter characters
1287 \param ignoreEmptyTokens Flag to avoid empty substrings in the result 1287 \param ignoreEmptyTokens Flag to avoid empty substrings in the result
1288 container. If two delimiters occur without a character in between, an 1288 container. If two delimiters occur without a character in between, an
1289 empty substring would be placed in the result. If this flag is set, 1289 empty substring would be placed in the result. If this flag is set,
1290 only non-empty strings are stored. 1290 only non-empty strings are stored.
1291 \param keepSeparators Flag which allows to add the separator to the 1291 \param keepSeparators Flag which allows to add the separator to the
1292 result string. If this flag is true, the concatenation of the 1292 result string. If this flag is true, the concatenation of the
1293 substrings results in the original string. Otherwise, only the 1293 substrings results in the original string. Otherwise, only the
1294 characters between the delimiters are returned. 1294 characters between the delimiters are returned.
1295 \return The number of resulting substrings 1295 \return The number of resulting substrings
1296 */ 1296 */
1297 template<class container> 1297 template<class container>
1298 u32 split(container& ret, const T* const c, u32 count=1, bool ignoreEmptyTokens=true, bool keepSeparators=false) const 1298 u32 split(container& ret, const T* const c, u32 count=1, bool ignoreEmptyTokens=true, bool keepSeparators=false) const
1299 { 1299 {
1300 if (!c) 1300 if (!c)
1301 return 0; 1301 return 0;
1302 1302
1303 const u32 oldSize=ret.size(); 1303 const u32 oldSize=ret.size();
1304 u32 lastpos = 0; 1304 u32 lastpos = 0;
1305 bool lastWasSeparator = false; 1305 bool lastWasSeparator = false;
1306 for (u32 i=0; i<used; ++i) 1306 for (u32 i=0; i<used; ++i)
1307 { 1307 {
1308 bool foundSeparator = false; 1308 bool foundSeparator = false;
1309 for (u32 j=0; j<count; ++j) 1309 for (u32 j=0; j<count; ++j)
1310 { 1310 {
1311 if (array[i] == c[j]) 1311 if (array[i] == c[j])
1312 { 1312 {
1313 if ((!ignoreEmptyTokens || i - lastpos != 0) && 1313 if ((!ignoreEmptyTokens || i - lastpos != 0) &&
1314 !lastWasSeparator) 1314 !lastWasSeparator)
1315 ret.push_back(string<T,TAlloc>(&array[lastpos], i - lastpos)); 1315 ret.push_back(string<T,TAlloc>(&array[lastpos], i - lastpos));
1316 foundSeparator = true; 1316 foundSeparator = true;
1317 lastpos = (keepSeparators ? i : i + 1); 1317 lastpos = (keepSeparators ? i : i + 1);
1318 break; 1318 break;
1319 } 1319 }
1320 } 1320 }
1321 lastWasSeparator = foundSeparator; 1321 lastWasSeparator = foundSeparator;
1322 } 1322 }
1323 if ((used - 1) > lastpos) 1323 if ((used - 1) > lastpos)
1324 ret.push_back(string<T,TAlloc>(&array[lastpos], (used - 1) - lastpos)); 1324 ret.push_back(string<T,TAlloc>(&array[lastpos], (used - 1) - lastpos));
1325 return ret.size()-oldSize; 1325 return ret.size()-oldSize;
1326 } 1326 }
1327 1327
1328private: 1328private:
1329 1329
1330 //! Reallocate the array, make it bigger or smaller 1330 //! Reallocate the array, make it bigger or smaller
1331 void reallocate(u32 new_size) 1331 void reallocate(u32 new_size)
1332 { 1332 {
1333 T* old_array = array; 1333 T* old_array = array;
1334 1334
1335 array = allocator.allocate(new_size); //new T[new_size]; 1335 array = allocator.allocate(new_size); //new T[new_size];
1336 allocated = new_size; 1336 allocated = new_size;
1337 1337
1338 u32 amount = used < new_size ? used : new_size; 1338 u32 amount = used < new_size ? used : new_size;
1339 for (u32 i=0; i<amount; ++i) 1339 for (u32 i=0; i<amount; ++i)
1340 array[i] = old_array[i]; 1340 array[i] = old_array[i];
1341 1341
1342 if (allocated < used) 1342 if (allocated < used)
1343 used = allocated; 1343 used = allocated;
1344 1344
1345 allocator.deallocate(old_array); // delete [] old_array; 1345 allocator.deallocate(old_array); // delete [] old_array;
1346 } 1346 }
1347 1347
1348 //--- member variables 1348 //--- member variables
1349 1349
1350 T* array; 1350 T* array;
1351 u32 allocated; 1351 u32 allocated;
1352 u32 used; 1352 u32 used;
1353 TAlloc allocator; 1353 TAlloc allocator;
1354}; 1354};
1355 1355
1356 1356
1357//! Typedef for character strings 1357//! Typedef for character strings
1358typedef string<c8> stringc; 1358typedef string<c8> stringc;
1359 1359
1360//! Typedef for wide character strings 1360//! Typedef for wide character strings
1361typedef string<wchar_t> stringw; 1361typedef string<wchar_t> stringw;
1362 1362
1363 1363
1364} // end namespace core 1364} // end namespace core
1365} // end namespace irr 1365} // end namespace irr
1366 1366
1367#endif 1367#endif
1368 1368