• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 ************************************************************************/
CPVRTString(const char * _Ptr,size_t _Count)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 ************************************************************************/
CPVRTString(const CPVRTString & _Right,size_t _Roff,size_t _Count)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 *************************************************************************/
CPVRTString(size_t _Count,char _Ch)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 *************************************************************************/
CPVRTString(const char _Ch)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 *************************************************************************/
CPVRTString()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 *************************************************************************/
~CPVRTString()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 *************************************************************************/
append(const char * _Ptr)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 *************************************************************************/
append(const char * _Ptr,size_t _Count)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 *************************************************************************/
append(const CPVRTString & _Str)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 *************************************************************************/
append(const CPVRTString & _Str,size_t _Off,size_t _Count)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 *************************************************************************/
append(size_t _Count,char _Ch)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 *************************************************************************/
assign(const char * _Ptr)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 *************************************************************************/
assign(const char * _Ptr,size_t _Count)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 *************************************************************************/
assign(const CPVRTString & _Str)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 *************************************************************************/
assign(const CPVRTString & _Str,size_t _Off,size_t _Count)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 *************************************************************************/
assign(size_t _Count,char _Ch)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 *************************************************************************/
c_str() const351 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 *************************************************************************/
capacity() const361 size_t CPVRTString::capacity() const
362 {
363 	return m_Capacity;
364 }
365 
366 /*!***********************************************************************
367 @Function			clear
368 @Description		Clears the string
369 *************************************************************************/
clear()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 *************************************************************************/
compare(const CPVRTString & _Str) const388 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 *************************************************************************/
operator <(const CPVRTString & _Str) const399 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 *************************************************************************/
compare(size_t _Pos1,size_t _Num1,const CPVRTString & _Str) const412 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 *************************************************************************/
compare(size_t _Pos1,size_t _Num1,const CPVRTString & _Str,size_t,size_t _Count) const457 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 *************************************************************************/
compare(const char * _Ptr) const499 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 *************************************************************************/
compare(size_t _Pos1,size_t _Num1,const char * _Ptr) const512 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 *************************************************************************/
compare(size_t _Pos1,size_t _Num1,const char * _Ptr,size_t _Count) const557 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 *************************************************************************/
operator ==(const CPVRTString & _Str) const600 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 *************************************************************************/
operator ==(const char * const _Ptr) const611 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 *************************************************************************/
operator !=(const CPVRTString & _Str) const625 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 *************************************************************************/
operator !=(const char * const _Ptr) const636 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 *************************************************************************/
copy(char * _Ptr,size_t _Count,size_t _Off) const652 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 *************************************************************************/
data() const665 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 *************************************************************************/
empty() const675 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 *************************************************************************/
erase(size_t _Pos,size_t _Count)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 *************************************************************************/
find(const char * _Ptr,size_t _Off,size_t _Count) const708 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 *************************************************************************/
find(const CPVRTString & _Str,size_t _Off) const736 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 *************************************************************************/
find_first_not_of(char _Ch,size_t _Off) const748 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 *************************************************************************/
find_first_not_of(const char * _Ptr,size_t _Off) const765 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 *************************************************************************/
find_first_not_of(const char * _Ptr,size_t _Off,size_t _Count) const791 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 *************************************************************************/
find_first_not_of(const CPVRTString & _Str,size_t _Off) const816 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 *************************************************************************/
find_first_of(char _Ch,size_t _Off) const841 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 *************************************************************************/
find_first_of(const char * _Ptr,size_t _Off) const858 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 *************************************************************************/
find_first_of(const char * _Ptr,size_t _Off,size_t _Count) const880 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 *************************************************************************/
find_first_ofn(const char * _Ptr,size_t _Off,size_t _Count) const903 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 *************************************************************************/
find_first_of(const CPVRTString & _Str,size_t _Off) const945 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 *************************************************************************/
find_last_not_of(char _Ch,size_t _Off) const966 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 *************************************************************************/
find_last_not_of(const char * _Ptr,size_t _Off) const985 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 *************************************************************************/
find_last_not_of(const char * _Ptr,size_t _Off,size_t _Count) const1011 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 *************************************************************************/
find_last_not_of(const CPVRTString & _Str,size_t _Off) const1037 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 *************************************************************************/
find_last_of(char _Ch,size_t _Off) const1063 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 *************************************************************************/
find_last_of(const char * _Ptr,size_t _Off) const1082 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 *************************************************************************/
find_last_of(const char * _Ptr,size_t _Off,size_t _Count) const1104 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 *************************************************************************/
find_last_of(const CPVRTString & _Str,size_t _Off) const1125 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 *************************************************************************/
find_number_of(char _Ch,size_t _Off) const1146 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 *************************************************************************/
find_number_of(const char * _Ptr,size_t _Off) const1164 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 *************************************************************************/
find_number_of(const char * _Ptr,size_t _Off,size_t _Count) const1190 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 *************************************************************************/
find_number_of(const CPVRTString & _Str,size_t _Off) const1215 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 *************************************************************************/
find_next_occurance_of(char _Ch,size_t _Off) const1243 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 *************************************************************************/
find_next_occurance_of(const char * _Ptr,size_t _Off) const1261 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 *************************************************************************/
find_next_occurance_of(const char * _Ptr,size_t _Off,size_t _Count) const1287 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 *************************************************************************/
find_next_occurance_of(const CPVRTString & _Str,size_t _Off) const1312 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 *************************************************************************/
find_previous_occurance_of(char _Ch,size_t _Off) const1337 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 *************************************************************************/
find_previous_occurance_of(const char * _Ptr,size_t _Off) const1355 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 *************************************************************************/
find_previous_occurance_of(const char * _Ptr,size_t _Off,size_t _Count) const1381 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 *************************************************************************/
find_previous_occurance_of(const CPVRTString & _Str,size_t _Off) const1406 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 *************************************************************************/
left(size_t iSize) const1431 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 *************************************************************************/
right(size_t iSize) const1445 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 *************************************************************************/
length() const1481 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 *************************************************************************/
max_size() const1491 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 *************************************************************************/
push_back(char _Ch)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 *************************************************************************/
reserve(size_t _Count)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 *************************************************************************/
resize(size_t _Count,char _Ch)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 *************************************************************************/
size() const1555 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 *************************************************************************/
substr(size_t _Off,size_t _Count) const1567 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 *************************************************************************/
swap(CPVRTString & _Str)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 *************************************************************************/
toLower()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 *************************************************************************/
toUpper()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 ************************************************************************/
format(const char * pFormat,...)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 *************************************************************************/
operator +=(char _Ch)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 *************************************************************************/
operator +=(const char * _Ptr)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 *************************************************************************/
operator +=(const CPVRTString & _Right)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 *************************************************************************/
operator =(char _Ch)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 *************************************************************************/
operator =(const char * _Ptr)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 *************************************************************************/
operator =(const CPVRTString & _Right)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 *************************************************************************/
operator [](size_t _Off) const1716 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 *************************************************************************/
operator [](size_t _Off)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 *************************************************************************/
operator +(const CPVRTString & _Left,const CPVRTString & _Right)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 *************************************************************************/
operator +(const CPVRTString & _Left,const char * _Right)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 *************************************************************************/
operator +(const CPVRTString & _Left,const char _Right)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 *************************************************************************/
operator +(const char * _Left,const CPVRTString & _Right)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 *************************************************************************/
operator +(const char _Left,const CPVRTString & _Right)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 ************************************************************************/
PVRTStringGetFileExtension(const CPVRTString & strFilePath)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 ************************************************************************/
PVRTStringGetContainingDirectoryPath(const CPVRTString & strFilePath)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 ************************************************************************/
PVRTStringGetFileName(const CPVRTString & strFilePath)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 ************************************************************************/
PVRTStringStripWhiteSpaceFromStartOf(const CPVRTString & strLine)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 ************************************************************************/
PVRTStringStripWhiteSpaceFromEndOf(const CPVRTString & strLine)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 ************************************************************************/
PVRTStringFromFormattedStr(const char * pFormat,...)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
substitute(char _src,char _subDes,bool _all)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 )
substitute(const char * _src,const char * _dest,bool _all)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