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 +