Subversion Repositories spk

Rev

Rev 43 | Rev 50 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
8 cycrow 1
#include "String.h"
2
 
3
#include <sstream>
4
#include <stdarg.h>
43 cycrow 5
#include <algorithm>
8 cycrow 6
 
7
namespace Utils {
8
 
13 cycrow 9
String operator+(const char *str1, const String &str2)
10
{
11
	return String(str1) + str2;
12
}
13
 
14
 
8 cycrow 15
String::String(void)						{ this->assign(""); }
16
String::String(const char *str)				{ this->assign(str); }
17
String::String(const unsigned char *str)	{ this->assign((const char *)str); }
18
String::String(const std::string &str)		{ this->assign(str);}
19
String::String(const unsigned char c)		{ this->assign(1, c); }
14 cycrow 20
String::String(const char c)				{ this->assign(1, c); }
8 cycrow 21
String::String(const String &str)			{ this->assign(str); }
22
String::String(long l)						{ this->fromLong(l); }
23
String::String(unsigned long l)				{ this->fromLong((long)l); }
24
String::String(float f)						{ this->fromFloat(f); }
25
String::String(double f)					{ this->fromDouble(f); }
26
 
27
String::~String(void)
28
{
29
}
30
 
31
/////////////////////////////////////////////////////////////////
32
// Conversion functions
33
 
34
void String::fromLong(long l)
35
{
36
	std::stringstream strstream;
37
	strstream << l;
14 cycrow 38
	*this = strstream.str();
8 cycrow 39
}
40
 
41
void String::fromFloat(float f, int dp)
42
{
43
	std::stringstream strstream;
44
	strstream.precision(dp);
45
	strstream << std::fixed << f;
14 cycrow 46
	*this = strstream.str();
8 cycrow 47
}
48
 
49
void String::fromFloat(float f)
50
{
51
	std::stringstream strstream;
52
	strstream << f;
14 cycrow 53
	*this = strstream.str();
8 cycrow 54
}
55
void String::fromDouble(double f)
56
{
57
	std::stringstream strstream;
58
	strstream << f;
14 cycrow 59
	*this = strstream.str();
8 cycrow 60
}
61
 
62
const String &String::format(const char *sFormat, ...)
63
{
64
	char buffer[1024];
65
	va_list args;
66
	va_start (args, sFormat);
67
	vsprintf (buffer, sFormat, args);
68
	va_end (args);
69
 
70
	this->assign(buffer);
71
	return (*this);
72
}
73
 
74
String String::fromFormat(const char *sFormat, ...)
75
{
76
	char buffer[1024];
77
	va_list args;
78
	va_start (args, sFormat);
79
	vsprintf (buffer, sFormat, args);
80
	va_end (args);
81
 
82
	return String(buffer);
83
}
84
 
85
long String::toLong() const
86
{
87
	return atoi(this->c_str());
88
}
89
double String::toDouble() const
90
{
91
	return atof(this->c_str());
92
}
93
float String::toFloat() const
94
{
95
	return (float)atof(this->c_str());
96
}
97
 
98
 
99
const String &String::operator= ( const char *str )				{ this->assign(str); return (*this); }
100
const String &String::operator= ( const unsigned char *str )	{ this->assign((const char *)str); return (*this); }
101
const String &String::operator= ( const String &str )			{ this->assign((std::string &)str); return (*this); }
102
const String &String::operator= ( const std::string &str )		{ this->assign(str); return (*this); }
103
const String &String::operator= ( unsigned char c )				{ this->assign(1, c); return (*this); }
104
const String &String::operator= ( char c )						{ this->assign(1, c); return (*this); }
105
const String &String::operator= ( long l )						{ this->fromLong(l); return (*this); }
106
const String &String::operator= ( unsigned long l )				{ this->fromLong(l); return (*this); }
107
const String &String::operator= ( float f )						{ this->fromFloat(f); return (*this); }
108
const String &String::operator= ( double f )					{ this->fromDouble(f); return (*this); }
109
 
110
const unsigned char String::operator[] ( int num ) const			{ return this->at(num); }
111
unsigned char &String::operator[] ( int num )						{ return (unsigned char &)this->at(num); }
112
 
113
const String &String::operator+= ( const char *str )			{ this->append(str); return (*this); }
114
const String &String::operator+= ( const unsigned char *str ) 	{ this->append((const char *)str); return (*this); }
115
const String &String::operator+= ( const std::string &str )		{ this->append(str); return (*this); }
116
const String &String::operator+= ( const String &str )		{ this->append(str); return (*this); }
117
const String &String::operator+= ( const char c )				{ this->append(1, c); return (*this); }
118
const String &String::operator+= ( const unsigned char c )		{ this->append(1, c); return (*this); }
119
const String &String::operator+= ( const unsigned long l )		
120
{ 
121
	std::stringstream strm;
122
	strm << (*this) << l;
123
	strm >> (*this);
124
	return (*this); 
125
}
126
const String &String::operator+= ( const long l )		
127
{ 
128
	std::stringstream strm;
129
	strm << (*this) << l;
14 cycrow 130
	*this = strm.str();
8 cycrow 131
	return (*this); 
132
}
133
const String &String::operator+= ( const float f )		
134
{ 
135
	std::stringstream strm;
136
	strm << (*this) << f;
14 cycrow 137
	*this = strm.str();
8 cycrow 138
	return (*this); 
139
}
140
const String &String::operator+= ( const double f )		
141
{ 
142
	std::stringstream strm;
143
	strm << (*this) << f;
14 cycrow 144
	*this = strm.str();
8 cycrow 145
	return (*this); 
146
}
147
 
148
 
149
String String::operator+ ( const char *str ) const			{ return String(*this) += str; }
150
String String::operator+ ( const unsigned char *str ) const	{ return String(*this) += str; }
151
String String::operator+ ( const std::string &str ) const	{ return String(*this) += str; }
152
String String::operator+ ( const String &str ) const		{ return String(*this) += str; }
153
String String::operator+ ( const char c ) const				{ return String(*this) += c; }
154
String String::operator+ ( const unsigned char c ) const	{ return String(*this) += c; }
155
String String::operator+ ( const long l ) const				{ return String(*this) += l; }
156
String String::operator+ ( const unsigned long l ) const	{ return String(*this) += l; }
157
String String::operator+ ( const float f ) const			{ return String(*this) += f; }
158
String String::operator+ ( const double f ) const			{ return String(*this) += f; }
159
 
160
bool String::operator== ( const char *str ) const				{ return (this->compare(str)) ? false : true; }
161
bool String::operator== ( const unsigned char *str ) const	{ return (this->compare((const char *)str)) ? false : true; }
162
bool String::operator== ( const std::string &str ) const		{ return (this->compare(str)) ? false : true; }
163
bool String::operator== ( const String &str ) const			{ return (this->compare(str)) ? false : true; }
164
 
165
bool String::operator!= ( const char *str ) const				{ return (this->compare(str)) ? true : false; }
166
bool String::operator!= ( const unsigned char *str ) const	{ return (this->compare((const char *)str)) ? true : false; }
167
bool String::operator!= ( const std::string &str ) const		{ return (this->compare(str)) ? true : false; }
168
bool String::operator!= ( const String &str ) const			{ return (this->compare(str)) ? true : false; }
169
 
170
bool String::Compare(const String &str, bool bCaseSensative) const
171
{
172
	if ( bCaseSensative ) {
173
		return (this->compare(str) == 0) ? true : false;
174
	}
175
 
176
	if ( str.length() != this->length() ) return false;
177
	for ( unsigned int i = 0; i < str.length(); i++ ) {
178
		if ( tolower(this->at(i)) != tolower(str[i]) ) {
179
			return false;
180
		}
181
	}
182
	return true;
183
}
184
 
185
bool String::Compare(const unsigned char *str, bool bCaseSensative) const
186
{
187
	return this->Compare((const char *)str, bCaseSensative);
188
}
189
 
190
bool String::Compare(const char *str, bool bCaseSensative) const
191
{
192
	if ( bCaseSensative ) {
193
		return (this->compare(str) == 0) ? true : false;
194
	}
195
 
196
	if ( strlen(str) != this->length() ) return false;
197
	for ( unsigned int i = 0; i < this->length(); i++ ) {
198
		if ( tolower(this->at(i)) != tolower(*(str + i)) ) {
199
			return false;
200
		}
201
	}
202
 
203
	return true;
204
}
205
 
206
String String::token(const char *token, int tok) const
207
{
208
	return this->tokens(token, tok, tok);
209
}
210
 
211
String String::tokens(const char *token, int from, int to) const
212
{
213
	if ( this->empty() ) return "";
214
 
215
	int max = this->countToken(token);
216
 
217
	std::string newstr;
218
 
219
	int whichtok = 1;
220
	std::string::size_type lastPos = 0;
221
	std::string::size_type pos     = _token_nextPos(token, 0);
222
 
223
	if ( from < 0 )
224
		from = max + (from + 1);
225
	if ( to < 0 )
226
		to = max + (to + 1);
227
 
228
	while (std::string::npos != pos || std::string::npos != lastPos)
229
	{
230
		if ( to == 0 )
231
		{
232
			if ( whichtok >= from )
233
			{
234
				if ( newstr != "" ) newstr = newstr + token;
235
				newstr = newstr + this->substr(lastPos, pos - lastPos);
236
			}
237
		}
238
		else
239
		{
240
			if ( (whichtok >= from) && (whichtok <= to) )
241
			{
242
				if ( newstr != "" ) newstr = newstr + token;
243
				newstr = newstr + this->substr(lastPos, pos - lastPos);
244
			}
245
			if ( whichtok > to )
246
				break;
247
		}
248
		// Found a token, add it to the vector.
249
		whichtok++;
250
 
251
		if ( pos >= this->length() )
252
			break;
253
 
254
		// skip past token
255
		size_t i = 0;
256
		size_t max = strlen(token);
257
		lastPos = pos;
258
		while ( (i < max) && (token[i] == this->at(lastPos)) )
259
		{
260
			++i;
261
			++lastPos;
262
		}
263
 
264
		// get the next token
265
		pos = _token_nextPos(token, lastPos);
266
	}
267
	return newstr;
268
}
269
 
39 cycrow 270
String String::remToken(const char *token, int from) const
271
{
272
	std::string newstr;
273
 
274
	int whichtok = 1;
275
	std::string::size_type lastPos = 0;
276
	std::string::size_type pos     = _token_nextPos(token, 0);
277
 
278
	while (std::string::npos != pos || std::string::npos != lastPos)
279
	{
280
		if ( whichtok != from )
281
		{
282
			if ( newstr != "" ) newstr = newstr + token;
283
			newstr = newstr + this->substr(lastPos, pos - lastPos);
284
		}
285
 
286
		// Found a token, add it to the vector.
287
		whichtok++;
288
 
289
		if ( pos >= this->length() )
290
			break;
291
 
292
		// skip past token
293
		size_t i = 0;
294
		size_t max = strlen(token);
295
		lastPos = pos;
296
		while ( (i < max) && (token[i] == this->at(lastPos)) )
297
		{
298
			++i;
299
			++lastPos;
300
		}
301
 
302
		// get the next token
303
		pos = _token_nextPos(token, lastPos);
304
	}
305
	return newstr;
306
}
307
 
308
String String::word(int word) const
309
{
310
	return this->token(" ", word);
311
}
312
String String::words(int from, int to) const
313
{
314
	return this->tokens(" ", from, to);
315
}
8 cycrow 316
int String::countToken(const char *token) const
317
{
318
	if ( this->empty() )
319
		return 0;
320
 
321
	// finds the number of tokens in a string
322
	int found = 1;
323
 
324
	std::string tmpstr = *this;
325
 
326
	// ignore the initial spaces
327
	std::string::size_type pos = this->find_first_not_of(token, 0);
328
 
329
	// remove end spaces
330
	size_t i = tmpstr.size() - 1;
331
	while ( tmpstr[i] == ' ' && i > 0 )
332
		i--;
333
	if ( i <= 0 ) return 0;
334
	tmpstr.erase ( i + 1, tmpstr.size() - i );
335
 
336
	// count tokens
337
	pos = tmpstr.find (token,pos + 1);
338
	while ( pos < std::string::npos )
339
	{
340
		while (tmpstr[pos] == ' ')
341
			pos++;
342
		found++;
343
		pos = tmpstr.find (token,pos + 1);
344
	}
345
 
346
	// return number of tokens
347
	return found;
348
}
349
 
350
std::string::size_type String::_token_nextPos(const char *token, std::string::size_type curPos) const
351
{
352
	bool found = false;
353
	std::string::size_type startPos = 0;
354
	size_t max = strlen(token);
355
	while ( !found ) {
356
		found = true;
357
		startPos = this->find_first_of(token[0], curPos);
358
		if ( startPos == std::string::npos ) {
359
			startPos = this->length();
360
			break;
361
		}
362
 
363
		std::string::size_type pos = startPos;
364
		size_t i = 1;
365
		while ( i < max )
366
		{
367
			++pos;
368
			if ( this->at(pos) != token[i] )
369
			{
370
				found = false;
371
				break;
372
			}
373
			++i;
374
		}
375
		curPos = pos;
376
	}
377
	return startPos;
378
}
379
 
380
String String::findReplace(const String &find, const String &replace ) const
381
{
382
	std::string newstr = *this;
383
	std::string::size_type pos = newstr.find(find, 0);
384
	while ( pos < std::string::npos ) {
385
		newstr.replace(pos, find.length(), replace);
386
		pos = newstr.find(find, pos + replace.length());
387
	}
388
 
389
	return newstr;
390
}
391
 
48 cycrow 392
String String::findRemove(const String &find) const
393
{
394
	Utils::String replace = *this;
395
 
396
	std::string::size_type pos = replace.find(find, 0 );
397
	while ( pos != std::string::npos ) {
398
		replace.erase ( pos, find.length() );
399
		pos = replace.find(find, pos);
400
	}
401
 
402
	return replace;
403
}
404
 
405
String String::stripHtml() const
406
{
407
	// if empty, theres no to strip
408
	if ( this->empty() ) return "";
409
 
410
	// replace break line with a new line
411
	Utils::String newStr = (*this);
412
	newStr = newStr.findReplace("<br/>", "\n");
413
	newStr = newStr.findReplace("<br />", "\n");
414
	newStr = newStr.findReplace("<p>", "\n\t");
415
	newStr = newStr.findReplace("</p>", "\n");
416
 
417
	// find any remaining tags and remove them
418
	std::string::size_type pos     = newStr.find_first_of('<', 0);
419
	std::string::size_type lastPos = newStr.find_first_of('>', pos);
420
 
421
	while (std::string::npos != pos || std::string::npos != lastPos)
422
	{
423
		if ( lastPos > newStr.length() ) break;
424
		// remove the tag
425
		newStr.erase(pos, lastPos + 1);
426
 
427
		// find the next tag
428
		pos = newStr.find_first_of('<', pos);
429
		lastPos = newStr.find_first_of('>', pos);
430
	}
431
 
432
	// now remove all the starting new lines
433
	while ( newStr[0] == '\n' || newStr[0] == '\t' ) newStr.erase(0, 1);
434
	return newStr;
435
}
436
 
8 cycrow 437
bool String::isin(const String &str, bool bCaseSensative) const
438
{
439
	unsigned int check = 0;
440
	for ( unsigned int i = 0; i < this->length(); i++ )
441
	{
442
		bool bCheck	= (bCaseSensative) ? (this->at(i) == str[check]) : (tolower(this->at(i)) == tolower(str[check]));
443
		if ( bCheck )
444
			++check;
445
		else
446
			check = 0;
447
 
448
		if ( check >= str.length() )
449
			return true;
450
	}
451
	return false;
452
}
453
 
39 cycrow 454
int String::findPos(const String &find, int iStartPos) const
455
{
456
	std::string::size_type pos = this->find(find, iStartPos);
457
	if ( pos == std::string::npos ) return -1;
458
	return pos;
459
}
460
 
8 cycrow 461
bool String::isin(char c, bool bCaseSensative) const
462
{
463
	bool f = false;
464
	for ( unsigned int i = 0; i < this->length(); i++ )
465
	{
466
		bool bCheck = (bCaseSensative) ? (this->at(i) == c) : (tolower(this->at(i)) == tolower(c));
467
		if ( bCheck ) {
468
			f = true;
469
			break;
470
		}
471
	}
472
	return f;
473
}
474
 
39 cycrow 475
String String::mid(int start, int end) const
476
{
477
	return this->substr(start, end - start);
478
}
8 cycrow 479
String String::left(long num) const
480
{
481
	if ( num < 0 )
482
		num = (long)this->length() + num;
483
	if ( num > (long)this->length() )
484
		num = (long)this->length();
485
 
486
	return this->substr(0, num);
487
}
488
 
489
String String::right(int num) const
490
{
491
	if ( num > 0 ) num -= (int)this->length();
492
	if ( num < -(int)this->length() ) num = -(int)this->length();
493
 
494
	return this->substr(-num);
495
}
496
 
39 cycrow 497
const String &String::readToEndOfLine(FILE *id, int *line, bool upper)
498
{
499
	(*this) == "";
500
	char c = fgetc ( id );
501
	if ( c == -1 )
502
		return (*this);
503
 
504
	while ( (c != 13) && (!feof(id)) && (c != '\n') )
505
	{
506
		(*this) += c;
507
		c = fgetc ( id );
508
	}
509
 
510
	if ( line )
511
		++(*line);
512
 
513
//	if ( upper )
514
	//	ToUpper ();
515
 
516
	return (*this);
517
}
518
 
8 cycrow 519
char *String::readToEndOfLine(char *data)
520
{
521
	return (char *)this->readToEndOfLine((unsigned char *)data);
522
}
523
unsigned char *String::readToEndOfLine(unsigned char *data)
524
{
525
	int pos = 0;
526
 
527
	// do until we get a line break
528
	while ( (data[pos] != 13) && (data[pos] != 0) && (data[pos] != '\n') ) {
529
		++pos;
530
	}
531
 
532
	if ( !pos ) {
533
		this->clear();
534
	}
535
	else {
536
		if ( pos > 2000 ) {
537
			char *d = new char[pos + 1];
538
			memcpy(d, data, pos);
539
			d[pos] = 0;
540
			*this = d;
541
			delete d;
542
		}
543
		else {
544
			char d[2000];
545
			memcpy(d, data, pos);
546
			d[pos] = 0;
547
			*this = d;
548
		}
549
	}
550
 
551
	if ( data[pos] == 0 ) return NULL;
552
	return data + (pos + 1);
553
}
554
 
14 cycrow 555
String String::replaceToken(const char *token, int from, const String &replace) const
556
{
557
	std::string newstr;
558
 
559
	int whichtok = 1;
560
	std::string::size_type lastPos = 0;
561
	std::string::size_type pos     = _token_nextPos(token, 0);
562
 
563
	while (std::string::npos != pos || std::string::npos != lastPos)
564
	{
565
		if ( whichtok == from )
566
		{
567
			if ( newstr != "" ) newstr = newstr + token;
568
			newstr = newstr + replace;
569
		}
570
		else
571
		{
572
			if ( newstr != "" ) newstr = newstr + token;
573
			newstr = newstr + this->substr(lastPos, pos - lastPos);
574
		}
575
 
576
		// Found a token, add it to the vector.
577
		whichtok++;
578
 
579
		if ( pos >= this->length() )
580
			break;
581
 
582
		// skip past token
583
		size_t i = 0;
584
		size_t max = strlen(token);
585
		lastPos = pos;
586
		while ( (i < max) && (token[i] == this->at(lastPos)) )
587
		{
588
			++i;
589
			++lastPos;
590
		}
591
 
592
		// get the next token
593
		pos = _token_nextPos(token, lastPos);
594
	}
595
	return newstr;
596
}
597
 
598
 
10 cycrow 599
String *String::tokenise(const char *token, int *max) const
600
{
601
	if ( empty() ) {
602
		*max = 0;
603
		return NULL;
604
	}
8 cycrow 605
 
10 cycrow 606
	*max = this->countToken(token);
8 cycrow 607
 
10 cycrow 608
	if ( (*max) <= 0 ) {
609
		*max = 0;
610
		return NULL;
611
	}
612
 
613
	String *newstr = (*max == 1) ? new String : new String[*max];
614
 
615
	int whichtok = 0;
616
	// get first token
617
	std::string::size_type lastPos = 0;
618
	std::string::size_type pos     = this->_token_nextPos(token, 0);
619
 
620
	while (std::string::npos != pos || std::string::npos != lastPos)
621
	{
622
		// set token
623
		if ( *max == 1 ) *newstr = this->substr(lastPos, pos - lastPos);
624
		else			  newstr[whichtok] = this->substr(lastPos, pos - lastPos);
625
 
626
		// move to next token
627
		whichtok++;
628
		if ( whichtok >= *max )
629
			break;
630
 
631
		if ( pos >= this->length() )
632
			break;
633
 
634
		// skip past token
635
		size_t i = 0;
636
		size_t max = strlen(token);
637
		lastPos = pos;
638
		while ( (i < max) && (token[i] == this->at(lastPos)) ) {
639
			++i;
640
			++lastPos;
641
		}
642
 
643
		// get the next token
644
		pos = _token_nextPos(token, lastPos);
645
	}
646
 
647
	return newstr;
648
}
649
 
39 cycrow 650
const String &String::removeChar(char c)
10 cycrow 651
{
652
	std::string::size_type pos = this->find_first_of(c, 0);
653
	while(pos != std::string::npos) {
654
		this->erase(pos, 1);
655
		pos = this->find_first_of(c, 0);
656
	}
657
 
658
	return (*this);
659
}
660
 
39 cycrow 661
String String::remove(char c) const
10 cycrow 662
{
663
	String newStr = *this;
664
 
665
	std::string::size_type pos = newStr.find_first_of(c, 0);
666
	while(pos != std::string::npos) {
667
		newStr.erase(pos, 1);
668
		pos = newStr.find_first_of(c, 0);
669
	}
670
 
671
	return newStr;
672
}
673
 
13 cycrow 674
bool String::_isCharNumber(char c) const
675
{
676
	return (c >= '0' && c <= '9') ? true : false;
677
}
678
 
679
bool String::isCharNumber(int c) const
680
{
681
	return _isCharNumber(this->at(c));
682
}
683
 
684
bool String::isNumber(bool integer) const
685
{
686
	bool foundpoint = integer;
687
	for ( int i = 0; i < (int)this->length(); i++ )
688
	{
689
		// check for a decimal point (floating point value)
690
		// only allow 1 decimal point, or none if just checking for an integer
691
		if ( this->at(i) == '.' && !foundpoint ) foundpoint = true;
692
		// check if it is a number, 0-9
693
		else if ( !this->isCharNumber(i) ) return false;
694
	}
695
	return true;
696
}
14 cycrow 697
 
698
const String &String::removeFirstSpace()
699
{
39 cycrow 700
	std::string::size_type pos = this->find_first_not_of(" \t\f\v\n\r", 0);
14 cycrow 701
	if ( pos != std::string::npos ) {
702
		this->erase(0, pos);
703
	}
704
	return (*this);
705
}
39 cycrow 706
const String &String::removeEndSpace()
707
{
708
	std::string::size_type pos = this->find_last_not_of(" \t\f\v\n\r");
709
	if ( pos != std::string::npos ) {
710
		this->erase(pos + 1);
711
	}
712
	return (*this);
713
}
14 cycrow 714
 
34 cycrow 715
const String &String::truncate(int iNum)
716
{
717
	size_t pos = iNum;
718
	if ( iNum < 0 ) pos = this->length() + iNum;
719
	this->erase(pos, this->length() - pos);
720
	return (*this);
721
}
722
 
43 cycrow 723
String String::lower() const
724
{
725
	Utils::String newStr(*this);
726
	std::transform(this->begin(), this->end(), newStr.begin(), tolower);
727
	return newStr;
728
}
729
 
730
String String::upper() const
731
{
732
	Utils::String newStr(*this);
733
	std::transform(this->begin(), this->end(), newStr.begin(), toupper);
734
	return newStr;
735
}
736
const String &String::toLower()
737
{
738
	std::transform(this->begin(), this->end(), this->begin(), tolower);
739
	return (*this);
740
}
741
 
742
const String &String::toUpper()
743
{
744
	std::transform(this->begin(), this->end(), this->begin(), toupper);
745
	return (*this);
746
}
747
 
8 cycrow 748
}//NAMESPACE