Subversion Repositories spk

Rev

Rev 39 | Rev 48 | 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
 
392
bool String::isin(const String &str, bool bCaseSensative) const
393
{
394
	unsigned int check = 0;
395
	for ( unsigned int i = 0; i < this->length(); i++ )
396
	{
397
		bool bCheck	= (bCaseSensative) ? (this->at(i) == str[check]) : (tolower(this->at(i)) == tolower(str[check]));
398
		if ( bCheck )
399
			++check;
400
		else
401
			check = 0;
402
 
403
		if ( check >= str.length() )
404
			return true;
405
	}
406
	return false;
407
}
408
 
39 cycrow 409
int String::findPos(const String &find, int iStartPos) const
410
{
411
	std::string::size_type pos = this->find(find, iStartPos);
412
	if ( pos == std::string::npos ) return -1;
413
	return pos;
414
}
415
 
8 cycrow 416
bool String::isin(char c, bool bCaseSensative) const
417
{
418
	bool f = false;
419
	for ( unsigned int i = 0; i < this->length(); i++ )
420
	{
421
		bool bCheck = (bCaseSensative) ? (this->at(i) == c) : (tolower(this->at(i)) == tolower(c));
422
		if ( bCheck ) {
423
			f = true;
424
			break;
425
		}
426
	}
427
	return f;
428
}
429
 
39 cycrow 430
String String::mid(int start, int end) const
431
{
432
	return this->substr(start, end - start);
433
}
8 cycrow 434
String String::left(long num) const
435
{
436
	if ( num < 0 )
437
		num = (long)this->length() + num;
438
	if ( num > (long)this->length() )
439
		num = (long)this->length();
440
 
441
	return this->substr(0, num);
442
}
443
 
444
String String::right(int num) const
445
{
446
	if ( num > 0 ) num -= (int)this->length();
447
	if ( num < -(int)this->length() ) num = -(int)this->length();
448
 
449
	return this->substr(-num);
450
}
451
 
39 cycrow 452
const String &String::readToEndOfLine(FILE *id, int *line, bool upper)
453
{
454
	(*this) == "";
455
	char c = fgetc ( id );
456
	if ( c == -1 )
457
		return (*this);
458
 
459
	while ( (c != 13) && (!feof(id)) && (c != '\n') )
460
	{
461
		(*this) += c;
462
		c = fgetc ( id );
463
	}
464
 
465
	if ( line )
466
		++(*line);
467
 
468
//	if ( upper )
469
	//	ToUpper ();
470
 
471
	return (*this);
472
}
473
 
8 cycrow 474
char *String::readToEndOfLine(char *data)
475
{
476
	return (char *)this->readToEndOfLine((unsigned char *)data);
477
}
478
unsigned char *String::readToEndOfLine(unsigned char *data)
479
{
480
	int pos = 0;
481
 
482
	// do until we get a line break
483
	while ( (data[pos] != 13) && (data[pos] != 0) && (data[pos] != '\n') ) {
484
		++pos;
485
	}
486
 
487
	if ( !pos ) {
488
		this->clear();
489
	}
490
	else {
491
		if ( pos > 2000 ) {
492
			char *d = new char[pos + 1];
493
			memcpy(d, data, pos);
494
			d[pos] = 0;
495
			*this = d;
496
			delete d;
497
		}
498
		else {
499
			char d[2000];
500
			memcpy(d, data, pos);
501
			d[pos] = 0;
502
			*this = d;
503
		}
504
	}
505
 
506
	if ( data[pos] == 0 ) return NULL;
507
	return data + (pos + 1);
508
}
509
 
14 cycrow 510
String String::replaceToken(const char *token, int from, const String &replace) const
511
{
512
	std::string newstr;
513
 
514
	int whichtok = 1;
515
	std::string::size_type lastPos = 0;
516
	std::string::size_type pos     = _token_nextPos(token, 0);
517
 
518
	while (std::string::npos != pos || std::string::npos != lastPos)
519
	{
520
		if ( whichtok == from )
521
		{
522
			if ( newstr != "" ) newstr = newstr + token;
523
			newstr = newstr + replace;
524
		}
525
		else
526
		{
527
			if ( newstr != "" ) newstr = newstr + token;
528
			newstr = newstr + this->substr(lastPos, pos - lastPos);
529
		}
530
 
531
		// Found a token, add it to the vector.
532
		whichtok++;
533
 
534
		if ( pos >= this->length() )
535
			break;
536
 
537
		// skip past token
538
		size_t i = 0;
539
		size_t max = strlen(token);
540
		lastPos = pos;
541
		while ( (i < max) && (token[i] == this->at(lastPos)) )
542
		{
543
			++i;
544
			++lastPos;
545
		}
546
 
547
		// get the next token
548
		pos = _token_nextPos(token, lastPos);
549
	}
550
	return newstr;
551
}
552
 
553
 
10 cycrow 554
String *String::tokenise(const char *token, int *max) const
555
{
556
	if ( empty() ) {
557
		*max = 0;
558
		return NULL;
559
	}
8 cycrow 560
 
10 cycrow 561
	*max = this->countToken(token);
8 cycrow 562
 
10 cycrow 563
	if ( (*max) <= 0 ) {
564
		*max = 0;
565
		return NULL;
566
	}
567
 
568
	String *newstr = (*max == 1) ? new String : new String[*max];
569
 
570
	int whichtok = 0;
571
	// get first token
572
	std::string::size_type lastPos = 0;
573
	std::string::size_type pos     = this->_token_nextPos(token, 0);
574
 
575
	while (std::string::npos != pos || std::string::npos != lastPos)
576
	{
577
		// set token
578
		if ( *max == 1 ) *newstr = this->substr(lastPos, pos - lastPos);
579
		else			  newstr[whichtok] = this->substr(lastPos, pos - lastPos);
580
 
581
		// move to next token
582
		whichtok++;
583
		if ( whichtok >= *max )
584
			break;
585
 
586
		if ( pos >= this->length() )
587
			break;
588
 
589
		// skip past token
590
		size_t i = 0;
591
		size_t max = strlen(token);
592
		lastPos = pos;
593
		while ( (i < max) && (token[i] == this->at(lastPos)) ) {
594
			++i;
595
			++lastPos;
596
		}
597
 
598
		// get the next token
599
		pos = _token_nextPos(token, lastPos);
600
	}
601
 
602
	return newstr;
603
}
604
 
39 cycrow 605
const String &String::removeChar(char c)
10 cycrow 606
{
607
	std::string::size_type pos = this->find_first_of(c, 0);
608
	while(pos != std::string::npos) {
609
		this->erase(pos, 1);
610
		pos = this->find_first_of(c, 0);
611
	}
612
 
613
	return (*this);
614
}
615
 
39 cycrow 616
String String::remove(char c) const
10 cycrow 617
{
618
	String newStr = *this;
619
 
620
	std::string::size_type pos = newStr.find_first_of(c, 0);
621
	while(pos != std::string::npos) {
622
		newStr.erase(pos, 1);
623
		pos = newStr.find_first_of(c, 0);
624
	}
625
 
626
	return newStr;
627
}
628
 
13 cycrow 629
bool String::_isCharNumber(char c) const
630
{
631
	return (c >= '0' && c <= '9') ? true : false;
632
}
633
 
634
bool String::isCharNumber(int c) const
635
{
636
	return _isCharNumber(this->at(c));
637
}
638
 
639
bool String::isNumber(bool integer) const
640
{
641
	bool foundpoint = integer;
642
	for ( int i = 0; i < (int)this->length(); i++ )
643
	{
644
		// check for a decimal point (floating point value)
645
		// only allow 1 decimal point, or none if just checking for an integer
646
		if ( this->at(i) == '.' && !foundpoint ) foundpoint = true;
647
		// check if it is a number, 0-9
648
		else if ( !this->isCharNumber(i) ) return false;
649
	}
650
	return true;
651
}
14 cycrow 652
 
653
const String &String::removeFirstSpace()
654
{
39 cycrow 655
	std::string::size_type pos = this->find_first_not_of(" \t\f\v\n\r", 0);
14 cycrow 656
	if ( pos != std::string::npos ) {
657
		this->erase(0, pos);
658
	}
659
	return (*this);
660
}
39 cycrow 661
const String &String::removeEndSpace()
662
{
663
	std::string::size_type pos = this->find_last_not_of(" \t\f\v\n\r");
664
	if ( pos != std::string::npos ) {
665
		this->erase(pos + 1);
666
	}
667
	return (*this);
668
}
14 cycrow 669
 
34 cycrow 670
const String &String::truncate(int iNum)
671
{
672
	size_t pos = iNum;
673
	if ( iNum < 0 ) pos = this->length() + iNum;
674
	this->erase(pos, this->length() - pos);
675
	return (*this);
676
}
677
 
43 cycrow 678
String String::lower() const
679
{
680
	Utils::String newStr(*this);
681
	std::transform(this->begin(), this->end(), newStr.begin(), tolower);
682
	return newStr;
683
}
684
 
685
String String::upper() const
686
{
687
	Utils::String newStr(*this);
688
	std::transform(this->begin(), this->end(), newStr.begin(), toupper);
689
	return newStr;
690
}
691
const String &String::toLower()
692
{
693
	std::transform(this->begin(), this->end(), this->begin(), tolower);
694
	return (*this);
695
}
696
 
697
const String &String::toUpper()
698
{
699
	std::transform(this->begin(), this->end(), this->begin(), toupper);
700
	return (*this);
701
}
702
 
8 cycrow 703
}//NAMESPACE