Home | History | Annotate | Download | only in Tools
      1 /******************************************************************************
      2 
      3  @File         PVRTString.cpp
      4 
      5  @Title        PVRTString
      6 
      7  @Version
      8 
      9  @Copyright    Copyright (c) Imagination Technologies Limited.
     10 
     11  @Platform     ANSI compatible
     12 
     13  @Description  A string class that can be used as drop-in replacement for
     14                std::string on platforms/compilers that don't provide a full C++
     15                standard library.
     16 
     17 ******************************************************************************/
     18 #include "PVRTString.h"
     19 
     20 #ifdef _USING_PVRTSTRING_
     21 
     22 #include <stdlib.h>
     23 #include <string.h>
     24 #include <stdarg.h>
     25 
     26 #include "PVRTGlobal.h"
     27 
     28 const size_t CPVRTString::npos = (size_t) -1;
     29 
     30 #if defined(_WIN32)
     31 #define vsnprintf _vsnprintf
     32 #define snprintf _snprintf
     33 #endif
     34 
     35 /*!***********************************************************************
     36 @Function			CPVRTString
     37 @Input				_Ptr	A string
     38 @Input				_Count	Length of _Ptr
     39 @Description		Constructor
     40 ************************************************************************/
     41 CPVRTString::CPVRTString(const char* _Ptr, size_t _Count) :
     42 m_pString(0), m_Capacity(0)
     43 {
     44 	if (_Count == npos)
     45 	{
     46 		if (_Ptr == NULL)
     47 		{
     48 			 assign(_Ptr, 0);
     49 		}
     50 		else
     51 		{
     52 			assign(_Ptr);
     53 		}
     54 	}
     55 	else
     56 		assign(_Ptr, _Count);
     57 }
     58 
     59 /*!***********************************************************************
     60 @Function			CPVRTString
     61 @Input				_Right	A string
     62 @Input				_Roff	Offset into _Right
     63 @Input				_Count	Number of chars from _Right to assign to the new string
     64 @Description		Constructor
     65 ************************************************************************/
     66 CPVRTString::CPVRTString(const CPVRTString& _Right, size_t _Roff, size_t _Count) :
     67 m_pString(0), m_Capacity(0)
     68 {
     69 	assign(_Right, _Roff, _Count);
     70 }
     71 
     72 /*!***********************************************************************
     73 @Function			CPVRTString
     74 @Input				_Count	Length of new string
     75 @Input				_Ch		A char to fill it with
     76 @Description		Constructor
     77 *************************************************************************/
     78 CPVRTString::CPVRTString(size_t _Count, char _Ch) :
     79 m_pString(0), m_Capacity(0)
     80 {
     81 	assign(_Count,_Ch);
     82 }
     83 
     84 /*!***********************************************************************
     85 @Function			CPVRTString
     86 @Input				_Ch	A char
     87 @Description		Constructor
     88 *************************************************************************/
     89 CPVRTString::CPVRTString(const char _Ch) :
     90 m_pString(0), m_Capacity(0)
     91 {
     92 	assign( 1, _Ch);
     93 }
     94 
     95 /*!***********************************************************************
     96 @Function			CPVRTString
     97 @Description		Constructor
     98 *************************************************************************/
     99 CPVRTString::CPVRTString() :
    100 m_Size(0), m_Capacity(1)
    101 {
    102 	m_pString = (char*)calloc(1, 1);
    103 }
    104 
    105 /*!***********************************************************************
    106 @Function			~CPVRTString
    107 @Description		Destructor
    108 *************************************************************************/
    109 CPVRTString::~CPVRTString()
    110 {
    111 	if (m_pString)
    112 	{
    113 		free(m_pString);
    114 		m_pString=NULL;
    115 	}
    116 }
    117 
    118 /*!***********************************************************************
    119 @Function			append
    120 @Input				_Ptr	A string
    121 @Returns			Updated string
    122 @Description		Appends a string
    123 *************************************************************************/
    124 CPVRTString& CPVRTString::append(const char* _Ptr)
    125 {
    126 	if (_Ptr==NULL)
    127 	{
    128 		return *this;
    129 	}
    130 	return append(_Ptr,strlen(_Ptr));
    131 }
    132 
    133 /*!***********************************************************************
    134 @Function			append
    135 @Input				_Ptr	A string
    136 @Input				_Count	String length
    137 @Returns			Updated string
    138 @Description		Appends a string of length _Count
    139 *************************************************************************/
    140 CPVRTString& CPVRTString::append(const char* _Ptr, size_t _Count)
    141 {
    142 	char* pString = m_pString;
    143 	size_t newCapacity = _Count + m_Size + 1;	// +1 for null termination
    144 
    145 	// extend CPVRTString if necessary
    146 	if (m_Capacity < newCapacity)
    147 	{
    148 		pString = (char*)malloc(newCapacity);
    149 		m_Capacity = newCapacity;				 // Using low memory profile (but very slow append)
    150 		memmove(pString, m_pString, m_Size);
    151 		pString[m_Capacity-1]='\0';
    152 	}
    153 
    154 	// append chars from _Ptr
    155 	memmove(pString + m_Size, _Ptr, _Count);
    156 	m_Size += _Count;
    157 	pString[m_Size] = 0;
    158 
    159 	// remove old CPVRTString if necessary
    160 	if (pString != m_pString)
    161 	{
    162 		if (m_pString)
    163 		{
    164 			free(m_pString);
    165 			m_pString=NULL;
    166 		}
    167 		m_pString = pString;
    168 	}
    169 	return *this;
    170 }
    171 
    172 /*!***********************************************************************
    173 @Function			append
    174 @Input				_Str	A string
    175 @Returns			Updated string
    176 @Description		Appends a string
    177 *************************************************************************/
    178 CPVRTString& CPVRTString::append(const CPVRTString& _Str)
    179 {
    180 	return append(_Str.m_pString,_Str.m_Size);
    181 }
    182 
    183 /*!***********************************************************************
    184 @Function			append
    185 @Input				_Str	A string
    186 @Input				_Off	A position in string
    187 @Input				_Count	Number of letters to append
    188 @Returns			Updated string
    189 @Description		Appends _Count letters of _Str from _Off in _Str
    190 *************************************************************************/
    191 CPVRTString& CPVRTString::append(const CPVRTString& _Str, size_t _Off, size_t _Count)
    192 {
    193 	if (_Str.length() < _Off + _Count)
    194 	{
    195 		int i32NewCount = (signed)(_Str.length())-(signed)_Off;
    196 
    197 		if(i32NewCount < 0 )
    198 		{
    199 			return *this;
    200 		}
    201 
    202 		_Count = (size_t) i32NewCount;
    203 	}
    204 
    205 	return append(_Str.m_pString+_Off,_Count);
    206 }
    207 
    208 /*!***********************************************************************
    209 @Function			append
    210 @Input				_Ch		A char
    211 @Input				_Count	Number of times to append _Ch
    212 @Returns			Updated string
    213 @Description		Appends _Ch _Count times
    214 *************************************************************************/
    215 CPVRTString& CPVRTString::append(size_t _Count, char _Ch)
    216 {
    217 	char* pString = m_pString;
    218 	size_t newCapacity = _Count + m_Size + 1;	// +1 for null termination
    219 	// extend CPVRTString if necessary
    220 	if (m_Capacity < newCapacity)
    221 	{
    222 		pString = (char*)malloc(newCapacity);
    223 		m_Capacity = newCapacity;
    224 		memmove(pString, m_pString, m_Size+1);
    225 	}
    226 
    227 	char* newChar = &pString[m_Size];
    228 	// fill new space with _Ch
    229 	for(size_t i=0;i<_Count;++i)
    230 	{
    231 		*newChar++ = _Ch;
    232 	}
    233 	*newChar = '\0';		// set null terminator
    234 	m_Size+=_Count;			// adjust length of string for new characters
    235 
    236 	// remove old CPVRTString if necessary
    237 	if (pString != m_pString)
    238 	{
    239 		if (m_pString)
    240 		{
    241 			free(m_pString);
    242 			m_pString=NULL;
    243 		}
    244 		m_pString = pString;
    245 	}
    246 	return *this;
    247 }
    248 
    249 /*!***********************************************************************
    250 @Function			assign
    251 @Input				_Ptr A string
    252 @Returns			Updated string
    253 @Description		Assigns the string to the string _Ptr
    254 *************************************************************************/
    255 CPVRTString& CPVRTString::assign(const char* _Ptr)
    256 {
    257 	if (_Ptr == NULL)
    258 	{
    259 		return assign(_Ptr, 0);
    260 	}
    261 	return assign(_Ptr, strlen(_Ptr));
    262 }
    263 
    264 /*!***********************************************************************
    265 @Function			assign
    266 @Input				_Ptr A string
    267 @Input				_Count Length of _Ptr
    268 @Returns			Updated string
    269 @Description		Assigns the string to the string _Ptr
    270 *************************************************************************/
    271 CPVRTString& CPVRTString::assign(const char* _Ptr, size_t _Count)
    272 {
    273 	if(m_Capacity <= _Count)
    274 	{
    275 		free(m_pString);
    276 		m_Capacity = _Count+1;
    277 		m_pString = (char*)malloc(m_Capacity);
    278 		memcpy(m_pString, _Ptr, _Count);
    279 	}
    280 	else
    281 		memmove(m_pString, _Ptr, _Count);
    282 
    283 	m_Size = _Count;
    284 	m_pString[m_Size] = 0;
    285 
    286 	return *this;
    287 }
    288 
    289 /*!***********************************************************************
    290 @Function			assign
    291 @Input				_Str A string
    292 @Returns			Updated string
    293 @Description		Assigns the string to the string _Str
    294 *************************************************************************/
    295 CPVRTString& CPVRTString::assign(const CPVRTString& _Str)
    296 {
    297 	return assign(_Str.m_pString, _Str.m_Size);
    298 }
    299 
    300 /*!***********************************************************************
    301 @Function			assign
    302 @Input				_Str A string
    303 @Input				_Off First char to start assignment from
    304 @Input				_Count Length of _Str
    305 @Returns			Updated string
    306 @Description		Assigns the string to _Count characters in string _Str starting at _Off
    307 *************************************************************************/
    308 CPVRTString& CPVRTString::assign(const CPVRTString& _Str, size_t _Off, size_t _Count)
    309 {
    310 	if(_Count==npos)
    311 	{
    312 		_Count = _Str.m_Size - _Off;
    313 	}
    314 	return assign(&_Str.m_pString[_Off], _Count);
    315 }
    316 
    317 /*!***********************************************************************
    318 @Function			assign
    319 @Input				_Ch A string
    320 @Input				_Count Number of times to repeat _Ch
    321 @Returns			Updated string
    322 @Description		Assigns the string to _Count copies of _Ch
    323 *************************************************************************/
    324 CPVRTString& CPVRTString::assign(size_t _Count,char _Ch)
    325 {
    326 	if (m_Capacity <= _Count)
    327 	{
    328 		if (m_pString)
    329 		{
    330 			free(m_pString);
    331 			m_pString=NULL;
    332 		}
    333 		m_pString = (char*)malloc(_Count + 1);
    334 		m_Capacity = _Count+1;
    335 	}
    336 	m_Size = _Count;
    337 	memset(m_pString, _Ch, _Count);
    338 	m_pString[m_Size] = 0;
    339 
    340 	return *this;
    341 }
    342 
    343 //const_reference at(size_t _Off) const;
    344 //reference at(size_t _Off);
    345 
    346 /*!***********************************************************************
    347 @Function			c_str
    348 @Returns			const char* pointer of the string
    349 @Description		Returns a const char* pointer of the string
    350 *************************************************************************/
    351 const char* CPVRTString::c_str() const
    352 {
    353 	return m_pString;
    354 }
    355 
    356 /*!***********************************************************************
    357 @Function			capacity
    358 @Returns			The size of the character array reserved
    359 @Description		Returns the size of the character array reserved
    360 *************************************************************************/
    361 size_t CPVRTString::capacity() const
    362 {
    363 	return m_Capacity;
    364 }
    365 
    366 /*!***********************************************************************
    367 @Function			clear
    368 @Description		Clears the string
    369 *************************************************************************/
    370 void CPVRTString::clear()
    371 {
    372 	if (m_pString)
    373 	{
    374 		free(m_pString);
    375 		m_pString=NULL;
    376 	}
    377 	m_pString = (char*)calloc(1, 1);
    378 	m_Size = 0;
    379 	m_Capacity = 1;
    380 }
    381 
    382 /*!***********************************************************************
    383 @Function			compare
    384 @Input				_Str A string to compare with
    385 @Returns			0 if the strings match
    386 @Description		Compares the string with _Str
    387 *************************************************************************/
    388 int CPVRTString::compare(const CPVRTString& _Str) const
    389 {
    390 	return strcmp(m_pString,_Str.m_pString);
    391 }
    392 
    393 /*!***********************************************************************
    394 @Function			<
    395 @Input				_Str A string to compare with
    396 @Returns			True on success
    397 @Description		Less than operator
    398 *************************************************************************/
    399 bool CPVRTString::operator<(const CPVRTString & _Str) const
    400 {
    401 	return (strcmp(m_pString, _Str.m_pString) < 0);
    402 }
    403 
    404 /*!***********************************************************************
    405 @Function			compare
    406 @Input				_Pos1	Position to start comparing from
    407 @Input				_Num1	Number of chars to compare
    408 @Input				_Str 	A string to compare with
    409 @Returns			0 if the strings match
    410 @Description		Compares the string with _Str
    411 *************************************************************************/
    412 int CPVRTString::compare(size_t _Pos1, size_t _Num1, const CPVRTString& _Str) const
    413 {
    414 	_ASSERT(_Pos1<=m_Size);	// check comparison starts within lhs CPVRTString
    415 
    416 	int i32Ret;	// value to return if no difference in actual comparisons between chars
    417 	size_t stLhsLength = m_Size-_Pos1;
    418 	size_t stSearchLength = PVRT_MIN(stLhsLength,PVRT_MIN(_Str.m_Size,_Num1));	// number of comparisons to do
    419 	if(PVRT_MIN(stLhsLength,_Num1)<PVRT_MIN(_Str.m_Size,_Num1))
    420 	{
    421 		i32Ret = -1;
    422 	}
    423 	else if(PVRT_MIN(stLhsLength,_Num1)>PVRT_MIN(_Str.m_Size,_Num1))
    424 	{
    425 		i32Ret = 1;
    426 	}
    427 	else
    428 	{
    429 		i32Ret = 0;
    430 	}
    431 
    432 	// do actual comparison
    433 	const char* lhptr = &m_pString[_Pos1];
    434 	const char* rhptr = _Str.m_pString;
    435 	for(size_t i=0;i<stSearchLength;++i)
    436 	{
    437 		if(*lhptr<*rhptr)
    438 			return -1;
    439 		else if (*lhptr>*rhptr)
    440 			return 1;
    441 		lhptr++;rhptr++;
    442 	}
    443 	// no difference found in compared characters
    444 	return i32Ret;
    445 }
    446 
    447 /*!***********************************************************************
    448 @Function			compare
    449 @Input				_Pos1	Position to start comparing from
    450 @Input				_Num1	Number of chars to compare
    451 @Input				_Str 	A string to compare with
    452 @Input				_Off 	Position in _Str to compare from
    453 @Input				_Count	Number of chars in _Str to compare with
    454 @Returns			0 if the strings match
    455 @Description		Compares the string with _Str
    456 *************************************************************************/
    457 int CPVRTString::compare(size_t _Pos1, size_t _Num1, const CPVRTString& _Str, size_t /*_Off*/, size_t _Count) const
    458 {
    459 	_ASSERT(_Pos1<=m_Size);	// check comparison starts within lhs CPVRTString
    460 
    461 	int i32Ret;	// value to return if no difference in actual comparisons between chars
    462 	size_t stLhsLength = m_Size-_Pos1;
    463 	size_t stSearchLength = PVRT_MIN(stLhsLength,PVRT_MIN(_Str.m_Size,PVRT_MIN(_Num1,_Count)));	// number of comparisons to do
    464 	if(PVRT_MIN(stLhsLength,_Num1)<PVRT_MIN(_Str.m_Size,_Count))
    465 	{
    466 		i32Ret = -1;
    467 	}
    468 	else if(PVRT_MIN(stLhsLength,_Num1)>PVRT_MIN(_Str.m_Size,_Count))
    469 	{
    470 		i32Ret = 1;
    471 	}
    472 	else
    473 	{
    474 		i32Ret = 0;
    475 	}
    476 
    477 
    478 	// do actual comparison
    479 	char* lhptr = &m_pString[_Pos1];
    480 	char* rhptr = _Str.m_pString;
    481 	for(size_t i=0;i<stSearchLength;++i)
    482 	{
    483 		if(*lhptr<*rhptr)
    484 			return -1;
    485 		else if (*lhptr>*rhptr)
    486 			return 1;
    487 		lhptr++;rhptr++;
    488 	}
    489 	// no difference found in compared characters
    490 	return i32Ret;
    491 }
    492 
    493 /*!***********************************************************************
    494 @Function			compare
    495 @Input				_Ptr A string to compare with
    496 @Returns			0 if the strings match
    497 @Description		Compares the string with _Ptr
    498 *************************************************************************/
    499 int CPVRTString::compare(const char* _Ptr) const
    500 {
    501 	return strcmp(m_pString,_Ptr);
    502 }
    503 
    504 /*!***********************************************************************
    505 @Function			compare
    506 @Input				_Pos1	Position to start comparing from
    507 @Input				_Num1	Number of chars to compare
    508 @Input				_Ptr 	A string to compare with
    509 @Returns			0 if the strings match
    510 @Description		Compares the string with _Ptr
    511 *************************************************************************/
    512 int CPVRTString::compare(size_t _Pos1, size_t _Num1, const char* _Ptr) const
    513 {
    514 	_ASSERT(_Pos1<=m_Size);	// check comparison starts within lhs CPVRTString
    515 
    516 	int i32Ret;	// value to return if no difference in actual comparisons between chars
    517 	size_t stLhsLength = m_Size-_Pos1;
    518 	size_t stRhsLength = strlen(_Ptr);
    519 	size_t stSearchLength = PVRT_MIN(stLhsLength,PVRT_MIN(stRhsLength,_Num1));	// number of comparisons to do
    520 	if(PVRT_MIN(stLhsLength,_Num1)<PVRT_MIN(stRhsLength,_Num1))
    521 	{
    522 		i32Ret = -1;
    523 	}
    524 	else if(PVRT_MIN(stLhsLength,_Num1)>PVRT_MIN(stRhsLength,_Num1))
    525 	{
    526 		i32Ret = 1;
    527 	}
    528 	else
    529 	{
    530 		i32Ret = 0;
    531 	}
    532 
    533 	// do actual comparison
    534 	const char* lhptr = &m_pString[_Pos1];
    535 	const char* rhptr = _Ptr;
    536 	for(size_t i=0;i<stSearchLength;++i)
    537 	{
    538 		if(*lhptr<*rhptr)
    539 			return -1;
    540 		else if (*lhptr>*rhptr)
    541 			return 1;
    542 		lhptr++;rhptr++;
    543 	}
    544 	// no difference found in compared characters
    545 	return i32Ret;
    546 }
    547 
    548 /*!***********************************************************************
    549 @Function			compare
    550 @Input				_Pos1	Position to start comparing from
    551 @Input				_Num1	Number of chars to compare
    552 @Input				_Ptr 	A string to compare with
    553 @Input				_Count	Number of char to compare
    554 @Returns			0 if the strings match
    555 @Description		Compares the string with _Str
    556 *************************************************************************/
    557 int CPVRTString::compare(size_t _Pos1, size_t _Num1, const char* _Ptr, size_t _Count) const
    558 {
    559 	_ASSERT(_Pos1<=m_Size);	// check comparison starts within lhs CPVRTString
    560 
    561 	int i32Ret;	// value to return if no difference in actual comparisons between chars
    562 	size_t stLhsLength = m_Size-_Pos1;
    563 	size_t stRhsLength = strlen(_Ptr);
    564 	size_t stSearchLength = PVRT_MIN(stLhsLength,PVRT_MIN(stRhsLength,PVRT_MIN(_Num1,_Count)));	// number of comparisons to do
    565 	if(PVRT_MIN(stLhsLength,_Num1)<PVRT_MIN(stRhsLength,_Count))
    566 	{
    567 		i32Ret = -1;
    568 	}
    569 	else if(PVRT_MIN(stLhsLength,_Num1)>PVRT_MIN(stRhsLength,_Count))
    570 	{
    571 		i32Ret = 1;
    572 	}
    573 	else
    574 	{
    575 		i32Ret = 0;
    576 	}
    577 
    578 
    579 	// do actual comparison
    580 	char* lhptr = &m_pString[_Pos1];
    581 	const char* rhptr = _Ptr;
    582 	for(size_t i=0;i<stSearchLength;++i)
    583 	{
    584 		if(*lhptr<*rhptr)
    585 			return -1;
    586 		else if (*lhptr>*rhptr)
    587 			return 1;
    588 		lhptr++;rhptr++;
    589 	}
    590 	// no difference found in compared characters
    591 	return i32Ret;
    592 }
    593 
    594 /*!***********************************************************************
    595 @Function			==
    596 @Input				_Str 	A string to compare with
    597 @Returns			True if they match
    598 @Description		== Operator
    599 *************************************************************************/
    600 bool CPVRTString::operator==(const CPVRTString& _Str) const
    601 {
    602 	return strcmp(m_pString, _Str.m_pString)==0;
    603 }
    604 
    605 /*!***********************************************************************
    606 @Function			==
    607 @Input				_Ptr 	A string to compare with
    608 @Returns			True if they match
    609 @Description		== Operator
    610 *************************************************************************/
    611 bool CPVRTString::operator==(const char* const _Ptr) const
    612 {
    613 	if(!_Ptr)
    614 		return false;
    615 
    616 	return strcmp(m_pString, _Ptr)==0;
    617 }
    618 
    619 /*!***********************************************************************
    620 @Function			!=
    621 @Input				_Str 	A string to compare with
    622 @Returns			True if they don't match
    623 @Description		!= Operator
    624 *************************************************************************/
    625 bool CPVRTString::operator!=(const CPVRTString& _Str) const
    626 {
    627 	return strcmp(m_pString, _Str.m_pString)!=0;
    628 }
    629 
    630 /*!***********************************************************************
    631 @Function			!=
    632 @Input				_Ptr 	A string to compare with
    633 @Returns			True if they don't match
    634 @Description		!= Operator
    635 *************************************************************************/
    636 bool CPVRTString::operator!=(const char* const _Ptr) const
    637 {
    638 	if(!_Ptr)
    639 		return true;
    640 
    641 	return strcmp(m_pString, _Ptr)!=0;
    642 }
    643 
    644 /*!***********************************************************************
    645 @Function			copy
    646 @Modified			_Ptr 	A string to copy to
    647 @Input				_Count	Size of _Ptr
    648 @Input				_Off	Position to start copying from
    649 @Returns			Number of bytes copied
    650 @Description		Copies the string to _Ptr
    651 *************************************************************************/
    652 size_t CPVRTString::copy(char* _Ptr, size_t _Count, size_t _Off) const
    653 {
    654 	if(memcpy(_Ptr, &m_pString[_Off], PVRT_MIN(_Count, m_Size - _Off)))
    655 		return _Count;
    656 
    657 	return 0;
    658 }
    659 
    660 /*!***********************************************************************
    661 @Function			data
    662 @Returns			A const char* version of the string
    663 @Description		Returns a const char* version of the string
    664 *************************************************************************/
    665 const char* CPVRTString::data() const
    666 {
    667 	return m_pString;
    668 }
    669 
    670 /*!***********************************************************************
    671 @Function			empty
    672 @Returns			True if the string is empty
    673 @Description		Returns true if the string is empty
    674 *************************************************************************/
    675 bool CPVRTString::empty() const
    676 {
    677 	return (m_Size == 0);
    678 }
    679 
    680 /*!***********************************************************************
    681 @Function			erase
    682 @Input				_Pos	The position to start erasing from
    683 @Input				_Count	Number of chars to erase
    684 @Returns			An updated string
    685 @Description		Erases a portion of the string
    686 *************************************************************************/
    687 CPVRTString& CPVRTString::erase(size_t _Pos, size_t _Count)
    688 {
    689 	if (_Count == npos || _Pos + _Count >= m_Size)
    690 	{
    691 		resize(_Pos, 0);
    692 	}
    693 	else
    694 	{
    695 		memmove(&m_pString[_Pos], &m_pString[_Pos + _Count], m_Size + 1 - (_Pos + _Count));
    696 	}
    697 	return *this;
    698 }
    699 
    700 /*!***********************************************************************
    701 @Function			find
    702 @Input				_Ptr	String to search.
    703 @Input				_Off	Offset to search from.
    704 @Input				_Count	Number of characters in this string.
    705 @Returns			Position of the first matched string.
    706 @Description		Finds a substring within this string.
    707 *************************************************************************/
    708 size_t CPVRTString::find(const char* _Ptr, size_t _Off, size_t _Count) const
    709 {
    710 	if(!_Ptr)
    711 		return npos;
    712 
    713 	if(_Count > m_Size)
    714 		return npos;
    715 
    716 	while(_Off < m_Size)
    717 	{
    718 		if(_Ptr[0] == m_pString[_Off])
    719 		{
    720 			if(compare(_Off, _Count, _Ptr) == 0)
    721 				return _Off;
    722 		}
    723 		_Off++;
    724 	}
    725 
    726 	return npos;
    727 }
    728 
    729 /*!***********************************************************************
    730 @Function			find
    731 @Input				_Str	String to search.
    732 @Input				_Off	Offset to search from.
    733 @Returns			Position of the first matched string.
    734 @Description		Erases a portion of the string
    735 *************************************************************************/
    736 size_t CPVRTString::find(const CPVRTString& _Str, size_t _Off) const
    737 {
    738 	return find(_Str.c_str(), _Off, _Str.length());
    739 }
    740 
    741 /*!***********************************************************************
    742 @Function			find_first_not_of
    743 @Input				_Ch		A char
    744 @Input				_Off	Start position of the find
    745 @Returns			Position of the first char that is not _Ch
    746 @Description		Returns the position of the first char that is not _Ch
    747 *************************************************************************/
    748 size_t CPVRTString::find_first_not_of(char _Ch, size_t _Off) const
    749 {
    750 	for(size_t i=_Off;i<m_Size;++i)
    751 	{
    752 		if(m_pString[i]!=_Ch)
    753 			return i;
    754 	}
    755 	return npos;
    756 }
    757 
    758 /*!***********************************************************************
    759 @Function			find_first_not_of
    760 @Input				_Ptr	A string
    761 @Input				_Off	Start position of the find
    762 @Returns			Position of the first char that is not in _Ptr
    763 @Description		Returns the position of the first char that is not in _Ptr
    764 *************************************************************************/
    765 size_t CPVRTString::find_first_not_of(const char* _Ptr, size_t _Off) const
    766 {
    767 	for(size_t i=_Off;i<m_Size;++i)
    768 	{
    769 		bool bFound = false;
    770 		// compare against each char from _Ptr
    771 		for(size_t j=0;_Ptr[j]!=0;++j)
    772 		{
    773 			bFound = bFound || (m_pString[i]==_Ptr[j]);
    774 		}
    775 		if(!bFound)
    776 		{	// return if no match
    777 			return i;
    778 		}
    779 	}
    780 	return npos;
    781 }
    782 
    783 /*!***********************************************************************
    784 @Function			find_first_not_of
    785 @Input				_Ptr	A string
    786 @Input				_Off	Start position of the find
    787 @Input				_Count	Number of chars in _Ptr
    788 @Returns			Position of the first char that is not in _Ptr
    789 @Description		Returns the position of the first char that is not in _Ptr
    790 *************************************************************************/
    791 size_t CPVRTString::find_first_not_of(const char* _Ptr, size_t _Off, size_t _Count) const
    792 {
    793 	for(size_t i=_Off;i<m_Size;++i)
    794 	{
    795 		bool bFound = false;
    796 		// compare against each char from _Ptr
    797 		for(size_t j=0;j<_Count;++j)
    798 		{
    799 			bFound = bFound || (m_pString[i]==_Ptr[j]);
    800 		}
    801 		if(!bFound)
    802 		{	// return if no match
    803 			return i;
    804 		}
    805 	}
    806 	return npos;
    807 }
    808 
    809 /*!***********************************************************************
    810 @Function			find_first_not_of
    811 @Input				_Str	A string
    812 @Input				_Off	Start position of the find
    813 @Returns			Position of the first char that is not in _Str
    814 @Description		Returns the position of the first char that is not in _Str
    815 *************************************************************************/
    816 size_t CPVRTString::find_first_not_of(const CPVRTString& _Str, size_t _Off) const
    817 {
    818 	for(size_t i=_Off;i<m_Size;++i)
    819 	{
    820 		bool bFound = false;
    821 		// compare against each char from _Str
    822 		for(size_t j=0;j<_Str.m_Size;++j)
    823 		{
    824 			bFound = bFound || (m_pString[i]==_Str[j]);
    825 		}
    826 		if(!bFound)
    827 		{	// return if no match
    828 			return i;
    829 		}
    830 	}
    831 	return npos;
    832 }
    833 
    834 /*!***********************************************************************
    835 @Function			find_first_of
    836 @Input				_Ch		A char
    837 @Input				_Off	Start position of the find
    838 @Returns			Position of the first char that is _Ch
    839 @Description		Returns the position of the first char that is _Ch
    840 *************************************************************************/
    841 size_t CPVRTString::find_first_of(char _Ch, size_t _Off) const
    842 {
    843 	for(size_t i=_Off;i<m_Size;++i)
    844 	{
    845 		if(m_pString[i]==_Ch)
    846 			return i;
    847 	}
    848 	return npos;
    849 }
    850 
    851 /*!***********************************************************************
    852 @Function			find_first_of
    853 @Input				_Ptr	A string
    854 @Input				_Off	Start position of the find
    855 @Returns			Position of the first char that matches a char in _Ptr
    856 @Description		Returns the position of the first char that matches a char in _Ptr
    857 *************************************************************************/
    858 size_t CPVRTString::find_first_of(const char* _Ptr, size_t _Off) const
    859 {
    860 	for(size_t i=_Off;i<m_Size;++i)
    861 	{
    862 		// compare against each char from _Ptr
    863 		for(size_t j=0;_Ptr[j]!=0;++j)
    864 		{
    865 			if(m_pString[i]==_Ptr[j])
    866 				return i;
    867 		}
    868 	}
    869 	return npos;
    870 }
    871 
    872 /*!***********************************************************************
    873 @Function			find_first_of
    874 @Input				_Ptr	A string
    875 @Input				_Off	Start position of the find
    876 @Input				_Count	Size of _Ptr
    877 @Returns			Position of the first char that matches a char in _Ptr
    878 @Description		Returns the position of the first char that matches a char in _Ptr
    879 *************************************************************************/
    880 size_t CPVRTString::find_first_of(const char* _Ptr, size_t _Off, size_t _Count) const
    881 {
    882 	for(size_t i=_Off;i<m_Size;++i)
    883 	{
    884 		// compare against each char from _Ptr
    885 		for(size_t j=0;j<_Count;++j)
    886 		{
    887 			if(m_pString[i]==_Ptr[j])
    888 				return i;
    889 		}
    890 	}
    891 	return npos;
    892 }
    893 
    894 
    895 /*!***********************************************************************
    896 @Function			find_first_of
    897 @Input				_Ptr	A string
    898 @Input				_Off	Start position of the find
    899 @Input				_Count	Size of _Ptr
    900 @Returns			Position of the first char that matches a char in _Ptr
    901 @Description		Returns the position of the first char that matches a char in _Ptr
    902 *************************************************************************/
    903 size_t CPVRTString::find_first_ofn(const char* _Ptr, size_t _Off, size_t _Count) const
    904 {
    905 	if (_Ptr == NULL)
    906 	{
    907 		return npos;
    908 	}
    909 
    910 	if (strlen(m_pString) < _Count)
    911 	{
    912 	   return npos;
    913 	}
    914 
    915 	for(size_t i=_Off;i<m_Size;++i)
    916 	{
    917 		if (m_pString[i] ==_Ptr[0])
    918 		{
    919 			if (i+_Count-1>=m_Size)  // There are not enough caracters in current String
    920 			{
    921 				return npos;
    922 			}
    923 
    924 			bool compare = true;
    925 			for(size_t k=1;k<_Count;++k)
    926 			{
    927 				compare &= (m_pString[i+k] ==_Ptr[k]);
    928 			}
    929 			if (compare == true)
    930 			{
    931 				return i;
    932 			}
    933 		}
    934 	}
    935 	return npos;
    936 }
    937 
    938 /*!***********************************************************************
    939 @Function			find_first_of
    940 @Input				_Str	A string
    941 @Input				_Off	Start position of the find
    942 @Returns			Position of the first char that matches a char in _Str
    943 @Description		Returns the position of the first char that matches a char in _Str
    944 *************************************************************************/
    945 size_t CPVRTString::find_first_of(const CPVRTString& _Str, size_t _Off) const
    946 {
    947 	for(size_t i=_Off;i<m_Size;++i)
    948 	{
    949 		// compare against each char from _Ptr
    950 		for(size_t j=0;j<_Str.m_Size;++j)
    951 		{
    952 			if(m_pString[i]==_Str[j])
    953 				return i;
    954 		}
    955 	}
    956 	return npos;
    957 }
    958 
    959 /*!***********************************************************************
    960 @Function			find_last_not_of
    961 @Input				_Ch		A char
    962 @Input				_Off	Start position of the find
    963 @Returns			Position of the last char that is not _Ch
    964 @Description		Returns the position of the last char that is not _Ch
    965 *************************************************************************/
    966 size_t CPVRTString::find_last_not_of(char _Ch, size_t _Off) const
    967 {
    968 	for(size_t i=m_Size-_Off-1;i<m_Size;--i)
    969 	{
    970 		if(m_pString[i]!=_Ch)
    971 		{
    972 			return i;
    973 		}
    974 	}
    975 	return npos;
    976 }
    977 
    978 /*!***********************************************************************
    979 @Function			find_last_not_of
    980 @Input				_Ptr	A string
    981 @Input				_Off	Start position of the find
    982 @Returns			Position of the last char that is not in _Ptr
    983 @Description		Returns the position of the last char that is not in _Ptr
    984 *************************************************************************/
    985 size_t CPVRTString::find_last_not_of(const char* _Ptr, size_t _Off) const
    986 {
    987 	for(size_t i=m_Size-_Off-1;i<m_Size;--i)
    988 	{
    989 		bool bFound = true;
    990 		// compare against each char from _Ptr
    991 		for(size_t j=0;_Ptr[j]!=0;++j)
    992 		{
    993 			bFound = bFound && (m_pString[i]!=_Ptr[j]);
    994 		}
    995 		if(bFound)
    996 		{	// return if considered character differed from all characters from _Ptr
    997 			return i;
    998 		}
    999 	}
   1000 	return npos;
   1001 }
   1002 
   1003 /*!***********************************************************************
   1004 @Function			find_last_not_of
   1005 @Input				_Ptr	A string
   1006 @Input				_Off	Start position of the find
   1007 @Input				_Count	Length of _Ptr
   1008 @Returns			Position of the last char that is not in _Ptr
   1009 @Description		Returns the position of the last char that is not in _Ptr
   1010 *************************************************************************/
   1011 size_t CPVRTString::find_last_not_of(const char* _Ptr, size_t _Off, size_t _Count) const
   1012 {
   1013 	for(size_t i=m_Size-_Off-1;i<m_Size;--i)
   1014 	{
   1015 		bool bFound = true;
   1016 		// compare against each char from _Ptr
   1017 		for(size_t j=0;j<_Count;++j)
   1018 		{
   1019 			bFound = bFound && (m_pString[i]!=_Ptr[j]);
   1020 		}
   1021 		if(bFound)
   1022 		{
   1023 		    // return if considered character differed from all characters from _Ptr
   1024 			return i;
   1025 		}
   1026 	}
   1027 	return npos;
   1028 }
   1029 
   1030 /*!***********************************************************************
   1031 @Function			find_last_not_of
   1032 @Input				_Str	A string
   1033 @Input				_Off	Start position of the find
   1034 @Returns			Position of the last char that is not in _Str
   1035 @Description		Returns the position of the last char that is not in _Str
   1036 *************************************************************************/
   1037 size_t CPVRTString::find_last_not_of(const CPVRTString& _Str, size_t _Off) const
   1038 {
   1039 	for(size_t i=m_Size-_Off-1;i<m_Size;--i)
   1040 	{
   1041 		bool bFound = true;
   1042 		// compare against each char from _Ptr
   1043 		for(size_t j=0;j<_Str.m_Size;++j)
   1044 		{
   1045 			bFound = bFound && (m_pString[i]!=_Str[j]);
   1046 		}
   1047 		if(bFound)
   1048 		{
   1049             // return if considered character differed from all characters from _Ptr
   1050 			return i;
   1051 		}
   1052 	}
   1053 	return npos;
   1054 }
   1055 
   1056 /*!***********************************************************************
   1057 @Function			find_last_of
   1058 @Input				_Ch		A char
   1059 @Input				_Off	Start position of the find
   1060 @Returns			Position of the last char that is _Ch
   1061 @Description		Returns the position of the last char that is _Ch
   1062 *************************************************************************/
   1063 size_t CPVRTString::find_last_of(char _Ch, size_t _Off) const
   1064 {
   1065 	for(size_t i=m_Size-_Off-1;i<m_Size;--i)
   1066 	{
   1067 		if(m_pString[i]==_Ch)
   1068 		{
   1069 			return i;
   1070 		}
   1071 	}
   1072 	return npos;
   1073 }
   1074 
   1075 /*!***********************************************************************
   1076 @Function			find_last_of
   1077 @Input				_Ptr	A string
   1078 @Input				_Off	Start position of the find
   1079 @Returns			Position of the last char that is in _Ptr
   1080 @Description		Returns the position of the last char that is in _Ptr
   1081 *************************************************************************/
   1082 size_t CPVRTString::find_last_of(const char* _Ptr, size_t _Off) const
   1083 {
   1084 	for(size_t i=m_Size-_Off-1;i<m_Size;--i)
   1085 	{
   1086 		// compare against each char from _Ptr
   1087 		for(size_t j=0;_Ptr[j]!=0;++j)
   1088 		{
   1089 			if(m_pString[i]==_Ptr[j])
   1090 				return i;
   1091 		}
   1092 	}
   1093 	return npos;
   1094 }
   1095 
   1096 /*!***********************************************************************
   1097 @Function			find_last_of
   1098 @Input				_Ptr	A string
   1099 @Input				_Off	Start position of the find
   1100 @Input				_Count	Length of _Ptr
   1101 @Returns			Position of the last char that is in _Ptr
   1102 @Description		Returns the position of the last char that is in _Ptr
   1103 *************************************************************************/
   1104 size_t CPVRTString::find_last_of(const char* _Ptr, size_t _Off, size_t _Count) const
   1105 {
   1106 	for(size_t i=m_Size-_Off-1;i<m_Size;--i)
   1107 	{
   1108 		// compare against each char from _Ptr
   1109 		for(size_t j=0;j<_Count;++j)
   1110 		{
   1111 			if(m_pString[i]!=_Ptr[j])
   1112 				return i;
   1113 		}
   1114 	}
   1115 	return npos;
   1116 }
   1117 
   1118 /*!***********************************************************************
   1119 @Function			find_last_of
   1120 @Input				_Str	A string
   1121 @Input				_Off	Start position of the find
   1122 @Returns			Position of the last char that is in _Str
   1123 @Description		Returns the position of the last char that is in _Str
   1124 *************************************************************************/
   1125 size_t CPVRTString::find_last_of(const CPVRTString& _Str, size_t _Off) const
   1126 {
   1127 	for(size_t i=m_Size-_Off-1;i<m_Size;--i)
   1128 	{
   1129 		// compare against each char from _Str
   1130 		for(size_t j=0;j<_Str.m_Size;++j)
   1131 		{
   1132 			if(m_pString[i]!=_Str[j])
   1133 				return i;
   1134 		}
   1135 	}
   1136 	return npos;
   1137 }
   1138 
   1139 /*!***********************************************************************
   1140 @Function			find_number_of
   1141 @Input				_Ch		A char
   1142 @Input				_Off	Start position of the find
   1143 @Returns			Number of occurances of _Ch in the parent string.
   1144 @Description		Returns the number of occurances of _Ch in the parent string.
   1145 *************************************************************************/
   1146 size_t CPVRTString::find_number_of(char _Ch, size_t _Off) const
   1147 {
   1148 	size_t occurances=0;
   1149 	for(size_t i=_Off;i<m_Size;++i)
   1150 	{
   1151 		if(m_pString[i]==_Ch)
   1152 			occurances++;
   1153 	}
   1154 	return occurances;
   1155 }
   1156 
   1157 /*!***********************************************************************
   1158 @Function			find_number_of
   1159 @Input				_Ptr	A string
   1160 @Input				_Off	Start position of the find
   1161 @Returns			Number of occurances of _Ptr in the parent string.
   1162 @Description		Returns the number of occurances of _Ptr in the parent string.
   1163 *************************************************************************/
   1164 size_t CPVRTString::find_number_of(const char* _Ptr, size_t _Off) const
   1165 {
   1166 	size_t occurances=0;
   1167 	bool bNotHere=false;
   1168 	for(size_t i=_Off;i<m_Size;++i)
   1169 	{
   1170 		// compare against each char from _Ptr
   1171 		for(size_t j=0;_Ptr[j]!=0;++j)
   1172 		{
   1173 			if(i+j>m_Size || m_pString[i+j]!=_Ptr[j]) bNotHere=true;
   1174 			if(bNotHere) break;
   1175 		}
   1176 		if(!bNotHere) occurances++;
   1177 		else bNotHere = false;
   1178 	}
   1179 	return occurances;
   1180 }
   1181 
   1182 /*!***********************************************************************
   1183 @Function			find_number_of
   1184 @Input				_Ptr	A string
   1185 @Input				_Off	Start position of the find
   1186 @Input				_Count	Size of _Ptr
   1187 @Returns			Number of occurances of _Ptr in the parent string.
   1188 @Description		Returns the number of occurances of _Ptr in the parent string.
   1189 *************************************************************************/
   1190 size_t CPVRTString::find_number_of(const char* _Ptr, size_t _Off, size_t _Count) const
   1191 {
   1192 	size_t occurances=0;
   1193 	bool bNotHere=false;
   1194 	for(size_t i=_Off;i<m_Size;++i)
   1195 	{
   1196 		// compare against each char from _Ptr
   1197 		for(size_t j=0;j<_Count;++j)
   1198 		{
   1199 			if(i+j>m_Size || m_pString[i+j]!=_Ptr[j]) bNotHere=true;
   1200 			if(bNotHere) break;
   1201 		}
   1202 		if(!bNotHere) occurances++;
   1203 		else bNotHere = false;
   1204 	}
   1205 	return occurances;
   1206 }
   1207 
   1208 /*!***********************************************************************
   1209 @Function			find_number_of
   1210 @Input				_Str	A string
   1211 @Input				_Off	Start position of the find
   1212 @Returns			Number of occurances of _Str in the parent string.
   1213 @Description		Returns the number of occurances of _Str in the parent string.
   1214 *************************************************************************/
   1215 size_t CPVRTString::find_number_of(const CPVRTString& _Str, size_t _Off) const
   1216 {
   1217 	size_t occurances=0;
   1218 	bool bNotHere=false;
   1219 	for(size_t i=_Off;i<m_Size;++i)
   1220 	{
   1221 		// compare against each char from _Ptr
   1222 		for(size_t j=0;j<_Str.m_Size;++j)
   1223 		{
   1224 			if(i+j>m_Size || m_pString[i+j]!=_Str[j])
   1225 				bNotHere=true;
   1226 			if(bNotHere)
   1227 				break;
   1228 		}
   1229 		if(!bNotHere) occurances++;
   1230 		else bNotHere = false;
   1231 	}
   1232 	return occurances;
   1233 }
   1234 
   1235 /*!***********************************************************************
   1236 @Function			find_next_occurance_of
   1237 @Input				_Ch		A char
   1238 @Input				_Off	Start position of the find
   1239 @Returns			Next occurance of _Ch in the parent string.
   1240 @Description		Returns the next occurance of _Ch in the parent string
   1241 					after or at _Off.	If not found, returns the length of the string.
   1242 *************************************************************************/
   1243 int CPVRTString::find_next_occurance_of(char _Ch, size_t _Off) const
   1244 {
   1245 	for(size_t i=_Off;i<m_Size;++i)
   1246 	{
   1247 		if(m_pString[i]==_Ch)
   1248 			return (int)i;
   1249 	}
   1250 	return (int)m_Size;
   1251 }
   1252 
   1253 /*!***********************************************************************
   1254 @Function			find_next_occurance_of
   1255 @Input				_Ptr	A string
   1256 @Input				_Off	Start position of the find
   1257 @Returns			Next occurance of _Ptr in the parent string.
   1258 @Description		Returns the next occurance of _Ptr in the parent string
   1259 					after or at _Off.	If not found, returns the length of the string.
   1260 *************************************************************************/
   1261 int CPVRTString::find_next_occurance_of(const char* _Ptr, size_t _Off) const
   1262 {
   1263 	bool bHere=true;
   1264 	for(size_t i=_Off;i<m_Size;++i)
   1265 	{
   1266 		// compare against each char from _Ptr
   1267 		for(size_t j=0;_Ptr[j]!=0;++j)
   1268 		{
   1269 			if(i+j>m_Size || m_pString[i+j]!=_Ptr[j]) bHere=false;
   1270 			if(!bHere) break;
   1271 		}
   1272 		if(bHere) return (int)i;
   1273 		bHere=true;
   1274 	}
   1275 	return (int)m_Size;
   1276 }
   1277 
   1278 /*!***********************************************************************
   1279 @Function			find_next_occurance_of
   1280 @Input				_Ptr	A string
   1281 @Input				_Off	Start position of the find
   1282 @Input				_Count	Size of _Ptr
   1283 @Returns			Next occurance of _Ptr in the parent string.
   1284 @Description		Returns the next occurance of _Ptr in the parent string
   1285 					after or at _Off.	If not found, returns the length of the string.
   1286 *************************************************************************/
   1287 int CPVRTString::find_next_occurance_of(const char* _Ptr, size_t _Off, size_t _Count) const
   1288 {
   1289 	bool bHere=true;
   1290 	for(size_t i=_Off;i<m_Size;++i)
   1291 	{
   1292 		// compare against each char from _Ptr
   1293 		for(size_t j=0;j<_Count;++j)
   1294 		{
   1295 			if(i+j>m_Size || m_pString[i+j]!=_Ptr[j]) bHere=false;
   1296 			if(!bHere) break;
   1297 		}
   1298 		if(bHere) return (int)i;
   1299 		bHere=true;
   1300 	}
   1301 	return (int)m_Size;
   1302 }
   1303 
   1304 /*!***********************************************************************
   1305 @Function			find_next_occurance_of
   1306 @Input				_Str	A string
   1307 @Input				_Off	Start position of the find
   1308 @Returns			Next occurance of _Str in the parent string.
   1309 @Description		Returns the next occurance of _Str in the parent string
   1310 					after or at _Off.	If not found, returns the length of the string.
   1311 *************************************************************************/
   1312 int CPVRTString::find_next_occurance_of(const CPVRTString& _Str, size_t _Off) const
   1313 {
   1314 	bool bHere=true;
   1315 	for(size_t i=_Off;i<m_Size;++i)
   1316 	{
   1317 		// compare against each char from _Str
   1318 		for(size_t j=0;j<_Str.m_Size;++j)
   1319 		{
   1320 			if(i+j>m_Size || m_pString[i+j]!=_Str[j]) bHere=false;
   1321 			if(!bHere) break;
   1322 		}
   1323 		if(bHere) return (int)i;
   1324 		bHere=true;
   1325 	}
   1326 	return (int)m_Size;
   1327 }
   1328 
   1329 /*!***********************************************************************
   1330 @Function			find_previous_occurance_of
   1331 @Input				_Ch		A char
   1332 @Input				_Off	Start position of the find
   1333 @Returns			Previous occurance of _Ch in the parent string.
   1334 @Description		Returns the previous occurance of _Ch in the parent string
   1335 					before _Off.	If not found, returns -1.
   1336 *************************************************************************/
   1337 int CPVRTString::find_previous_occurance_of(char _Ch, size_t _Off) const
   1338 {
   1339 	for(size_t i=_Off;i>0;--i)
   1340 	{
   1341 		if(m_pString[i]==_Ch)
   1342 			return (int)i;
   1343 	}
   1344 	return -1;
   1345 }
   1346 
   1347 /*!***********************************************************************
   1348 @Function			find_previous_occurance_of
   1349 @Input				_Ptr	A string
   1350 @Input				_Off	Start position of the find
   1351 @Returns			Previous occurance of _Ptr in the parent string.
   1352 @Description		Returns the previous occurance of _Ptr in the parent string
   1353 					before _Off.	If not found, returns -1.
   1354 *************************************************************************/
   1355 int CPVRTString::find_previous_occurance_of(const char* _Ptr, size_t _Off) const
   1356 {
   1357 	bool bHere=true;
   1358 	for(size_t i=_Off;i>0;--i)
   1359 	{
   1360 		// compare against each char from _Ptr
   1361 		for(size_t j=0;_Ptr[j]!=0;++j)
   1362 		{
   1363 			if(i+j>m_Size || m_pString[i+j]!=_Ptr[j]) bHere=false;
   1364 			if(!bHere) break;
   1365 		}
   1366 		if(bHere) return (int)i;
   1367 		bHere=true;
   1368 	}
   1369 	return -1;
   1370 }
   1371 
   1372 /*!***********************************************************************
   1373 @Function			find_previous_occurance_of
   1374 @Input				_Ptr	A string
   1375 @Input				_Off	Start position of the find
   1376 @Input				_Count	Size of _Ptr
   1377 @Returns			Previous occurance of _Ptr in the parent string.
   1378 @Description		Returns the previous occurance of _Ptr in the parent string
   1379 					before _Off.	If not found, returns -1.
   1380 *************************************************************************/
   1381 int CPVRTString::find_previous_occurance_of(const char* _Ptr, size_t _Off, size_t _Count) const
   1382 {
   1383 	bool bHere=true;
   1384 	for(size_t i=_Off;i>0;--i)
   1385 	{
   1386 		// compare against each char from _Ptr
   1387 		for(size_t j=0;j<_Count;++j)
   1388 		{
   1389 			if(i+j>m_Size || m_pString[i+j]!=_Ptr[j]) bHere=false;
   1390 			if(!bHere) break;
   1391 		}
   1392 		if(bHere) return (int)i;
   1393 		bHere=true;
   1394 	}
   1395 	return -1;
   1396 }
   1397 
   1398 /*!***********************************************************************
   1399 @Function			find_previous_occurance_of
   1400 @Input				_Str	A string
   1401 @Input				_Off	Start position of the find
   1402 @Returns			Previous occurance of _Str in the parent string.
   1403 @Description		Returns the previous occurance of _Str in the parent string
   1404 					before _Off.	If not found, returns -1.
   1405 *************************************************************************/
   1406 int CPVRTString::find_previous_occurance_of(const CPVRTString& _Str, size_t _Off) const
   1407 {
   1408 	bool bHere=true;
   1409 	for(size_t i=_Off;i>0;--i)
   1410 	{
   1411 		// compare against each char from _Str
   1412 		for(size_t j=0;j<_Str.m_Size;++j)
   1413 		{
   1414 			if(i+j>m_Size || m_pString[i+j]!=_Str[j]) bHere=false;
   1415 			if(!bHere) break;
   1416 		}
   1417 		if(bHere) return (int)i;
   1418 		bHere=true;
   1419 	}
   1420 	return -1;
   1421 }
   1422 
   1423 /*!***********************************************************************
   1424 @Function			left
   1425 @Input				iSize	number of characters to return (excluding null character)
   1426 @Returns			The leftmost 'iSize' characters of the string.
   1427 @Description		Returns the leftmost characters of the string (excluding
   1428 					the null character) in a new CPVRTString. If iSize is
   1429 					larger than the string, a copy of the original string is returned.
   1430 *************************************************************************/
   1431 CPVRTString CPVRTString::left(size_t iSize) const
   1432 {
   1433 	if(iSize>=m_Size) return *this;
   1434 	return CPVRTString(m_pString,iSize);
   1435 }
   1436 
   1437 /*!***********************************************************************
   1438 @Function			right
   1439 @Input				iSize	number of characters to return (excluding null character)
   1440 @Returns			The rightmost 'iSize' characters of the string.
   1441 @Description		Returns the rightmost characters of the string (excluding
   1442 					the null character) in a new CPVRTString. If iSize is
   1443 					larger than the string, a copy of the original string is returned.
   1444 *************************************************************************/
   1445 CPVRTString CPVRTString::right(size_t iSize) const
   1446 {
   1447 	if(iSize>=m_Size) return *this;
   1448 	return CPVRTString(m_pString+(m_Size-iSize),iSize);
   1449 }
   1450 
   1451 //CPVRTString& CPVRTString::insert(size_t _P0, const char* _Ptr)
   1452 //{
   1453 //	return replace(_P0, 0, _Ptr);
   1454 //}
   1455 
   1456 //CPVRTString& CPVRTString::insert(size_t _P0, const char* _Ptr, size_t _Count)
   1457 //{
   1458 //	return replace(_P0, 0, _Ptr, _Count);
   1459 //}
   1460 
   1461 //CPVRTString& CPVRTString::insert(size_t _P0, const CPVRTString& _Str)
   1462 //{
   1463 //	return replace(_P0, 0, _Str);
   1464 //}
   1465 
   1466 //CPVRTString& CPVRTString::insert(size_t _P0, const CPVRTString& _Str, size_t _Off, size_t _Count)
   1467 //{
   1468 //	return replace(_P0, 0, _Str, _Off, _Count);
   1469 //}
   1470 
   1471 //CPVRTString& CPVRTString::insert(size_t _P0, size_t _Count, char _Ch)
   1472 //{
   1473 //	return replace(_P0, 0, _Count, _Ch);
   1474 //}
   1475 
   1476 /*!***********************************************************************
   1477 @Function			length
   1478 @Returns			Length of the string
   1479 @Description		Returns the length of the string
   1480 *************************************************************************/
   1481 size_t CPVRTString::length() const
   1482 {
   1483 	return m_Size;
   1484 }
   1485 
   1486 /*!***********************************************************************
   1487 @Function			max_size
   1488 @Returns			The maximum number of chars that the string can contain
   1489 @Description		Returns the maximum number of chars that the string can contain
   1490 *************************************************************************/
   1491 size_t CPVRTString::max_size() const
   1492 {
   1493 	return 0x7FFFFFFF;
   1494 }
   1495 
   1496 /*!***********************************************************************
   1497 @Function			push_back
   1498 @Input				_Ch A char to append
   1499 @Description		Appends _Ch to the string
   1500 *************************************************************************/
   1501 void CPVRTString::push_back(char _Ch)
   1502 {
   1503 	append(1, _Ch);
   1504 }
   1505 
   1506 //CPVRTString& replace(size_t _Pos1, size_t _Num1, const char* _Ptr)
   1507 //CPVRTString& replace(size_t _Pos1, size_t _Num1, const CPVRTString& _Str)
   1508 //CPVRTString& replace(size_t _Pos1, size_t _Num1, const char* _Ptr, size_t _Num2)
   1509 //CPVRTString& replace(size_t _Pos1, size_t _Num1, const CPVRTString& _Str, size_t _Pos2, size_t _Num2)
   1510 //CPVRTString& replace(size_t _Pos1, size_t _Num1, size_t _Count, char _Ch)
   1511 
   1512 /*!***********************************************************************
   1513 @Function			reserve
   1514 @Input				_Count Size of string to reserve
   1515 @Description		Reserves space for _Count number of chars
   1516 *************************************************************************/
   1517 void CPVRTString::reserve(size_t _Count)
   1518 {
   1519 	if (_Count >= m_Capacity)
   1520 	{
   1521 		m_pString = (char*)realloc(m_pString, _Count + 1);
   1522 		m_Capacity = _Count + 1;
   1523 	}
   1524 }
   1525 
   1526 /*!***********************************************************************
   1527 @Function			resize
   1528 @Input				_Count 	Size of string to resize to
   1529 @Input				_Ch		Character to use to fill any additional space
   1530 @Description		Resizes the string to _Count in length
   1531 *************************************************************************/
   1532 void CPVRTString::resize(size_t _Count, char _Ch)
   1533 {
   1534 	if (_Count <= m_Size)
   1535 	{
   1536 		m_Size = _Count;
   1537 		m_pString[m_Size] = 0;
   1538 	}
   1539 	else
   1540 	{
   1541 		append(_Count - m_Size,_Ch);
   1542 	}
   1543 }
   1544 
   1545 //size_t rfind(char _Ch, size_t _Off = npos) const;
   1546 //size_t rfind(const char* _Ptr, size_t _Off = npos) const;
   1547 //size_t rfind(const char* _Ptr, size_t _Off = npos, size_t _Count) const;
   1548 //size_t rfind(const CPVRTString& _Str, size_t _Off = npos) const;
   1549 
   1550 /*!***********************************************************************
   1551 @Function			size
   1552 @Returns			Size of the string
   1553 @Description		Returns the size of the string
   1554 *************************************************************************/
   1555 size_t CPVRTString::size() const
   1556 {
   1557 	return m_Size;
   1558 }
   1559 
   1560 /*!***********************************************************************
   1561 @Function			substr
   1562 @Input				_Off	Start of the substring
   1563 @Input				_Count	Length of the substring
   1564 @Returns			A substring of the string
   1565 @Description		Returns the size of the string
   1566 *************************************************************************/
   1567 CPVRTString CPVRTString::substr(size_t _Off, size_t _Count) const
   1568 {
   1569 	return CPVRTString(*this, _Off, _Count);
   1570 }
   1571 
   1572 /*!***********************************************************************
   1573 @Function			swap
   1574 @Input				_Str	A string to swap with
   1575 @Description		Swaps the contents of the string with _Str
   1576 *************************************************************************/
   1577 void CPVRTString::swap(CPVRTString& _Str)
   1578 {
   1579 	size_t Size = _Str.m_Size;
   1580 	size_t Capacity = _Str.m_Capacity;
   1581 	char* pString = _Str.m_pString;
   1582 	_Str.m_Size = m_Size;
   1583 	_Str.m_Capacity = m_Capacity;
   1584 	_Str.m_pString = m_pString;
   1585 	m_Size = Size;
   1586 	m_Capacity = Capacity;
   1587 	m_pString = pString;
   1588 }
   1589 
   1590 /*!***********************************************************************
   1591 @Function			toLower
   1592 @Returns			An updated string
   1593 @Description		Converts the string to lower case
   1594 *************************************************************************/
   1595 CPVRTString&  CPVRTString::toLower()
   1596 {
   1597 	int i = 0;
   1598 	while ( (m_pString[i] = (m_pString[i]>='A'&&m_pString[i]<='Z') ? ('a'+m_pString[i])-'A': m_pString[i]) != 0) i++;
   1599 	return *this;
   1600 }
   1601 
   1602 /*!***********************************************************************
   1603 @Function			toUpper
   1604 @Returns			An updated string
   1605 @Description		Converts the string to upper case
   1606 *************************************************************************/
   1607 CPVRTString&  CPVRTString::toUpper()
   1608 {
   1609 	int i = 0;
   1610 	while ( (m_pString[i] = (m_pString[i]>='a'&&m_pString[i]<='z') ? ('A'+m_pString[i])-'a': m_pString[i]) != 0) i++;
   1611 	return *this;
   1612 }
   1613 
   1614 /*!***********************************************************************
   1615 @Function			Format
   1616 @Input				pFormat A string containing the formating
   1617 @Returns			A formatted string
   1618 @Description		return the formatted string
   1619 ************************************************************************/
   1620 CPVRTString CPVRTString::format(const char *pFormat, ...)
   1621 {
   1622 	va_list arg;
   1623 
   1624 	va_start(arg, pFormat);
   1625 #if defined(_WIN32)
   1626 	size_t bufSize = _vscprintf(pFormat,arg);
   1627 #else
   1628 	size_t bufSize = vsnprintf(NULL,0,pFormat,arg);
   1629 #endif
   1630 	va_end(arg);
   1631 
   1632 	char*	buf=new char[bufSize + 1];
   1633 
   1634 	va_start(arg, pFormat);
   1635 	vsnprintf(buf, bufSize + 1, pFormat, arg);
   1636 	va_end(arg);
   1637 
   1638 	CPVRTString returnString(buf);
   1639 	delete [] buf;
   1640 	*this = returnString;
   1641 	return returnString;
   1642 }
   1643 
   1644 /*!***********************************************************************
   1645 @Function			+=
   1646 @Input				_Ch A char
   1647 @Returns			An updated string
   1648 @Description		+= Operator
   1649 *************************************************************************/
   1650 CPVRTString& CPVRTString::operator+=(char _Ch)
   1651 {
   1652 	return append(1, _Ch);
   1653 }
   1654 
   1655 /*!***********************************************************************
   1656 @Function			+=
   1657 @Input				_Ptr A string
   1658 @Returns			An updated string
   1659 @Description		+= Operator
   1660 *************************************************************************/
   1661 CPVRTString& CPVRTString::operator+=(const char* _Ptr)
   1662 {
   1663 	return append(_Ptr);
   1664 }
   1665 
   1666 /*!***********************************************************************
   1667 @Function			+=
   1668 @Input				_Right A string
   1669 @Returns			An updated string
   1670 @Description		+= Operator
   1671 *************************************************************************/
   1672 CPVRTString& CPVRTString::operator+=(const CPVRTString& _Right)
   1673 {
   1674 	return append(_Right);
   1675 }
   1676 
   1677 /*!***********************************************************************
   1678 @Function			=
   1679 @Input				_Ch A char
   1680 @Returns			An updated string
   1681 @Description		= Operator
   1682 *************************************************************************/
   1683 CPVRTString& CPVRTString::operator=(char _Ch)
   1684 {
   1685 	return assign(1, _Ch);
   1686 }
   1687 
   1688 /*!***********************************************************************
   1689 @Function			=
   1690 @Input				_Ptr A string
   1691 @Returns			An updated string
   1692 @Description		= Operator
   1693 *************************************************************************/
   1694 CPVRTString& CPVRTString::operator=(const char* _Ptr)
   1695 {
   1696 	return assign(_Ptr);
   1697 }
   1698 
   1699 /*!***********************************************************************
   1700 @Function			=
   1701 @Input				_Right A string
   1702 @Returns			An updated string
   1703 @Description		= Operator
   1704 *************************************************************************/
   1705 CPVRTString& CPVRTString::operator=(const CPVRTString& _Right)
   1706 {
   1707 	return assign(_Right);
   1708 }
   1709 
   1710 /*!***********************************************************************
   1711 @Function			[]
   1712 @Input				_Off An index into the string
   1713 @Returns			A character
   1714 @Description		[] Operator
   1715 *************************************************************************/
   1716 CPVRTString::const_reference CPVRTString::operator[](size_t _Off) const
   1717 {
   1718 	return m_pString[_Off];
   1719 }
   1720 
   1721 /*!***********************************************************************
   1722 @Function			[]
   1723 @Input				_Off An index into the string
   1724 @Returns			A character
   1725 @Description		[] Operator
   1726 *************************************************************************/
   1727 CPVRTString::reference CPVRTString::operator[](size_t _Off)
   1728 {
   1729 	return m_pString[_Off];
   1730 }
   1731 
   1732 /*!***********************************************************************
   1733 @Function			+
   1734 @Input				_Left A string
   1735 @Input				_Right A string
   1736 @Returns			An updated string
   1737 @Description		+ Operator
   1738 *************************************************************************/
   1739 CPVRTString operator+ (const CPVRTString& _Left, const CPVRTString& _Right)
   1740 {
   1741 	return CPVRTString(_Left).append(_Right);
   1742 }
   1743 
   1744 /*!***********************************************************************
   1745 @Function			+
   1746 @Input				_Left A string
   1747 @Input				_Right A string
   1748 @Returns			An updated string
   1749 @Description		+ Operator
   1750 *************************************************************************/
   1751 CPVRTString operator+ (const CPVRTString& _Left, const char* _Right)
   1752 {
   1753 	return CPVRTString(_Left).append(_Right);
   1754 }
   1755 
   1756 /*!***********************************************************************
   1757 @Function			+
   1758 @Input				_Left A string
   1759 @Input				_Right A string
   1760 @Returns			An updated string
   1761 @Description		+ Operator
   1762 *************************************************************************/
   1763 CPVRTString operator+ (const CPVRTString& _Left, const char _Right)
   1764 {
   1765 	return CPVRTString(_Left).append(_Right);
   1766 }
   1767 
   1768 /*!***********************************************************************
   1769 @Function			+
   1770 @Input				_Left A string
   1771 @Input				_Right A string
   1772 @Returns			An updated string
   1773 @Description		+ Operator
   1774 *************************************************************************/
   1775 CPVRTString operator+ (const char* _Left, const CPVRTString& _Right)
   1776 {
   1777 	return CPVRTString(_Left).append(_Right);
   1778 }
   1779 
   1780 /*!***********************************************************************
   1781 @Function			+
   1782 @Input				_Left A string
   1783 @Input				_Right A string
   1784 @Returns			An updated string
   1785 @Description		+ Operator
   1786 *************************************************************************/
   1787 CPVRTString operator+ (const char _Left, const CPVRTString& _Right)
   1788 {
   1789 	return CPVRTString(_Left).append(_Right);
   1790 }
   1791 
   1792 /*************************************************************************
   1793 * MISCELLANEOUS UTILITY FUNCTIONS
   1794 *************************************************************************/
   1795 /*!***********************************************************************
   1796 @Function			PVRTStringGetFileExtension
   1797 @Input				strFilePath A string
   1798 @Returns			Extension
   1799 @Description		Extracts the file extension from a file path.
   1800 					Returns an empty CPVRTString if no extension is found.
   1801 ************************************************************************/
   1802 CPVRTString PVRTStringGetFileExtension(const CPVRTString& strFilePath)
   1803 {
   1804 	CPVRTString::size_type idx = strFilePath.find_last_of ( '.' );
   1805 
   1806     if (idx == CPVRTString::npos)
   1807     	return CPVRTString("");
   1808     else
   1809     	return strFilePath.substr(idx);
   1810 }
   1811 
   1812 /*!***********************************************************************
   1813 @Function			PVRTStringGetContainingDirectoryPath
   1814 @Input				strFilePath A string
   1815 @Returns			Directory
   1816 @Description		Extracts the directory portion from a file path.
   1817 ************************************************************************/
   1818 CPVRTString PVRTStringGetContainingDirectoryPath(const CPVRTString& strFilePath)
   1819 {
   1820 	size_t i32sep = strFilePath.find_last_of('/');
   1821 	if(i32sep == strFilePath.npos)
   1822 	{
   1823 		i32sep = strFilePath.find_last_of('\\');
   1824 		if(i32sep == strFilePath.npos)
   1825 		{	// can't find an actual \ or /, so return an empty string
   1826 			return CPVRTString("");
   1827 		}
   1828 	}
   1829 	return strFilePath.substr(0,i32sep);
   1830 }
   1831 
   1832 /*!***********************************************************************
   1833 @Function			PVRTStringGetFileName
   1834 @Input				strFilePath A string
   1835 @Returns			FileName
   1836 @Description		Extracts the name and extension portion from a file path.
   1837 ************************************************************************/
   1838 CPVRTString PVRTStringGetFileName(const CPVRTString& strFilePath)
   1839 {
   1840 	size_t i32sep = strFilePath.find_last_of('/');
   1841 	if(i32sep == strFilePath.npos)
   1842 	{
   1843 		i32sep = strFilePath.find_last_of('\\');
   1844 		if(i32sep == strFilePath.npos)
   1845 		{	// can't find an actual \ or / so leave it be
   1846 			return strFilePath;
   1847 		}
   1848 	}
   1849 	return strFilePath.substr(i32sep+1,strFilePath.length());
   1850 }
   1851 
   1852 /*!***********************************************************************
   1853 @Function			PVRTStringStripWhiteSpaceFromStartOf
   1854 @Input				strLine A string
   1855 @Returns			Result of the white space stripping
   1856 @Description		strips white space characters from the beginning of a CPVRTString.
   1857 ************************************************************************/
   1858 CPVRTString PVRTStringStripWhiteSpaceFromStartOf(const CPVRTString& strLine)
   1859 {
   1860 	size_t start = strLine.find_first_not_of(" \t	\n\r");
   1861 	if(start!=strLine.npos)
   1862 		return strLine.substr(start,strLine.length()-(start));
   1863 	return strLine;
   1864 }
   1865 
   1866 
   1867 /*!***********************************************************************
   1868 @Function			PVRTStringStripWhiteSpaceFromEndOf
   1869 @Input				strLine A string
   1870 @Returns			Result of the white space stripping
   1871 @Description		strips white space characters from the end of a CPVRTString.
   1872 ************************************************************************/
   1873 CPVRTString PVRTStringStripWhiteSpaceFromEndOf(const CPVRTString& strLine)
   1874 {
   1875 	size_t end = strLine.find_last_not_of(" \t	\n\r");
   1876 	if(end!=strLine.npos)
   1877 		return strLine.substr(0,end+1);
   1878 	return strLine;
   1879 }
   1880 
   1881 /*!***********************************************************************
   1882 @Function			PVRTStringFromFormattedStr
   1883 @Input				pFormat A string containing the formating
   1884 @Returns			A formatted string
   1885 @Description		Creates a formatted string
   1886 ************************************************************************/
   1887 CPVRTString PVRTStringFromFormattedStr(const char *pFormat, ...)
   1888 {
   1889 	va_list arg;
   1890 
   1891 	va_start(arg, pFormat);
   1892 #if defined(_WIN32)
   1893 	size_t bufSize = _vscprintf(pFormat,arg);
   1894 #else
   1895 	size_t bufSize = vsnprintf(NULL,0,pFormat,arg);
   1896 #endif
   1897 	va_end(arg);
   1898 
   1899 	char* buf = new char[bufSize + 1];
   1900 
   1901 	va_start(arg, pFormat);
   1902 	vsnprintf(buf, bufSize + 1, pFormat, arg);
   1903 	va_end(arg);
   1904 
   1905 	CPVRTString returnString(buf);
   1906 	delete [] buf;
   1907 	return returnString;
   1908 }
   1909 
   1910 ///*!***************************************************************************
   1911 
   1912 
   1913 // Substitute one character by another
   1914 CPVRTString& CPVRTString::substitute(char _src,char _subDes, bool _all)
   1915 {
   1916 	int len = (int) length();
   1917 	char  c=_src;
   1918 	char  s=_subDes;
   1919 	int  i=0;
   1920 	while(i<len)
   1921 	{
   1922 		if(m_pString[i]==c)
   1923 		{
   1924 			m_pString[i]=s;
   1925 			if(!_all) break;
   1926 		}
   1927 		i++;
   1928 	}
   1929 	return *this;
   1930 }
   1931 
   1932 
   1933 // Substitute one string by another ( Need time to improved )
   1934 CPVRTString& CPVRTString::substitute(const char* _src, const char* _dest, bool _all)
   1935 {
   1936 	if (this->length() == 0)
   1937 	{
   1938 		return *this;
   1939 	}
   1940 	unsigned int pos=0;
   1941 	CPVRTString src = _src;
   1942 	CPVRTString dest = _dest;
   1943 	CPVRTString ori;
   1944 
   1945 	while(pos<=m_Size-src.length())
   1946 	{
   1947 		if(this->compare(pos,src.length(),_src)==0)
   1948 		{
   1949 			ori = this->c_str();
   1950 			CPVRTString sub1, sub2, result;
   1951 			sub1.assign(ori,0,pos);
   1952 			sub2.assign(ori,pos+src.length(),m_Size - (pos+src.length()));
   1953 
   1954 			this->assign("");
   1955 			this->append(sub1);
   1956 			this->append(dest);
   1957 			this->append(sub2);
   1958 
   1959 			if(!_all)
   1960 			{
   1961 					break;
   1962 			}
   1963 			pos += (unsigned int) dest.length();
   1964 			continue;
   1965 		}
   1966 		pos++;
   1967 	}
   1968 
   1969 	return *this;
   1970 }
   1971 
   1972 
   1973 #endif // _USING_PVRTSTRING_
   1974 
   1975 /*****************************************************************************
   1976  End of file (PVRTString.cpp)
   1977 *****************************************************************************/
   1978 
   1979