1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
18 #ifndef PDSLIB_STRING_H
19 #define PDSLIB_STRING_H
24 class CSString
: public std::string
31 CSString(const char *s
)
33 *(std::string
*)this=s
;
36 CSString(const std::string
&s
)
38 *(std::string
*)this=s
;
43 *(std::string
*)this=c
;
46 CSString(int i
,const char *fmt
="%d")
53 CSString(unsigned u
,const char *fmt
="%u")
60 CSString(double d
,const char *fmt
="%f")
67 CSString(const char *s
,const char *fmt
)
74 CSString(const std::string
&s
,const char *fmt
)
77 sprintf(buf
,fmt
,s
.c_str());
88 // return the n right hand most characters of a string
89 CSString
right(unsigned count
) const
93 return substr(size()-count
);
96 // return the string minus the n right hand most characters of a string
97 CSString
rightCrop(unsigned count
) const
101 return substr(0,size()-count
);
104 // return the n left hand most characters of a string
105 CSString
left(unsigned count
) const
107 return substr(0,count
);
110 // return the string minus the n left hand most characters of a string
111 CSString
leftCrop(unsigned count
) const
115 return substr(count
);
118 // return sub string up to but not including first instance of given character
119 CSString
splitTo(char c
,bool truncateThis
=false)
123 for (i
=0;i
<size() && (*this)[i
]!=c
;++i
)
126 // remove the result string from the input string if so desired
130 (*this)=substr(i
+1); // +1 to skip the separator character
138 // return sub string up to but not including first instance of given character
139 CSString
splitTo(const char *s
,bool truncateThis
=false)
143 for (i
=0;i
<size();++i
)
145 // perform a quick string compare
147 for (j
=0;s
[j
]!=0 && s
[j
]==(&((*this)[i
]))[j
];++j
)
150 // if string compare matched then return result so far
153 // remove the result string from the input string if so desired
157 (*this)=substr(i
+1); // +1 to skip the separator character
166 // we didn't find the separator string so we're returning a copy of the whole string
172 // return sub string from character following first instance of given character on
173 CSString
splitFrom(char c
) const
176 std::string::const_iterator it
;
177 for (it
=begin();it
!=end() && *it
!=c
;++it
)
182 for (;it
!=end();++it
)
188 // return sub string from character following first instance of given character on
189 CSString
splitFrom(const char *s
) const
193 for (i
=0;i
<size();++i
)
195 // perform a quick string compare
197 for (j
=0;i
+j
<size() && s
[j
]!=0 && s
[j
]==(*this)[i
+j
];++j
)
200 // if string compare matched then build and return a result
210 // behave like a s strtok() routine, returning the sun string extracted from (and removed from) *this
211 CSString
strtok(const char *separators
)
217 for (i
=0;i
<size();++i
)
219 // look for the next character in the 'separator' character list supplied
221 for (j
=0;separators
[j
] && (*this)[i
]!=separators
[j
];++j
)
223 // if not found then we're at end of leading junk
228 // copy out everything up to the next separator character
231 // look for the next character in the 'separator' character list supplied
233 for (j
=0;separators
[j
] && (*this)[i
]!=separators
[j
];++j
)
235 // if not found then we're at end of leading junk
241 // skip trailing junk
244 // look for the next character in the 'separator' character list supplied
246 for (j
=0;separators
[j
] && (*this)[i
]!=separators
[j
];++j
)
248 // if not found then we're at end of leading junk
253 // delete the treated bit from this string
259 // return first word (blank separated)
260 CSString
firstWord(bool truncateThis
=false)
265 for (i
=0;i
<size() && isWhiteSpace((*this)[i
]);++i
)
268 if ( ((*this)[i
]>='A' && (*this)[i
]<='Z') || ((*this)[i
]>='a' && (*this)[i
]<='z') ||
269 ((*this)[i
]>='0' && (*this)[i
]<='9') || (*this)[i
]=='_')
271 // copy out an alpha-numeric string
272 for (;i
<(*this).size() &&
273 ( ((*this)[i
]>='A' && (*this)[i
]<='Z') || ((*this)[i
]>='a' && (*this)[i
]<='z') ||
274 ((*this)[i
]>='0' && (*this)[i
]<='9') || (*this)[i
]=='_')
280 // just take the first character of the input
285 // remove the result string from the input string if so desired
297 CSString
firstWordConst() const
299 return const_cast<CSString
*>(this)->firstWord();
302 // return sub string up to but not including first instance of given character
303 CSString
tailFromFirstWord() const
306 hold
.firstWord(true);
310 // count the number of words (or quote delimited sub-strings) in a string
311 unsigned countWords() const
314 CSString hold
=strip();
315 while (!hold
.empty())
317 hold
=hold
.tailFromFirstWord().strip();
323 // count the number of words (or quote delimited sub-strings) in a string
324 CSString
word(unsigned idx
) const
326 CSString hold
=strip();
328 for (unsigned count
=0;count
<idx
;++count
)
329 hold
=hold
.tailFromFirstWord().strip();
331 return hold
.firstWord();
334 // return first word or quote-encompassed sub-string
335 CSString
firstWordOrWords(bool truncateThis
=false)
337 CSString hold
=strip();
339 return firstWord(truncateThis
);
341 // the string is quote enclosed
343 unsigned i
=1; // skip leading quote
344 // copy from character following opening quote to char preceding closing quote (or end of string)
345 while (i
<hold
.size() && hold
[i
]!='\"')
351 // remove the result string from the input string if so desired
355 (*this)=substr(i
+1); // +1 to skip the closing quote
363 CSString
firstWordOrWordsConst() const
365 return const_cast<CSString
*>(this)->firstWordOrWords();
368 // return sub string up to but not including first instance of given character
369 CSString
tailFromFirstWordOrWords() const
372 hold
.firstWordOrWords(true);
376 // count the number of words (or quote delimited sub-strings) in a string
377 unsigned countWordOrWords() const
380 CSString hold
=strip();
381 while (!hold
.empty())
383 hold
=hold
.tailFromFirstWordOrWords().strip();
389 // count the number of words (or quote delimited sub-strings) in a string
390 CSString
wordOrWords(unsigned idx
) const
392 CSString hold
=strip();
394 for (unsigned count
=0;count
<idx
;++count
)
395 hold
=hold
.tailFromFirstWordOrWords().strip();
397 return hold
.firstWordOrWords();
400 // a handy utility routine for knowing if a character is a white space character or not
401 static bool isWhiteSpace(char c
) { return c
==' ' || c
=='\t' || c
=='\n' || c
=='\r' || c
==26; }
403 // return a copy of the string with leading and trainling spaces rmoved
404 CSString
strip() const
408 for (j
=size()-1; j
>=0 && isWhiteSpace((*this)[j
]); --j
) {}
409 for (i
=0; i
<j
&& isWhiteSpace((*this)[i
]); ++i
) {}
415 // making an upper case copy of a string
416 CSString
toUpper() const
419 std::string::const_iterator it
;
420 for (it
=begin();it
!=end();++it
)
423 if (c
>='a' && c
<='z')
430 // making a lower case copy of a string
431 CSString
toLower() const
434 std::string::const_iterator it
;
435 for (it
=begin();it
!=end();++it
)
438 if (c
>='A' && c
<='Z')
445 // replacing all occurences of one string with another
446 CSString
replace(const char *toFind
,const char *replacement
) const
448 // just bypass the problems that can cause a crash...
449 if (toFind
==NULL
|| *toFind
==0)
456 // string compare toFind against (*this)+i ...
457 for (j
=0;toFind
[j
];++j
)
458 if ((*this)[i
+j
]!=toFind
[j
])
460 // if strings were identical then j reffers to ASCIIZ terminator at end of 'toFind'
463 if (replacement
!=NULL
)
476 // find index at which a sub-string starts - if sub-string not found then returns size()
477 unsigned find(const char *toFind
,unsigned startLocation
=0) const
479 // just bypass the problems that can cause a crash...
480 if (toFind
==NULL
|| *toFind
==0 || startLocation
>size())
484 for (i
=startLocation
;i
<size();++i
)
486 // string compare toFind against (*this)+i ...
487 for (j
=0;toFind
[j
];++j
)
488 if ((*this)[i
+j
]!=toFind
[j
])
490 // if strings were identical then we're done
497 // return true if this contains given sub string
498 bool contains(const char *toFind
) const
500 return find(toFind
)!=size();
503 // a couple of handy atoi routines...
504 template <class C
> bool atoi(C
& result
) const
506 result
=::atoi(c_str());
507 return (result
!=0 || *this=="0");
509 unsigned atoi() const
511 return ::atoi(c_str());
514 // a couple of handy atof routines...
515 template <class C
> bool atof(C
& result
) const
517 result
=::atof(c_str());
518 return (result
!=0 || *this=="0");
522 return ::atof(c_str());
525 // case insensitive string compare
526 bool operator==(const std::string
&other
) const
528 return stricmp(c_str(),other
.c_str())==0;
531 // case insesnsitive string compare
532 bool operator!=(const std::string
&other
) const
534 return !(*this==other
);