From f9158592e1478b2013afc7041d9ed041cf2d2f4a Mon Sep 17 00:00:00 2001 From: David Walter Seikel Date: Mon, 13 Jan 2014 19:47:58 +1000 Subject: Update Irrlicht to 1.8.1. Include actual change markers this time. lol --- .../doc/html/irr_string_8h_source.html | 1340 ++++++++++++++++++++ 1 file changed, 1340 insertions(+) create mode 100644 libraries/irrlicht-1.8.1/doc/html/irr_string_8h_source.html (limited to 'libraries/irrlicht-1.8.1/doc/html/irr_string_8h_source.html') diff --git a/libraries/irrlicht-1.8.1/doc/html/irr_string_8h_source.html b/libraries/irrlicht-1.8.1/doc/html/irr_string_8h_source.html new file mode 100644 index 0000000..42c1b05 --- /dev/null +++ b/libraries/irrlicht-1.8.1/doc/html/irr_string_8h_source.html @@ -0,0 +1,1340 @@ + + +
+ +00001 // Copyright (C) 2002-2012 Nikolaus Gebhardt +00002 // This file is part of the "Irrlicht Engine" and the "irrXML" project. +00003 // For conditions of distribution and use, see copyright notice in irrlicht.h and irrXML.h +00004 +00005 #ifndef __IRR_STRING_H_INCLUDED__ +00006 #define __IRR_STRING_H_INCLUDED__ +00007 +00008 #include "irrTypes.h" +00009 #include "irrAllocator.h" +00010 #include "irrMath.h" +00011 #include <stdio.h> +00012 #include <string.h> +00013 #include <stdlib.h> +00014 +00015 namespace irr +00016 { +00017 namespace core +00018 { +00019 +00021 +00032 enum eLocaleID +00033 { +00034 IRR_LOCALE_ANSI = 0, +00035 IRR_LOCALE_GERMAN = 1 +00036 }; +00037 +00038 static eLocaleID locale_current = IRR_LOCALE_ANSI; +00039 static inline void locale_set ( eLocaleID id ) +00040 { +00041 locale_current = id; +00042 } +00043 +00045 static inline u32 locale_lower ( u32 x ) +00046 { +00047 switch ( locale_current ) +00048 { +00049 case IRR_LOCALE_GERMAN: +00050 case IRR_LOCALE_ANSI: +00051 break; +00052 } +00053 // ansi +00054 return x >= 'A' && x <= 'Z' ? x + 0x20 : x; +00055 } +00056 +00058 static inline u32 locale_upper ( u32 x ) +00059 { +00060 switch ( locale_current ) +00061 { +00062 case IRR_LOCALE_GERMAN: +00063 case IRR_LOCALE_ANSI: +00064 break; +00065 } +00066 +00067 // ansi +00068 return x >= 'a' && x <= 'z' ? x + ( 'A' - 'a' ) : x; +00069 } +00070 +00071 +00072 template <typename T, typename TAlloc = irrAllocator<T> > +00073 class string +00074 { +00075 public: +00076 +00077 typedef T char_type; +00078 +00080 string() +00081 : array(0), allocated(1), used(1) +00082 { +00083 array = allocator.allocate(1); // new T[1]; +00084 array[0] = 0; +00085 } +00086 +00087 +00089 string(const string<T,TAlloc>& other) +00090 : array(0), allocated(0), used(0) +00091 { +00092 *this = other; +00093 } +00094 +00096 template <class B, class A> +00097 string(const string<B, A>& other) +00098 : array(0), allocated(0), used(0) +00099 { +00100 *this = other; +00101 } +00102 +00103 +00105 explicit string(const double number) +00106 : array(0), allocated(0), used(0) +00107 { +00108 c8 tmpbuf[255]; +00109 snprintf(tmpbuf, 255, "%0.6f", number); +00110 *this = tmpbuf; +00111 } +00112 +00113 +00115 explicit string(int number) +00116 : array(0), allocated(0), used(0) +00117 { +00118 // store if negative and make positive +00119 +00120 bool negative = false; +00121 if (number < 0) +00122 { +00123 number *= -1; +00124 negative = true; +00125 } +00126 +00127 // temporary buffer for 16 numbers +00128 +00129 c8 tmpbuf[16]={0}; +00130 u32 idx = 15; +00131 +00132 // special case '0' +00133 +00134 if (!number) +00135 { +00136 tmpbuf[14] = '0'; +00137 *this = &tmpbuf[14]; +00138 return; +00139 } +00140 +00141 // add numbers +00142 +00143 while(number && idx) +00144 { +00145 --idx; +00146 tmpbuf[idx] = (c8)('0' + (number % 10)); +00147 number /= 10; +00148 } +00149 +00150 // add sign +00151 +00152 if (negative) +00153 { +00154 --idx; +00155 tmpbuf[idx] = '-'; +00156 } +00157 +00158 *this = &tmpbuf[idx]; +00159 } +00160 +00161 +00163 explicit string(unsigned int number) +00164 : array(0), allocated(0), used(0) +00165 { +00166 // temporary buffer for 16 numbers +00167 +00168 c8 tmpbuf[16]={0}; +00169 u32 idx = 15; +00170 +00171 // special case '0' +00172 +00173 if (!number) +00174 { +00175 tmpbuf[14] = '0'; +00176 *this = &tmpbuf[14]; +00177 return; +00178 } +00179 +00180 // add numbers +00181 +00182 while(number && idx) +00183 { +00184 --idx; +00185 tmpbuf[idx] = (c8)('0' + (number % 10)); +00186 number /= 10; +00187 } +00188 +00189 *this = &tmpbuf[idx]; +00190 } +00191 +00192 +00194 explicit string(long number) +00195 : array(0), allocated(0), used(0) +00196 { +00197 // store if negative and make positive +00198 +00199 bool negative = false; +00200 if (number < 0) +00201 { +00202 number *= -1; +00203 negative = true; +00204 } +00205 +00206 // temporary buffer for 16 numbers +00207 +00208 c8 tmpbuf[16]={0}; +00209 u32 idx = 15; +00210 +00211 // special case '0' +00212 +00213 if (!number) +00214 { +00215 tmpbuf[14] = '0'; +00216 *this = &tmpbuf[14]; +00217 return; +00218 } +00219 +00220 // add numbers +00221 +00222 while(number && idx) +00223 { +00224 --idx; +00225 tmpbuf[idx] = (c8)('0' + (number % 10)); +00226 number /= 10; +00227 } +00228 +00229 // add sign +00230 +00231 if (negative) +00232 { +00233 --idx; +00234 tmpbuf[idx] = '-'; +00235 } +00236 +00237 *this = &tmpbuf[idx]; +00238 } +00239 +00240 +00242 explicit string(unsigned long number) +00243 : array(0), allocated(0), used(0) +00244 { +00245 // temporary buffer for 16 numbers +00246 +00247 c8 tmpbuf[16]={0}; +00248 u32 idx = 15; +00249 +00250 // special case '0' +00251 +00252 if (!number) +00253 { +00254 tmpbuf[14] = '0'; +00255 *this = &tmpbuf[14]; +00256 return; +00257 } +00258 +00259 // add numbers +00260 +00261 while(number && idx) +00262 { +00263 --idx; +00264 tmpbuf[idx] = (c8)('0' + (number % 10)); +00265 number /= 10; +00266 } +00267 +00268 *this = &tmpbuf[idx]; +00269 } +00270 +00271 +00273 template <class B> +00274 string(const B* const c, u32 length) +00275 : array(0), allocated(0), used(0) +00276 { +00277 if (!c) +00278 { +00279 // correctly init the string to an empty one +00280 *this=""; +00281 return; +00282 } +00283 +00284 allocated = used = length+1; +00285 array = allocator.allocate(used); // new T[used]; +00286 +00287 for (u32 l = 0; l<length; ++l) +00288 array[l] = (T)c[l]; +00289 +00290 array[length] = 0; +00291 } +00292 +00293 +00295 template <class B> +00296 string(const B* const c) +00297 : array(0), allocated(0), used(0) +00298 { +00299 *this = c; +00300 } +00301 +00302 +00304 ~string() +00305 { +00306 allocator.deallocate(array); // delete [] array; +00307 } +00308 +00309 +00311 string<T,TAlloc>& operator=(const string<T,TAlloc>& other) +00312 { +00313 if (this == &other) +00314 return *this; +00315 +00316 used = other.size()+1; +00317 if (used>allocated) +00318 { +00319 allocator.deallocate(array); // delete [] array; +00320 allocated = used; +00321 array = allocator.allocate(used); //new T[used]; +00322 } +00323 +00324 const T* p = other.c_str(); +00325 for (u32 i=0; i<used; ++i, ++p) +00326 array[i] = *p; +00327 +00328 return *this; +00329 } +00330 +00332 template <class B, class A> +00333 string<T,TAlloc>& operator=(const string<B,A>& other) +00334 { +00335 *this = other.c_str(); +00336 return *this; +00337 } +00338 +00339 +00341 template <class B> +00342 string<T,TAlloc>& operator=(const B* const c) +00343 { +00344 if (!c) +00345 { +00346 if (!array) +00347 { +00348 array = allocator.allocate(1); //new T[1]; +00349 allocated = 1; +00350 } +00351 used = 1; +00352 array[0] = 0x0; +00353 return *this; +00354 } +00355 +00356 if ((void*)c == (void*)array) +00357 return *this; +00358 +00359 u32 len = 0; +00360 const B* p = c; +00361 do +00362 { +00363 ++len; +00364 } while(*p++); +00365 +00366 // we'll keep the old string for a while, because the new +00367 // string could be a part of the current string. +00368 T* oldArray = array; +00369 +00370 used = len; +00371 if (used>allocated) +00372 { +00373 allocated = used; +00374 array = allocator.allocate(used); //new T[used]; +00375 } +00376 +00377 for (u32 l = 0; l<len; ++l) +00378 array[l] = (T)c[l]; +00379 +00380 if (oldArray != array) +00381 allocator.deallocate(oldArray); // delete [] oldArray; +00382 +00383 return *this; +00384 } +00385 +00386 +00388 string<T,TAlloc> operator+(const string<T,TAlloc>& other) const +00389 { +00390 string<T,TAlloc> str(*this); +00391 str.append(other); +00392 +00393 return str; +00394 } +00395 +00396 +00398 template <class B> +00399 string<T,TAlloc> operator+(const B* const c) const +00400 { +00401 string<T,TAlloc> str(*this); +00402 str.append(c); +00403 +00404 return str; +00405 } +00406 +00407 +00409 T& operator [](const u32 index) +00410 { +00411 _IRR_DEBUG_BREAK_IF(index>=used) // bad index +00412 return array[index]; +00413 } +00414 +00415 +00417 const T& operator [](const u32 index) const +00418 { +00419 _IRR_DEBUG_BREAK_IF(index>=used) // bad index +00420 return array[index]; +00421 } +00422 +00423 +00425 bool operator==(const T* const str) const +00426 { +00427 if (!str) +00428 return false; +00429 +00430 u32 i; +00431 for (i=0; array[i] && str[i]; ++i) +00432 if (array[i] != str[i]) +00433 return false; +00434 +00435 return (!array[i] && !str[i]); +00436 } +00437 +00438 +00440 bool operator==(const string<T,TAlloc>& other) const +00441 { +00442 for (u32 i=0; array[i] && other.array[i]; ++i) +00443 if (array[i] != other.array[i]) +00444 return false; +00445 +00446 return used == other.used; +00447 } +00448 +00449 +00451 bool operator<(const string<T,TAlloc>& other) const +00452 { +00453 for (u32 i=0; array[i] && other.array[i]; ++i) +00454 { +00455 const s32 diff = array[i] - other.array[i]; +00456 if (diff) +00457 return (diff < 0); +00458 } +00459 +00460 return (used < other.used); +00461 } +00462 +00463 +00465 bool operator!=(const T* const str) const +00466 { +00467 return !(*this == str); +00468 } +00469 +00470 +00472 bool operator!=(const string<T,TAlloc>& other) const +00473 { +00474 return !(*this == other); +00475 } +00476 +00477 +00479 +00481 u32 size() const +00482 { +00483 return used-1; +00484 } +00485 +00488 bool empty() const +00489 { +00490 return (size() == 0); +00491 } +00492 +00494 +00495 const T* c_str() const +00496 { +00497 return array; +00498 } +00499 +00500 +00502 string<T,TAlloc>& make_lower() +00503 { +00504 for (u32 i=0; array[i]; ++i) +00505 array[i] = locale_lower ( array[i] ); +00506 return *this; +00507 } +00508 +00509 +00511 string<T,TAlloc>& make_upper() +00512 { +00513 for (u32 i=0; array[i]; ++i) +00514 array[i] = locale_upper ( array[i] ); +00515 return *this; +00516 } +00517 +00518 +00520 +00522 bool equals_ignore_case(const string<T,TAlloc>& other) const +00523 { +00524 for(u32 i=0; array[i] && other[i]; ++i) +00525 if (locale_lower( array[i]) != locale_lower(other[i])) +00526 return false; +00527 +00528 return used == other.used; +00529 } +00530 +00532 +00535 bool equals_substring_ignore_case(const string<T,TAlloc>&other, const s32 sourcePos = 0 ) const +00536 { +00537 if ( (u32) sourcePos >= used ) +00538 return false; +00539 +00540 u32 i; +00541 for( i=0; array[sourcePos + i] && other[i]; ++i) +00542 if (locale_lower( array[sourcePos + i]) != locale_lower(other[i])) +00543 return false; +00544 +00545 return array[sourcePos + i] == 0 && other[i] == 0; +00546 } +00547 +00548 +00550 +00552 bool lower_ignore_case(const string<T,TAlloc>& other) const +00553 { +00554 for(u32 i=0; array[i] && other.array[i]; ++i) +00555 { +00556 s32 diff = (s32) locale_lower ( array[i] ) - (s32) locale_lower ( other.array[i] ); +00557 if ( diff ) +00558 return diff < 0; +00559 } +00560 +00561 return used < other.used; +00562 } +00563 +00564 +00566 +00569 bool equalsn(const string<T,TAlloc>& other, u32 n) const +00570 { +00571 u32 i; +00572 for(i=0; array[i] && other[i] && i < n; ++i) +00573 if (array[i] != other[i]) +00574 return false; +00575 +00576 // if one (or both) of the strings was smaller then they +00577 // are only equal if they have the same length +00578 return (i == n) || (used == other.used); +00579 } +00580 +00581 +00583 +00586 bool equalsn(const T* const str, u32 n) const +00587 { +00588 if (!str) +00589 return false; +00590 u32 i; +00591 for(i=0; array[i] && str[i] && i < n; ++i) +00592 if (array[i] != str[i]) +00593 return false; +00594 +00595 // if one (or both) of the strings was smaller then they +00596 // are only equal if they have the same length +00597 return (i == n) || (array[i] == 0 && str[i] == 0); +00598 } +00599 +00600 +00602 +00603 string<T,TAlloc>& append(T character) +00604 { +00605 if (used + 1 > allocated) +00606 reallocate(used + 1); +00607 +00608 ++used; +00609 +00610 array[used-2] = character; +00611 array[used-1] = 0; +00612 +00613 return *this; +00614 } +00615 +00616 +00618 +00620 string<T,TAlloc>& append(const T* const other, u32 length=0xffffffff) +00621 { +00622 if (!other) +00623 return *this; +00624 +00625 u32 len = 0; +00626 const T* p = other; +00627 while(*p) +00628 { +00629 ++len; +00630 ++p; +00631 } +00632 if (len > length) +00633 len = length; +00634 +00635 if (used + len > allocated) +00636 reallocate(used + len); +00637 +00638 --used; +00639 ++len; +00640 +00641 for (u32 l=0; l<len; ++l) +00642 array[l+used] = *(other+l); +00643 +00644 used += len; +00645 +00646 return *this; +00647 } +00648 +00649 +00651 +00652 string<T,TAlloc>& append(const string<T,TAlloc>& other) +00653 { +00654 if (other.size() == 0) +00655 return *this; +00656 +00657 --used; +00658 u32 len = other.size()+1; +00659 +00660 if (used + len > allocated) +00661 reallocate(used + len); +00662 +00663 for (u32 l=0; l<len; ++l) +00664 array[used+l] = other[l]; +00665 +00666 used += len; +00667 +00668 return *this; +00669 } +00670 +00671 +00673 +00675 string<T,TAlloc>& append(const string<T,TAlloc>& other, u32 length) +00676 { +00677 if (other.size() == 0) +00678 return *this; +00679 +00680 if (other.size() < length) +00681 { +00682 append(other); +00683 return *this; +00684 } +00685 +00686 if (used + length > allocated) +00687 reallocate(used + length); +00688 +00689 --used; +00690 +00691 for (u32 l=0; l<length; ++l) +00692 array[l+used] = other[l]; +00693 used += length; +00694 +00695 // ensure proper termination +00696 array[used]=0; +00697 ++used; +00698 +00699 return *this; +00700 } +00701 +00702 +00704 +00705 void reserve(u32 count) +00706 { +00707 if (count < allocated) +00708 return; +00709 +00710 reallocate(count); +00711 } +00712 +00713 +00715 +00718 s32 findFirst(T c) const +00719 { +00720 for (u32 i=0; i<used-1; ++i) +00721 if (array[i] == c) +00722 return i; +00723 +00724 return -1; +00725 } +00726 +00728 +00734 s32 findFirstChar(const T* const c, u32 count=1) const +00735 { +00736 if (!c || !count) +00737 return -1; +00738 +00739 for (u32 i=0; i<used-1; ++i) +00740 for (u32 j=0; j<count; ++j) +00741 if (array[i] == c[j]) +00742 return i; +00743 +00744 return -1; +00745 } +00746 +00747 +00749 +00755 template <class B> +00756 s32 findFirstCharNotInList(const B* const c, u32 count=1) const +00757 { +00758 if (!c || !count) +00759 return -1; +00760 +00761 for (u32 i=0; i<used-1; ++i) +00762 { +00763 u32 j; +00764 for (j=0; j<count; ++j) +00765 if (array[i] == c[j]) +00766 break; +00767 +00768 if (j==count) +00769 return i; +00770 } +00771 +00772 return -1; +00773 } +00774 +00776 +00782 template <class B> +00783 s32 findLastCharNotInList(const B* const c, u32 count=1) const +00784 { +00785 if (!c || !count) +00786 return -1; +00787 +00788 for (s32 i=(s32)(used-2); i>=0; --i) +00789 { +00790 u32 j; +00791 for (j=0; j<count; ++j) +00792 if (array[i] == c[j]) +00793 break; +00794 +00795 if (j==count) +00796 return i; +00797 } +00798 +00799 return -1; +00800 } +00801 +00803 +00807 s32 findNext(T c, u32 startPos) const +00808 { +00809 for (u32 i=startPos; i<used-1; ++i) +00810 if (array[i] == c) +00811 return i; +00812 +00813 return -1; +00814 } +00815 +00816 +00818 +00822 s32 findLast(T c, s32 start = -1) const +00823 { +00824 start = core::clamp ( start < 0 ? (s32)(used) - 2 : start, 0, (s32)(used) - 2 ); +00825 for (s32 i=start; i>=0; --i) +00826 if (array[i] == c) +00827 return i; +00828 +00829 return -1; +00830 } +00831 +00833 +00839 s32 findLastChar(const T* const c, u32 count=1) const +00840 { +00841 if (!c || !count) +00842 return -1; +00843 +00844 for (s32 i=(s32)used-2; i>=0; --i) +00845 for (u32 j=0; j<count; ++j) +00846 if (array[i] == c[j]) +00847 return i; +00848 +00849 return -1; +00850 } +00851 +00852 +00854 +00858 template <class B> +00859 s32 find(const B* const str, const u32 start = 0) const +00860 { +00861 if (str && *str) +00862 { +00863 u32 len = 0; +00864 +00865 while (str[len]) +00866 ++len; +00867 +00868 if (len > used-1) +00869 return -1; +00870 +00871 for (u32 i=start; i<used-len; ++i) +00872 { +00873 u32 j=0; +00874 +00875 while(str[j] && array[i+j] == str[j]) +00876 ++j; +00877 +00878 if (!str[j]) +00879 return i; +00880 } +00881 } +00882 +00883 return -1; +00884 } +00885 +00886 +00888 +00891 string<T> subString(u32 begin, s32 length, bool make_lower = false ) const +00892 { +00893 // if start after string +00894 // or no proper substring length +00895 if ((length <= 0) || (begin>=size())) +00896 return string<T>(""); +00897 // clamp length to maximal value +00898 if ((length+begin) > size()) +00899 length = size()-begin; +00900 +00901 string<T> o; +00902 o.reserve(length+1); +00903 +00904 s32 i; +00905 if ( !make_lower ) +00906 { +00907 for (i=0; i<length; ++i) +00908 o.array[i] = array[i+begin]; +00909 } +00910 else +00911 { +00912 for (i=0; i<length; ++i) +00913 o.array[i] = locale_lower ( array[i+begin] ); +00914 } +00915 +00916 o.array[length] = 0; +00917 o.used = length + 1; +00918 +00919 return o; +00920 } +00921 +00922 +00924 +00925 string<T,TAlloc>& operator += (T c) +00926 { +00927 append(c); +00928 return *this; +00929 } +00930 +00931 +00933 +00934 string<T,TAlloc>& operator += (const T* const c) +00935 { +00936 append(c); +00937 return *this; +00938 } +00939 +00940 +00942 +00943 string<T,TAlloc>& operator += (const string<T,TAlloc>& other) +00944 { +00945 append(other); +00946 return *this; +00947 } +00948 +00949 +00951 +00952 string<T,TAlloc>& operator += (const int i) +00953 { +00954 append(string<T,TAlloc>(i)); +00955 return *this; +00956 } +00957 +00958 +00960 +00961 string<T,TAlloc>& operator += (const unsigned int i) +00962 { +00963 append(string<T,TAlloc>(i)); +00964 return *this; +00965 } +00966 +00967 +00969 +00970 string<T,TAlloc>& operator += (const long i) +00971 { +00972 append(string<T,TAlloc>(i)); +00973 return *this; +00974 } +00975 +00976 +00978 +00979 string<T,TAlloc>& operator += (const unsigned long i) +00980 { +00981 append(string<T,TAlloc>(i)); +00982 return *this; +00983 } +00984 +00985 +00987 +00988 string<T,TAlloc>& operator += (const double i) +00989 { +00990 append(string<T,TAlloc>(i)); +00991 return *this; +00992 } +00993 +00994 +00996 +00997 string<T,TAlloc>& operator += (const float i) +00998 { +00999 append(string<T,TAlloc>(i)); +01000 return *this; +01001 } +01002 +01003 +01005 +01007 string<T,TAlloc>& replace(T toReplace, T replaceWith) +01008 { +01009 for (u32 i=0; i<used-1; ++i) +01010 if (array[i] == toReplace) +01011 array[i] = replaceWith; +01012 return *this; +01013 } +01014 +01015 +01017 +01019 string<T,TAlloc>& replace(const string<T,TAlloc>& toReplace, const string<T,TAlloc>& replaceWith) +01020 { +01021 if (toReplace.size() == 0) +01022 return *this; +01023 +01024 const T* other = toReplace.c_str(); +01025 const T* replace = replaceWith.c_str(); +01026 const u32 other_size = toReplace.size(); +01027 const u32 replace_size = replaceWith.size(); +01028 +01029 // Determine the delta. The algorithm will change depending on the delta. +01030 s32 delta = replace_size - other_size; +01031 +01032 // A character for character replace. The string will not shrink or grow. +01033 if (delta == 0) +01034 { +01035 s32 pos = 0; +01036 while ((pos = find(other, pos)) != -1) +01037 { +01038 for (u32 i = 0; i < replace_size; ++i) +01039 array[pos + i] = replace[i]; +01040 ++pos; +01041 } +01042 return *this; +01043 } +01044 +01045 // We are going to be removing some characters. The string will shrink. +01046 if (delta < 0) +01047 { +01048 u32 i = 0; +01049 for (u32 pos = 0; pos < used; ++i, ++pos) +01050 { +01051 // Is this potentially a match? +01052 if (array[pos] == *other) +01053 { +01054 // Check to see if we have a match. +01055 u32 j; +01056 for (j = 0; j < other_size; ++j) +01057 { +01058 if (array[pos + j] != other[j]) +01059 break; +01060 } +01061 +01062 // If we have a match, replace characters. +01063 if (j == other_size) +01064 { +01065 for (j = 0; j < replace_size; ++j) +01066 array[i + j] = replace[j]; +01067 i += replace_size - 1; +01068 pos += other_size - 1; +01069 continue; +01070 } +01071 } +01072 +01073 // No match found, just copy characters. +01074 array[i] = array[pos]; +01075 } +01076 array[i-1] = 0; +01077 used = i; +01078 +01079 return *this; +01080 } +01081 +01082 // We are going to be adding characters, so the string size will increase. +01083 // Count the number of times toReplace exists in the string so we can allocate the new size. +01084 u32 find_count = 0; +01085 s32 pos = 0; +01086 while ((pos = find(other, pos)) != -1) +01087 { +01088 ++find_count; +01089 ++pos; +01090 } +01091 +01092 // Re-allocate the string now, if needed. +01093 u32 len = delta * find_count; +01094 if (used + len > allocated) +01095 reallocate(used + len); +01096 +01097 // Start replacing. +01098 pos = 0; +01099 while ((pos = find(other, pos)) != -1) +01100 { +01101 T* start = array + pos + other_size - 1; +01102 T* ptr = array + used - 1; +01103 T* end = array + delta + used -1; +01104 +01105 // Shift characters to make room for the string. +01106 while (ptr != start) +01107 { +01108 *end = *ptr; +01109 --ptr; +01110 --end; +01111 } +01112 +01113 // Add the new string now. +01114 for (u32 i = 0; i < replace_size; ++i) +01115 array[pos + i] = replace[i]; +01116 +01117 pos += replace_size; +01118 used += delta; +01119 } +01120 +01121 return *this; +01122 } +01123 +01124 +01126 +01127 string<T,TAlloc>& remove(T c) +01128 { +01129 u32 pos = 0; +01130 u32 found = 0; +01131 for (u32 i=0; i<used-1; ++i) +01132 { +01133 if (array[i] == c) +01134 { +01135 ++found; +01136 continue; +01137 } +01138 +01139 array[pos++] = array[i]; +01140 } +01141 used -= found; +01142 array[used-1] = 0; +01143 return *this; +01144 } +01145 +01146 +01148 +01149 string<T,TAlloc>& remove(const string<T,TAlloc>& toRemove) +01150 { +01151 u32 size = toRemove.size(); +01152 if ( size == 0 ) +01153 return *this; +01154 u32 pos = 0; +01155 u32 found = 0; +01156 for (u32 i=0; i<used-1; ++i) +01157 { +01158 u32 j = 0; +01159 while (j < size) +01160 { +01161 if (array[i + j] != toRemove[j]) +01162 break; +01163 ++j; +01164 } +01165 if (j == size) +01166 { +01167 found += size; +01168 i += size - 1; +01169 continue; +01170 } +01171 +01172 array[pos++] = array[i]; +01173 } +01174 used -= found; +01175 array[used-1] = 0; +01176 return *this; +01177 } +01178 +01179 +01181 +01182 string<T,TAlloc>& removeChars(const string<T,TAlloc> & characters) +01183 { +01184 if (characters.size() == 0) +01185 return *this; +01186 +01187 u32 pos = 0; +01188 u32 found = 0; +01189 for (u32 i=0; i<used-1; ++i) +01190 { +01191 // Don't use characters.findFirst as it finds the \0, +01192 // causing used to become incorrect. +01193 bool docontinue = false; +01194 for (u32 j=0; j<characters.size(); ++j) +01195 { +01196 if (characters[j] == array[i]) +01197 { +01198 ++found; +01199 docontinue = true; +01200 break; +01201 } +01202 } +01203 if (docontinue) +01204 continue; +01205 +01206 array[pos++] = array[i]; +01207 } +01208 used -= found; +01209 array[used-1] = 0; +01210 +01211 return *this; +01212 } +01213 +01214 +01216 +01218 string<T,TAlloc>& trim(const string<T,TAlloc> & whitespace = " \t\n\r") +01219 { +01220 // find start and end of the substring without the specified characters +01221 const s32 begin = findFirstCharNotInList(whitespace.c_str(), whitespace.used); +01222 if (begin == -1) +01223 return (*this=""); +01224 +01225 const s32 end = findLastCharNotInList(whitespace.c_str(), whitespace.used); +01226 +01227 return (*this = subString(begin, (end +1) - begin)); +01228 } +01229 +01230 +01232 +01235 string<T,TAlloc>& erase(u32 index) +01236 { +01237 _IRR_DEBUG_BREAK_IF(index>=used) // access violation +01238 +01239 for (u32 i=index+1; i<used; ++i) +01240 array[i-1] = array[i]; +01241 +01242 --used; +01243 return *this; +01244 } +01245 +01247 string<T,TAlloc>& validate() +01248 { +01249 // terminate on existing null +01250 for (u32 i=0; i<allocated; ++i) +01251 { +01252 if (array[i] == 0) +01253 { +01254 used = i + 1; +01255 return *this; +01256 } +01257 } +01258 +01259 // terminate +01260 if ( allocated > 0 ) +01261 { +01262 used = allocated; +01263 array[used-1] = 0; +01264 } +01265 else +01266 { +01267 used = 0; +01268 } +01269 +01270 return *this; +01271 } +01272 +01274 T lastChar() const +01275 { +01276 return used > 1 ? array[used-2] : 0; +01277 } +01278 +01280 +01297 template<class container> +01298 u32 split(container& ret, const T* const c, u32 count=1, bool ignoreEmptyTokens=true, bool keepSeparators=false) const +01299 { +01300 if (!c) +01301 return 0; +01302 +01303 const u32 oldSize=ret.size(); +01304 u32 lastpos = 0; +01305 bool lastWasSeparator = false; +01306 for (u32 i=0; i<used; ++i) +01307 { +01308 bool foundSeparator = false; +01309 for (u32 j=0; j<count; ++j) +01310 { +01311 if (array[i] == c[j]) +01312 { +01313 if ((!ignoreEmptyTokens || i - lastpos != 0) && +01314 !lastWasSeparator) +01315 ret.push_back(string<T,TAlloc>(&array[lastpos], i - lastpos)); +01316 foundSeparator = true; +01317 lastpos = (keepSeparators ? i : i + 1); +01318 break; +01319 } +01320 } +01321 lastWasSeparator = foundSeparator; +01322 } +01323 if ((used - 1) > lastpos) +01324 ret.push_back(string<T,TAlloc>(&array[lastpos], (used - 1) - lastpos)); +01325 return ret.size()-oldSize; +01326 } +01327 +01328 private: +01329 +01331 void reallocate(u32 new_size) +01332 { +01333 T* old_array = array; +01334 +01335 array = allocator.allocate(new_size); //new T[new_size]; +01336 allocated = new_size; +01337 +01338 u32 amount = used < new_size ? used : new_size; +01339 for (u32 i=0; i<amount; ++i) +01340 array[i] = old_array[i]; +01341 +01342 if (allocated < used) +01343 used = allocated; +01344 +01345 allocator.deallocate(old_array); // delete [] old_array; +01346 } +01347 +01348 //--- member variables +01349 +01350 T* array; +01351 u32 allocated; +01352 u32 used; +01353 TAlloc allocator; +01354 }; +01355 +01356 +01358 typedef string<c8> stringc; +01359 +01361 typedef string<wchar_t> stringw; +01362 +01363 +01364 } // end namespace core +01365 } // end namespace irr +01366 +01367 #endif +01368 +