vrshoot
diff libs/assimp/irrXML/irrString.h @ 0:b2f14e535253
initial commit
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sat, 01 Feb 2014 19:58:19 +0200 |
parents | |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/libs/assimp/irrXML/irrString.h Sat Feb 01 19:58:19 2014 +0200 1.3 @@ -0,0 +1,664 @@ 1.4 +// Copyright (C) 2002-2005 Nikolaus Gebhardt 1.5 +// This file is part of the "Irrlicht Engine" and the "irrXML" project. 1.6 +// For conditions of distribution and use, see copyright notice in irrlicht.h and irrXML.h 1.7 + 1.8 +#ifndef __IRR_STRING_H_INCLUDED__ 1.9 +#define __IRR_STRING_H_INCLUDED__ 1.10 + 1.11 +#include "irrTypes.h" 1.12 + 1.13 +namespace irr 1.14 +{ 1.15 +namespace core 1.16 +{ 1.17 + 1.18 +//! Very simple string class with some useful features. 1.19 +/** string<c8> and string<wchar_t> work both with unicode AND ascii, 1.20 +so you can assign unicode to string<c8> and ascii to string<wchar_t> 1.21 +(and the other way round) if your ever would want to. 1.22 +Note that the conversation between both is not done using an encoding. 1.23 + 1.24 +Known bugs: 1.25 +Special characters like 'Ä', 'Ü' and 'Ö' are ignored in the 1.26 +methods make_upper, make_lower and equals_ignore_case. 1.27 +*/ 1.28 +template <class T> 1.29 +class string 1.30 +{ 1.31 +public: 1.32 + 1.33 + //! Default constructor 1.34 + string() 1.35 + : array(0), allocated(1), used(1) 1.36 + { 1.37 + array = new T[1]; 1.38 + array[0] = 0x0; 1.39 + } 1.40 + 1.41 + 1.42 + 1.43 + //! Constructor 1.44 + string(const string<T>& other) 1.45 + : array(0), allocated(0), used(0) 1.46 + { 1.47 + *this = other; 1.48 + } 1.49 + 1.50 + 1.51 + //! Constructs a string from an int 1.52 + string(int number) 1.53 + : array(0), allocated(0), used(0) 1.54 + { 1.55 + // store if negative and make positive 1.56 + 1.57 + bool negative = false; 1.58 + if (number < 0) 1.59 + { 1.60 + number *= -1; 1.61 + negative = true; 1.62 + } 1.63 + 1.64 + // temporary buffer for 16 numbers 1.65 + 1.66 + c8 tmpbuf[16]; 1.67 + tmpbuf[15] = 0; 1.68 + s32 idx = 15; 1.69 + 1.70 + // special case '0' 1.71 + 1.72 + if (!number) 1.73 + { 1.74 + tmpbuf[14] = '0'; 1.75 + *this = &tmpbuf[14]; 1.76 + return; 1.77 + } 1.78 + 1.79 + // add numbers 1.80 + 1.81 + while(number && idx) 1.82 + { 1.83 + idx--; 1.84 + tmpbuf[idx] = (c8)('0' + (number % 10)); 1.85 + number = number / 10; 1.86 + } 1.87 + 1.88 + // add sign 1.89 + 1.90 + if (negative) 1.91 + { 1.92 + idx--; 1.93 + tmpbuf[idx] = '-'; 1.94 + } 1.95 + 1.96 + *this = &tmpbuf[idx]; 1.97 + } 1.98 + 1.99 + 1.100 + 1.101 + //! Constructor for copying a string from a pointer with a given lenght 1.102 + template <class B> 1.103 + string(const B* c, s32 lenght) 1.104 + : array(0), allocated(0), used(0) 1.105 + { 1.106 + if (!c) 1.107 + return; 1.108 + 1.109 + allocated = used = lenght+1; 1.110 + array = new T[used]; 1.111 + 1.112 + for (s32 l = 0; l<lenght; ++l) 1.113 + array[l] = (T)c[l]; 1.114 + 1.115 + array[lenght] = 0; 1.116 + } 1.117 + 1.118 + 1.119 + 1.120 + //! Constructor for unicode and ascii strings 1.121 + template <class B> 1.122 + string(const B* c) 1.123 + : array(0),allocated(0), used(0) 1.124 + { 1.125 + *this = c; 1.126 + } 1.127 + 1.128 + 1.129 + 1.130 + //! destructor 1.131 + ~string() 1.132 + { 1.133 + delete [] array; 1.134 + } 1.135 + 1.136 + 1.137 + 1.138 + //! Assignment operator 1.139 + string<T>& operator=(const string<T>& other) 1.140 + { 1.141 + if (this == &other) 1.142 + return *this; 1.143 + 1.144 + delete [] array; 1.145 + allocated = used = other.size()+1; 1.146 + array = new T[used]; 1.147 + 1.148 + const T* p = other.c_str(); 1.149 + for (s32 i=0; i<used; ++i, ++p) 1.150 + array[i] = *p; 1.151 + 1.152 + return *this; 1.153 + } 1.154 + 1.155 + 1.156 + 1.157 + //! Assignment operator for strings, ascii and unicode 1.158 + template <class B> 1.159 + string<T>& operator=(const B* c) 1.160 + { 1.161 + if (!c) 1.162 + { 1.163 + if (!array) 1.164 + { 1.165 + array = new T[1]; 1.166 + allocated = 1; 1.167 + used = 1; 1.168 + } 1.169 + array[0] = 0x0; 1.170 + return *this; 1.171 + } 1.172 + 1.173 + if ((void*)c == (void*)array) 1.174 + return *this; 1.175 + 1.176 + s32 len = 0; 1.177 + const B* p = c; 1.178 + while(*p) 1.179 + { 1.180 + ++len; 1.181 + ++p; 1.182 + } 1.183 + 1.184 + // we'll take the old string for a while, because the new string could be 1.185 + // a part of the current string. 1.186 + T* oldArray = array; 1.187 + 1.188 + allocated = used = len+1; 1.189 + array = new T[used]; 1.190 + 1.191 + for (s32 l = 0; l<len+1; ++l) 1.192 + array[l] = (T)c[l]; 1.193 + 1.194 + delete [] oldArray; 1.195 + return *this; 1.196 + } 1.197 + 1.198 + //! Add operator for other strings 1.199 + string<T> operator+(const string<T>& other) 1.200 + { 1.201 + string<T> str(*this); 1.202 + str.append(other); 1.203 + 1.204 + return str; 1.205 + } 1.206 + 1.207 + //! Add operator for strings, ascii and unicode 1.208 + template <class B> 1.209 + string<T> operator+(const B* c) 1.210 + { 1.211 + string<T> str(*this); 1.212 + str.append(c); 1.213 + 1.214 + return str; 1.215 + } 1.216 + 1.217 + 1.218 + 1.219 + //! Direct access operator 1.220 + T& operator [](const s32 index) const 1.221 + { 1.222 + _IRR_DEBUG_BREAK_IF(index>=used) // bad index 1.223 + 1.224 + return array[index]; 1.225 + } 1.226 + 1.227 + 1.228 + //! Comparison operator 1.229 + bool operator ==(const T* str) const 1.230 + { 1.231 + int i; 1.232 + for(i=0; array[i] && str[i]; ++i) 1.233 + if (array[i] != str[i]) 1.234 + return false; 1.235 + 1.236 + return !array[i] && !str[i]; 1.237 + } 1.238 + 1.239 + 1.240 + 1.241 + //! Comparison operator 1.242 + bool operator ==(const string<T>& other) const 1.243 + { 1.244 + for(s32 i=0; array[i] && other.array[i]; ++i) 1.245 + if (array[i] != other.array[i]) 1.246 + return false; 1.247 + 1.248 + return used == other.used; 1.249 + } 1.250 + 1.251 + 1.252 + 1.253 + //! Is smaller operator 1.254 + bool operator <(const string<T>& other) const 1.255 + { 1.256 + for(s32 i=0; array[i] && other.array[i]; ++i) 1.257 + if (array[i] != other.array[i]) 1.258 + return (array[i] < other.array[i]); 1.259 + 1.260 + return used < other.used; 1.261 + } 1.262 + 1.263 + 1.264 + 1.265 + //! Equals not operator 1.266 + bool operator !=(const string<T>& other) const 1.267 + { 1.268 + return !(*this == other); 1.269 + } 1.270 + 1.271 + 1.272 + 1.273 + //! Returns length of string 1.274 + /** \return Returns length of the string in characters. */ 1.275 + s32 size() const 1.276 + { 1.277 + return used-1; 1.278 + } 1.279 + 1.280 + 1.281 + 1.282 + //! Returns character string 1.283 + /** \return Returns pointer to C-style zero terminated string. */ 1.284 + const T* c_str() const 1.285 + { 1.286 + return array; 1.287 + } 1.288 + 1.289 + 1.290 + 1.291 + //! Makes the string lower case. 1.292 + void make_lower() 1.293 + { 1.294 + const T A = (T)'A'; 1.295 + const T Z = (T)'Z'; 1.296 + const T diff = (T)'a' - A; 1.297 + 1.298 + for (s32 i=0; i<used; ++i) 1.299 + { 1.300 + if (array[i]>=A && array[i]<=Z) 1.301 + array[i] += diff; 1.302 + } 1.303 + } 1.304 + 1.305 + 1.306 + 1.307 + //! Makes the string upper case. 1.308 + void make_upper() 1.309 + { 1.310 + const T a = (T)'a'; 1.311 + const T z = (T)'z'; 1.312 + const T diff = (T)'A' - a; 1.313 + 1.314 + for (s32 i=0; i<used; ++i) 1.315 + { 1.316 + if (array[i]>=a && array[i]<=z) 1.317 + array[i] += diff; 1.318 + } 1.319 + } 1.320 + 1.321 + 1.322 + 1.323 + //! Compares the string ignoring case. 1.324 + /** \param other: Other string to compare. 1.325 + \return Returns true if the string are equal ignoring case. */ 1.326 + bool equals_ignore_case(const string<T>& other) const 1.327 + { 1.328 + for(s32 i=0; array[i] && other[i]; ++i) 1.329 + if (toLower(array[i]) != toLower(other[i])) 1.330 + return false; 1.331 + 1.332 + return used == other.used; 1.333 + } 1.334 + 1.335 + 1.336 + //! compares the first n characters of the strings 1.337 + bool equalsn(const string<T>& other, int len) 1.338 + { 1.339 + int i; 1.340 + for(i=0; array[i] && other[i] && i < len; ++i) 1.341 + if (array[i] != other[i]) 1.342 + return false; 1.343 + 1.344 + // if one (or both) of the strings was smaller then they 1.345 + // are only equal if they have the same lenght 1.346 + return (i == len) || (used == other.used); 1.347 + } 1.348 + 1.349 + 1.350 + //! compares the first n characters of the strings 1.351 + bool equalsn(const T* str, int len) 1.352 + { 1.353 + int i; 1.354 + for(i=0; array[i] && str[i] && i < len; ++i) 1.355 + if (array[i] != str[i]) 1.356 + return false; 1.357 + 1.358 + // if one (or both) of the strings was smaller then they 1.359 + // are only equal if they have the same lenght 1.360 + return (i == len) || (array[i] == 0 && str[i] == 0); 1.361 + } 1.362 + 1.363 + 1.364 + //! Appends a character to this string 1.365 + /** \param character: Character to append. */ 1.366 + void append(T character) 1.367 + { 1.368 + if (used + 1 > allocated) 1.369 + reallocate((s32)used + 1); 1.370 + 1.371 + used += 1; 1.372 + 1.373 + array[used-2] = character; 1.374 + array[used-1] = 0; 1.375 + } 1.376 + 1.377 + //! Appends a string to this string 1.378 + /** \param other: String to append. */ 1.379 + void append(const string<T>& other) 1.380 + { 1.381 + --used; 1.382 + 1.383 + s32 len = other.size(); 1.384 + 1.385 + if (used + len + 1 > allocated) 1.386 + reallocate((s32)used + (s32)len + 1); 1.387 + 1.388 + for (s32 l=0; l<len+1; ++l) 1.389 + array[l+used] = other[l]; 1.390 + 1.391 + used = used + len + 1; 1.392 + } 1.393 + 1.394 + 1.395 + //! Appends a string of the length l to this string. 1.396 + /** \param other: other String to append to this string. 1.397 + \param length: How much characters of the other string to add to this one. */ 1.398 + void append(const string<T>& other, s32 length) 1.399 + { 1.400 + s32 len = other.size(); 1.401 + 1.402 + if (len < length) 1.403 + { 1.404 + append(other); 1.405 + return; 1.406 + } 1.407 + 1.408 + len = length; 1.409 + --used; 1.410 + 1.411 + if (used + len > allocated) 1.412 + reallocate((s32)used + (s32)len); 1.413 + 1.414 + for (s32 l=0; l<len; ++l) 1.415 + array[l+used] = other[l]; 1.416 + 1.417 + used = used + len; 1.418 + } 1.419 + 1.420 + 1.421 + //! Reserves some memory. 1.422 + /** \param count: Amount of characters to reserve. */ 1.423 + void reserve(s32 count) 1.424 + { 1.425 + if (count < allocated) 1.426 + return; 1.427 + 1.428 + reallocate(count); 1.429 + } 1.430 + 1.431 + 1.432 + //! finds first occurrence of character in string 1.433 + /** \param c: Character to search for. 1.434 + \return Returns position where the character has been found, 1.435 + or -1 if not found. */ 1.436 + s32 findFirst(T c) const 1.437 + { 1.438 + for (s32 i=0; i<used; ++i) 1.439 + if (array[i] == c) 1.440 + return i; 1.441 + 1.442 + return -1; 1.443 + } 1.444 + 1.445 + //! finds first occurrence of a character of a list in string 1.446 + /** \param c: List of strings to find. For example if the method 1.447 + should find the first occurance of 'a' or 'b', this parameter should be "ab". 1.448 + \param count: Amount of characters in the list. Ususally, 1.449 + this should be strlen(ofParameter1) 1.450 + \return Returns position where one of the character has been found, 1.451 + or -1 if not found. */ 1.452 + s32 findFirstChar(T* c, int count) const 1.453 + { 1.454 + for (s32 i=0; i<used; ++i) 1.455 + for (int j=0; j<count; ++j) 1.456 + if (array[i] == c[j]) 1.457 + return i; 1.458 + 1.459 + return -1; 1.460 + } 1.461 + 1.462 + 1.463 + //! Finds first position of a character not in a given list. 1.464 + /** \param c: List of characters not to find. For example if the method 1.465 + should find the first occurance of a character not 'a' or 'b', this parameter should be "ab". 1.466 + \param count: Amount of characters in the list. Ususally, 1.467 + this should be strlen(ofParameter1) 1.468 + \return Returns position where the character has been found, 1.469 + or -1 if not found. */ 1.470 + template <class B> 1.471 + s32 findFirstCharNotInList(B* c, int count) const 1.472 + { 1.473 + for (int i=0; i<used; ++i) 1.474 + { 1.475 + int j; 1.476 + for (j=0; j<count; ++j) 1.477 + if (array[i] == c[j]) 1.478 + break; 1.479 + 1.480 + if (j==count) 1.481 + return i; 1.482 + } 1.483 + 1.484 + return -1; 1.485 + } 1.486 + 1.487 + //! Finds last position of a character not in a given list. 1.488 + /** \param c: List of characters not to find. For example if the method 1.489 + should find the first occurance of a character not 'a' or 'b', this parameter should be "ab". 1.490 + \param count: Amount of characters in the list. Ususally, 1.491 + this should be strlen(ofParameter1) 1.492 + \return Returns position where the character has been found, 1.493 + or -1 if not found. */ 1.494 + template <class B> 1.495 + s32 findLastCharNotInList(B* c, int count) const 1.496 + { 1.497 + for (int i=used-2; i>=0; --i) 1.498 + { 1.499 + int j; 1.500 + for (j=0; j<count; ++j) 1.501 + if (array[i] == c[j]) 1.502 + break; 1.503 + 1.504 + if (j==count) 1.505 + return i; 1.506 + } 1.507 + 1.508 + return -1; 1.509 + } 1.510 + 1.511 + //! finds next occurrence of character in string 1.512 + /** \param c: Character to search for. 1.513 + \param startPos: Position in string to start searching. 1.514 + \return Returns position where the character has been found, 1.515 + or -1 if not found. */ 1.516 + s32 findNext(T c, s32 startPos) const 1.517 + { 1.518 + for (s32 i=startPos; i<used; ++i) 1.519 + if (array[i] == c) 1.520 + return i; 1.521 + 1.522 + return -1; 1.523 + } 1.524 + 1.525 + 1.526 + //! finds last occurrence of character in string 1.527 + //! \param c: Character to search for. 1.528 + //! \return Returns position where the character has been found, 1.529 + //! or -1 if not found. 1.530 + s32 findLast(T c) const 1.531 + { 1.532 + for (s32 i=used-1; i>=0; --i) 1.533 + if (array[i] == c) 1.534 + return i; 1.535 + 1.536 + return -1; 1.537 + } 1.538 + 1.539 + 1.540 + //! Returns a substring 1.541 + //! \param begin: Start of substring. 1.542 + //! \param length: Length of substring. 1.543 + string<T> subString(s32 begin, s32 length) 1.544 + { 1.545 + if (length <= 0) 1.546 + return string<T>(""); 1.547 + 1.548 + string<T> o; 1.549 + o.reserve(length+1); 1.550 + 1.551 + for (s32 i=0; i<length; ++i) 1.552 + o.array[i] = array[i+begin]; 1.553 + 1.554 + o.array[length] = 0; 1.555 + o.used = o.allocated; 1.556 + 1.557 + return o; 1.558 + } 1.559 + 1.560 + 1.561 + void operator += (T c) 1.562 + { 1.563 + append(c); 1.564 + } 1.565 + 1.566 + void operator += (const string<T>& other) 1.567 + { 1.568 + append(other); 1.569 + } 1.570 + 1.571 + void operator += (int i) 1.572 + { 1.573 + append(string<T>(i)); 1.574 + } 1.575 + 1.576 + //! replaces all characters of a special type with another one 1.577 + void replace(T toReplace, T replaceWith) 1.578 + { 1.579 + for (s32 i=0; i<used; ++i) 1.580 + if (array[i] == toReplace) 1.581 + array[i] = replaceWith; 1.582 + } 1.583 + 1.584 + //! trims the string. 1.585 + /** Removes whitespace from begin and end of the string. */ 1.586 + void trim() 1.587 + { 1.588 + const char whitespace[] = " \t\n"; 1.589 + const int whitespacecount = 3; 1.590 + 1.591 + // find start and end of real string without whitespace 1.592 + int begin = findFirstCharNotInList(whitespace, whitespacecount); 1.593 + if (begin == -1) 1.594 + return; 1.595 + 1.596 + int end = findLastCharNotInList(whitespace, whitespacecount); 1.597 + if (end == -1) 1.598 + return; 1.599 + 1.600 + *this = subString(begin, (end +1) - begin); 1.601 + } 1.602 + 1.603 + 1.604 + //! Erases a character from the string. May be slow, because all elements 1.605 + //! following after the erased element have to be copied. 1.606 + //! \param index: Index of element to be erased. 1.607 + void erase(int index) 1.608 + { 1.609 + _IRR_DEBUG_BREAK_IF(index>=used || index<0) // access violation 1.610 + 1.611 + for (int i=index+1; i<used; ++i) 1.612 + array[i-1] = array[i]; 1.613 + 1.614 + --used; 1.615 + } 1.616 + 1.617 + 1.618 + 1.619 +private: 1.620 + 1.621 + //! Returns a character converted to lower case 1.622 + T toLower(const T& t) const 1.623 + { 1.624 + if (t>=(T)'A' && t<=(T)'Z') 1.625 + return t + ((T)'a' - (T)'A'); 1.626 + else 1.627 + return t; 1.628 + } 1.629 + 1.630 + //! Reallocate the array, make it bigger or smaler 1.631 + void reallocate(s32 new_size) 1.632 + { 1.633 + T* old_array = array; 1.634 + 1.635 + array = new T[new_size]; 1.636 + allocated = new_size; 1.637 + 1.638 + s32 amount = used < new_size ? used : new_size; 1.639 + for (s32 i=0; i<amount; ++i) 1.640 + array[i] = old_array[i]; 1.641 + 1.642 + if (allocated < used) 1.643 + used = allocated; 1.644 + 1.645 + delete [] old_array; 1.646 + } 1.647 + 1.648 + 1.649 + //--- member variables 1.650 + 1.651 + T* array; 1.652 + s32 allocated; 1.653 + s32 used; 1.654 +}; 1.655 + 1.656 + 1.657 +//! Typedef for character strings 1.658 +typedef string<irr::c8> stringc; 1.659 + 1.660 +//! Typedef for wide character strings 1.661 +typedef string<wchar_t> stringw; 1.662 + 1.663 +} // end namespace core 1.664 +} // end namespace irr 1.665 + 1.666 +#endif 1.667 +