Subversion Repositories spk

Rev

Rev 34 | 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>
5
 
6
namespace Utils {
7
 
13 cycrow 8
String operator+(const char *str1, const String &str2)
9
{
10
	return String(str1) + str2;
11
}
12
 
13
 
8 cycrow 14
String::String(void)						{ this->assign(""); }
15
String::String(const char *str)				{ this->assign(str); }
16
String::String(const unsigned char *str)	{ this->assign((const char *)str); }
17
String::String(const std::string &str)		{ this->assign(str);}
18
String::String(const unsigned char c)		{ this->assign(1, c); }
14 cycrow 19
String::String(const char c)				{ this->assign(1, c); }
8 cycrow 20
String::String(const String &str)			{ this->assign(str); }
21
String::String(long l)						{ this->fromLong(l); }
22
String::String(unsigned long l)				{ this->fromLong((long)l); }
23
String::String(float f)						{ this->fromFloat(f); }
24
String::String(double f)					{ this->fromDouble(f); }
25
 
26
String::~String(void)
27
{
28
}
29
 
30
/////////////////////////////////////////////////////////////////
31
// Conversion functions
32
 
33
void String::fromLong(long l)
34
{
35
	std::stringstream strstream;
36
	strstream << l;
14 cycrow 37
	*this = strstream.str();
8 cycrow 38
}
39
 
40
void String::fromFloat(float f, int dp)
41
{
42
	std::stringstream strstream;
43
	strstream.precision(dp);
44
	strstream << std::fixed << f;
14 cycrow 45
	*this = strstream.str();
8 cycrow 46
}
47
 
48
void String::fromFloat(float f)
49
{
50
	std::stringstream strstream;
51
	strstream << f;
14 cycrow 52
	*this = strstream.str();
8 cycrow 53
}
54
void String::fromDouble(double f)
55
{
56
	std::stringstream strstream;
57
	strstream << f;
14 cycrow 58
	*this = strstream.str();
8 cycrow 59
}
60
 
61
const String &String::format(const char *sFormat, ...)
62
{
63
	char buffer[1024];
64
	va_list args;
65
	va_start (args, sFormat);
66
	vsprintf (buffer, sFormat, args);
67
	va_end (args);
68
 
69
	this->assign(buffer);
70
	return (*this);
71
}
72
 
73
String String::fromFormat(const char *sFormat, ...)
74
{
75
	char buffer[1024];
76
	va_list args;
77
	va_start (args, sFormat);
78
	vsprintf (buffer, sFormat, args);
79
	va_end (args);
80
 
81
	return String(buffer);
82
}
83
 
84
long String::toLong() const
85
{
86
	return atoi(this->c_str());
87
}
88
double String::toDouble() const
89
{
90
	return atof(this->c_str());
91
}
92
float String::toFloat() const
93
{
94
	return (float)atof(this->c_str());
95
}
96
 
97
 
98
const String &String::operator= ( const char *str )				{ this->assign(str); return (*this); }
99
const String &String::operator= ( const unsigned char *str )	{ this->assign((const char *)str); return (*this); }
100
const String &String::operator= ( const String &str )			{ this->assign((std::string &)str); return (*this); }
101
const String &String::operator= ( const std::string &str )		{ this->assign(str); return (*this); }
102
const String &String::operator= ( unsigned char c )				{ this->assign(1, c); return (*this); }
103
const String &String::operator= ( char c )						{ this->assign(1, c); return (*this); }
104
const String &String::operator= ( long l )						{ this->fromLong(l); return (*this); }
105
const String &String::operator= ( unsigned long l )				{ this->fromLong(l); return (*this); }
106
const String &String::operator= ( float f )						{ this->fromFloat(f); return (*this); }
107
const String &String::operator= ( double f )					{ this->fromDouble(f); return (*this); }
108
 
109
const unsigned char String::operator[] ( int num ) const			{ return this->at(num); }
110
unsigned char &String::operator[] ( int num )						{ return (unsigned char &)this->at(num); }
111
 
112
const String &String::operator+= ( const char *str )			{ this->append(str); return (*this); }
113
const String &String::operator+= ( const unsigned char *str ) 	{ this->append((const char *)str); return (*this); }
114
const String &String::operator+= ( const std::string &str )		{ this->append(str); return (*this); }
115
const String &String::operator+= ( const String &str )		{ this->append(str); return (*this); }
116
const String &String::operator+= ( const char c )				{ this->append(1, c); return (*this); }
117
const String &String::operator+= ( const unsigned char c )		{ this->append(1, c); return (*this); }
118
const String &String::operator+= ( const unsigned long l )		
119
{ 
120
	std::stringstream strm;
121
	strm << (*this) << l;
122
	strm >> (*this);
123
	return (*this); 
124
}
125
const String &String::operator+= ( const long l )		
126
{ 
127
	std::stringstream strm;
128
	strm << (*this) << l;
14 cycrow 129
	*this = strm.str();
8 cycrow 130
	return (*this); 
131
}
132
const String &String::operator+= ( const float f )		
133
{ 
134
	std::stringstream strm;
135
	strm << (*this) << f;
14 cycrow 136
	*this = strm.str();
8 cycrow 137
	return (*this); 
138
}
139
const String &String::operator+= ( const double f )		
140
{ 
141
	std::stringstream strm;
142
	strm << (*this) << f;
14 cycrow 143
	*this = strm.str();
8 cycrow 144
	return (*this); 
145
}
146
 
147
 
148
String String::operator+ ( const char *str ) const			{ return String(*this) += str; }
149
String String::operator+ ( const unsigned char *str ) const	{ return String(*this) += str; }
150
String String::operator+ ( const std::string &str ) const	{ return String(*this) += str; }
151
String String::operator+ ( const String &str ) const		{ return String(*this) += str; }
152
String String::operator+ ( const char c ) const				{ return String(*this) += c; }
153
String String::operator+ ( const unsigned char c ) const	{ return String(*this) += c; }
154
String String::operator+ ( const long l ) const				{ return String(*this) += l; }
155
String String::operator+ ( const unsigned long l ) const	{ return String(*this) += l; }
156
String String::operator+ ( const float f ) const			{ return String(*this) += f; }
157
String String::operator+ ( const double f ) const			{ return String(*this) += f; }
158
 
159
bool String::operator== ( const char *str ) const				{ return (this->compare(str)) ? false : true; }
160
bool String::operator== ( const unsigned char *str ) const	{ return (this->compare((const char *)str)) ? false : true; }
161
bool String::operator== ( const std::string &str ) const		{ return (this->compare(str)) ? false : true; }
162
bool String::operator== ( const String &str ) const			{ return (this->compare(str)) ? false : true; }
163
 
164
bool String::operator!= ( const char *str ) const				{ return (this->compare(str)) ? true : false; }
165
bool String::operator!= ( const unsigned char *str ) const	{ return (this->compare((const char *)str)) ? true : false; }
166
bool String::operator!= ( const std::string &str ) const		{ return (this->compare(str)) ? true : false; }
167
bool String::operator!= ( const String &str ) const			{ return (this->compare(str)) ? true : false; }
168
 
169
bool String::Compare(const String &str, bool bCaseSensative) const
170
{
171
	if ( bCaseSensative ) {
172
		return (this->compare(str) == 0) ? true : false;
173
	}
174
 
175
	if ( str.length() != this->length() ) return false;
176
	for ( unsigned int i = 0; i < str.length(); i++ ) {
177
		if ( tolower(this->at(i)) != tolower(str[i]) ) {
178
			return false;
179
		}
180
	}
181
	return true;
182
}
183
 
184
bool String::Compare(const unsigned char *str, bool bCaseSensative) const
185
{
186
	return this->Compare((const char *)str, bCaseSensative);
187
}
188
 
189
bool String::Compare(const char *str, bool bCaseSensative) const
190
{
191
	if ( bCaseSensative ) {
192
		return (this->compare(str) == 0) ? true : false;
193
	}
194
 
195
	if ( strlen(str) != this->length() ) return false;
196
	for ( unsigned int i = 0; i < this->length(); i++ ) {
197
		if ( tolower(this->at(i)) != tolower(*(str + i)) ) {
198
			return false;
199
		}
200
	}
201
 
202
	return true;
203
}
204
 
205
String String::token(const char *token, int tok) const
206
{
207
	return this->tokens(token, tok, tok);
208
}
209
 
210
String String::tokens(const char *token, int from, int to) const
211
{
212
	if ( this->empty() ) return "";
213
 
214
	int max = this->countToken(token);
215
 
216
	std::string newstr;
217
 
218
	int whichtok = 1;
219
	std::string::size_type lastPos = 0;
220
	std::string::size_type pos     = _token_nextPos(token, 0);
221
 
222
	if ( from < 0 )
223
		from = max + (from + 1);
224
	if ( to < 0 )
225
		to = max + (to + 1);
226
 
227
	while (std::string::npos != pos || std::string::npos != lastPos)
228
	{
229
		if ( to == 0 )
230
		{
231
			if ( whichtok >= from )
232
			{
233
				if ( newstr != "" ) newstr = newstr + token;
234
				newstr = newstr + this->substr(lastPos, pos - lastPos);
235
			}
236
		}
237
		else
238
		{
239
			if ( (whichtok >= from) && (whichtok <= to) )
240
			{
241
				if ( newstr != "" ) newstr = newstr + token;
242
				newstr = newstr + this->substr(lastPos, pos - lastPos);
243
			}
244
			if ( whichtok > to )
245
				break;
246
		}
247
		// Found a token, add it to the vector.
248
		whichtok++;
249
 
250
		if ( pos >= this->length() )
251
			break;
252
 
253
		// skip past token
254
		size_t i = 0;
255
		size_t max = strlen(token);
256
		lastPos = pos;
257
		while ( (i < max) && (token[i] == this->at(lastPos)) )
258
		{
259
			++i;
260
			++lastPos;
261
		}
262
 
263
		// get the next token
264
		pos = _token_nextPos(token, lastPos);
265
	}
266
	return newstr;
267
}
268
 
269
int String::countToken(const char *token) const
270
{
271
	if ( this->empty() )
272
		return 0;
273
 
274
	// finds the number of tokens in a string
275
	int found = 1;
276
 
277
	std::string tmpstr = *this;
278
 
279
	// ignore the initial spaces
280
	std::string::size_type pos = this->find_first_not_of(token, 0);
281
 
282
	// remove end spaces
283
	size_t i = tmpstr.size() - 1;
284
	while ( tmpstr[i] == ' ' && i > 0 )
285
		i--;
286
	if ( i <= 0 ) return 0;
287
	tmpstr.erase ( i + 1, tmpstr.size() - i );
288
 
289
	// count tokens
290
	pos = tmpstr.find (token,pos + 1);
291
	while ( pos < std::string::npos )
292
	{
293
		while (tmpstr[pos] == ' ')
294
			pos++;
295
		found++;
296
		pos = tmpstr.find (token,pos + 1);
297
	}
298
 
299
	// return number of tokens
300
	return found;
301
}
302
 
303
std::string::size_type String::_token_nextPos(const char *token, std::string::size_type curPos) const
304
{
305
	bool found = false;
306
	std::string::size_type startPos = 0;
307
	size_t max = strlen(token);
308
	while ( !found ) {
309
		found = true;
310
		startPos = this->find_first_of(token[0], curPos);
311
		if ( startPos == std::string::npos ) {
312
			startPos = this->length();
313
			break;
314
		}
315
 
316
		std::string::size_type pos = startPos;
317
		size_t i = 1;
318
		while ( i < max )
319
		{
320
			++pos;
321
			if ( this->at(pos) != token[i] )
322
			{
323
				found = false;
324
				break;
325
			}
326
			++i;
327
		}
328
		curPos = pos;
329
	}
330
	return startPos;
331
}
332
 
333
String String::findReplace(const String &find, const String &replace ) const
334
{
335
	std::string newstr = *this;
336
	std::string::size_type pos = newstr.find(find, 0);
337
	while ( pos < std::string::npos ) {
338
		newstr.replace(pos, find.length(), replace);
339
		pos = newstr.find(find, pos + replace.length());
340
	}
341
 
342
	return newstr;
343
}
344
 
345
bool String::isin(const String &str, bool bCaseSensative) const
346
{
347
	unsigned int check = 0;
348
	for ( unsigned int i = 0; i < this->length(); i++ )
349
	{
350
		bool bCheck	= (bCaseSensative) ? (this->at(i) == str[check]) : (tolower(this->at(i)) == tolower(str[check]));
351
		if ( bCheck )
352
			++check;
353
		else
354
			check = 0;
355
 
356
		if ( check >= str.length() )
357
			return true;
358
	}
359
	return false;
360
}
361
 
362
bool String::isin(char c, bool bCaseSensative) const
363
{
364
	bool f = false;
365
	for ( unsigned int i = 0; i < this->length(); i++ )
366
	{
367
		bool bCheck = (bCaseSensative) ? (this->at(i) == c) : (tolower(this->at(i)) == tolower(c));
368
		if ( bCheck ) {
369
			f = true;
370
			break;
371
		}
372
	}
373
	return f;
374
}
375
 
376
String String::left(long num) const
377
{
378
	if ( num < 0 )
379
		num = (long)this->length() + num;
380
	if ( num > (long)this->length() )
381
		num = (long)this->length();
382
 
383
	return this->substr(0, num);
384
}
385
 
386
String String::right(int num) const
387
{
388
	if ( num > 0 ) num -= (int)this->length();
389
	if ( num < -(int)this->length() ) num = -(int)this->length();
390
 
391
	return this->substr(-num);
392
}
393
 
394
char *String::readToEndOfLine(char *data)
395
{
396
	return (char *)this->readToEndOfLine((unsigned char *)data);
397
}
398
unsigned char *String::readToEndOfLine(unsigned char *data)
399
{
400
	int pos = 0;
401
 
402
	// do until we get a line break
403
	while ( (data[pos] != 13) && (data[pos] != 0) && (data[pos] != '\n') ) {
404
		++pos;
405
	}
406
 
407
	if ( !pos ) {
408
		this->clear();
409
	}
410
	else {
411
		if ( pos > 2000 ) {
412
			char *d = new char[pos + 1];
413
			memcpy(d, data, pos);
414
			d[pos] = 0;
415
			*this = d;
416
			delete d;
417
		}
418
		else {
419
			char d[2000];
420
			memcpy(d, data, pos);
421
			d[pos] = 0;
422
			*this = d;
423
		}
424
	}
425
 
426
	if ( data[pos] == 0 ) return NULL;
427
	return data + (pos + 1);
428
}
429
 
14 cycrow 430
String String::replaceToken(const char *token, int from, const String &replace) const
431
{
432
	std::string newstr;
433
 
434
	int whichtok = 1;
435
	std::string::size_type lastPos = 0;
436
	std::string::size_type pos     = _token_nextPos(token, 0);
437
 
438
	while (std::string::npos != pos || std::string::npos != lastPos)
439
	{
440
		if ( whichtok == from )
441
		{
442
			if ( newstr != "" ) newstr = newstr + token;
443
			newstr = newstr + replace;
444
		}
445
		else
446
		{
447
			if ( newstr != "" ) newstr = newstr + token;
448
			newstr = newstr + this->substr(lastPos, pos - lastPos);
449
		}
450
 
451
		// Found a token, add it to the vector.
452
		whichtok++;
453
 
454
		if ( pos >= this->length() )
455
			break;
456
 
457
		// skip past token
458
		size_t i = 0;
459
		size_t max = strlen(token);
460
		lastPos = pos;
461
		while ( (i < max) && (token[i] == this->at(lastPos)) )
462
		{
463
			++i;
464
			++lastPos;
465
		}
466
 
467
		// get the next token
468
		pos = _token_nextPos(token, lastPos);
469
	}
470
	return newstr;
471
}
472
 
473
 
10 cycrow 474
String *String::tokenise(const char *token, int *max) const
475
{
476
	if ( empty() ) {
477
		*max = 0;
478
		return NULL;
479
	}
8 cycrow 480
 
10 cycrow 481
	*max = this->countToken(token);
8 cycrow 482
 
10 cycrow 483
	if ( (*max) <= 0 ) {
484
		*max = 0;
485
		return NULL;
486
	}
487
 
488
	String *newstr = (*max == 1) ? new String : new String[*max];
489
 
490
	int whichtok = 0;
491
	// get first token
492
	std::string::size_type lastPos = 0;
493
	std::string::size_type pos     = this->_token_nextPos(token, 0);
494
 
495
	while (std::string::npos != pos || std::string::npos != lastPos)
496
	{
497
		// set token
498
		if ( *max == 1 ) *newstr = this->substr(lastPos, pos - lastPos);
499
		else			  newstr[whichtok] = this->substr(lastPos, pos - lastPos);
500
 
501
		// move to next token
502
		whichtok++;
503
		if ( whichtok >= *max )
504
			break;
505
 
506
		if ( pos >= this->length() )
507
			break;
508
 
509
		// skip past token
510
		size_t i = 0;
511
		size_t max = strlen(token);
512
		lastPos = pos;
513
		while ( (i < max) && (token[i] == this->at(lastPos)) ) {
514
			++i;
515
			++lastPos;
516
		}
517
 
518
		// get the next token
519
		pos = _token_nextPos(token, lastPos);
520
	}
521
 
522
	return newstr;
523
}
524
 
525
const String &String::remove(char c)
526
{
527
	std::string::size_type pos = this->find_first_of(c, 0);
528
	while(pos != std::string::npos) {
529
		this->erase(pos, 1);
530
		pos = this->find_first_of(c, 0);
531
	}
532
 
533
	return (*this);
534
}
535
 
536
String String::removeChar(char c) const
537
{
538
	String newStr = *this;
539
 
540
	std::string::size_type pos = newStr.find_first_of(c, 0);
541
	while(pos != std::string::npos) {
542
		newStr.erase(pos, 1);
543
		pos = newStr.find_first_of(c, 0);
544
	}
545
 
546
	return newStr;
547
}
548
 
13 cycrow 549
bool String::_isCharNumber(char c) const
550
{
551
	return (c >= '0' && c <= '9') ? true : false;
552
}
553
 
554
bool String::isCharNumber(int c) const
555
{
556
	return _isCharNumber(this->at(c));
557
}
558
 
559
bool String::isNumber(bool integer) const
560
{
561
	bool foundpoint = integer;
562
	for ( int i = 0; i < (int)this->length(); i++ )
563
	{
564
		// check for a decimal point (floating point value)
565
		// only allow 1 decimal point, or none if just checking for an integer
566
		if ( this->at(i) == '.' && !foundpoint ) foundpoint = true;
567
		// check if it is a number, 0-9
568
		else if ( !this->isCharNumber(i) ) return false;
569
	}
570
	return true;
571
}
14 cycrow 572
 
573
const String &String::removeFirstSpace()
574
{
575
	std::string::size_type pos = this->find_first_not_of(" ", 0);
576
	if ( pos != std::string::npos ) {
577
		this->erase(0, pos);
578
	}
579
	return (*this);
580
}
581
 
34 cycrow 582
const String &String::truncate(int iNum)
583
{
584
	size_t pos = iNum;
585
	if ( iNum < 0 ) pos = this->length() + iNum;
586
	this->erase(pos, this->length() - pos);
587
	return (*this);
588
}
589
 
8 cycrow 590
}//NAMESPACE