00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef _STRINGUTIL_H_
00031 #define _STRINGUTIL_H_
00032
00033
00034
00035
00036 #include <algorithm>
00037 #include <iterator>
00038 #include <sstream>
00039 #include <string>
00040 #include <limits>
00041
00042
00043
00044
00045
00046 namespace {
00047 }
00048
00049
00050
00051 namespace OSB_LIB {
00056 extern const std::string posixWs;
00057
00064 void ltrim(
00065 std::string& s,
00066 const std::string& d = posixWs
00067 );
00068
00075 void rtrim(
00076 std::string& s,
00077 const std::string& d = posixWs
00078 );
00079
00086 void trim(
00087 std::string& s,
00088 const std::string& d = posixWs
00089 );
00090
00098 bool endsWith(
00099 const std::string& str,
00100 const std::string& what
00101 );
00102
00112 std::string lstrip(
00113 const std::string& from,
00114 const std::string& what
00115 );
00116
00126 std::string rstrip(
00127 const std::string& from,
00128 const std::string& what
00129 );
00130
00141 void escapeChars(
00142 std::string& str,
00143 const char esc,
00144 size_t maxLen
00145 );
00146
00154 bool decDigitsOnly(
00155 const std::string& s
00156 );
00157
00165 bool hexDigitsOnly(
00166 const std::string& s
00167 );
00168
00180 template<typename Cont>
00181 void tokenize(
00182 Cont& dest,
00183 const std::string& src,
00184 const std::string& del,
00185 bool takeEmpty = false
00186 );
00187
00199 template<typename Cont>
00200 void tokenize(
00201 Cont& dest,
00202 const std::string& src
00203 );
00204
00220 template<typename Cont>
00221 void stringTokenize(
00222 Cont& dest,
00223 const std::string& src,
00224 const std::string& del,
00225 bool takeEmpty = true
00226 );
00227
00240 template<typename T>
00241 bool ston(
00242 T* dest,
00243 const std::string& src,
00244 std::string* reminder = 0
00245 );
00246
00256 template<typename T>
00257 std::string mkStr(const T& src);
00258
00276 template<typename S = std::string>
00277 struct StrCmp : public std::binary_function<S, S, int> {
00279 explicit StrCmp(bool ignoreCase = false)
00280 : ignoreCase_(ignoreCase)
00281 {
00282
00283 }
00284
00294 int operator()(
00295 const S& lhs,
00296 const S& rhs
00297 ) const;
00298 private:
00300 bool ignoreCase_;
00301 };
00302
00310 template<typename S = std::string>
00311 struct LessStr : public std::binary_function<S, S, bool> {
00313 explicit LessStr(bool ignoreCase = false)
00314 : ignoreCase_(ignoreCase)
00315 {
00316
00317 }
00318
00320 bool operator()(
00321 const S& lhs,
00322 const S& rhs
00323 ) const
00324 {
00325 return 0 > StrCmp<S>(ignoreCase_)(lhs, rhs);
00326 }
00327 private:
00329 bool ignoreCase_;
00330 };
00331
00339 template<typename S = std::string>
00340 struct GreaterStr : public std::binary_function<S, S, bool> {
00342 explicit GreaterStr(bool ignoreCase = false)
00343 : ignoreCase_(ignoreCase)
00344 {
00345
00346 }
00347
00349 inline bool operator()(
00350 const S& lhs,
00351 const S& rhs
00352 ) const
00353 {
00354 return 0 < StrCmp<S>(ignoreCase_)(lhs, rhs);
00355 }
00356 private:
00358 bool ignoreCase_;
00359 };
00360
00372 template<typename T, typename S = std::string>
00373 struct LessName : public std::binary_function<T, T, bool> {
00375 explicit LessName(bool ignoreCase = false)
00376 : ignoreCase_(ignoreCase)
00377 {
00378
00379 }
00380
00382 inline bool operator()(
00383 const T& lhs,
00384 const T& rhs
00385 ) const
00386 {
00387 return LessStr<S>(ignoreCase_)(lhs.name(), rhs.name());
00388 }
00389 private:
00391 bool ignoreCase_;
00392 };
00393
00406 template<typename T, typename S>
00407 struct LessName<T*, S> : public std::binary_function<T, T, bool> {
00409 LessName(bool ignoreCase = false)
00410 : ignoreCase_(ignoreCase)
00411 {
00412 }
00413
00415 inline bool operator()(
00416 const T* lhs,
00417 const T* rhs
00418 ) const
00419 {
00420 return LessStr<S>(ignoreCase_)(lhs->name(), rhs->name());
00421 }
00422 private:
00424 bool ignoreCase_;
00425 };
00426
00459 template<typename T, typename S = std::string>
00460 struct GreaterName : public std::binary_function<T, T, bool> {
00462 GreaterName(bool ignoreCase = false)
00463 : ignoreCase_(ignoreCase)
00464 {
00465 }
00466
00468 inline bool operator()(
00469 const T& lhs,
00470 const T& rhs
00471 ) const
00472 {
00473 return GreaterStr<S>(ignoreCase_)(lhs.name(), rhs.name());
00474 }
00475 private:
00477 bool ignoreCase_;
00478 };
00479
00490 template<typename T, typename S>
00491 struct GreaterName<T*, S> : public std::binary_function<T, T, bool> {
00493 GreaterName(bool ignoreCase = false)
00494 : ignoreCase_(ignoreCase)
00495 {
00496 }
00497
00499 inline bool operator()(
00500 const T* lhs,
00501 const T* rhs
00502 ) const
00503 {
00504 return GreaterStr<S>(ignoreCase_)(lhs->name(), rhs->name());
00505 }
00506 private:
00508 bool ignoreCase_;
00509 };
00510 }
00511
00512
00513
00514 namespace OSB_LIB {
00515 template<typename Cont>
00516 void tokenize(
00517 Cont& dest,
00518 const std::string& src,
00519 const std::string& del,
00520 bool takeEmpty
00521 )
00522 {
00523 using std::string;
00524 string::size_type len = src.length();
00525 string::size_type startPos = 0;
00526 string::size_type endPos = string::npos;
00527
00528 dest.clear();
00529 while (startPos < len) {
00530 if (!takeEmpty) {
00531
00532 startPos = src.find_first_not_of(del, startPos);
00533
00534 if (string::npos == startPos) return;
00535 }
00536
00537
00538 endPos = src.find_first_of(del, startPos);
00539
00540 if (string::npos != endPos) {
00541 dest.push_back(src.substr(startPos, endPos-startPos));
00542
00543 startPos = endPos+1;
00544 }
00545
00546 else {
00547 dest.push_back(src.substr(startPos));
00548 return;
00549 }
00550 }
00551
00552 if (takeEmpty && string::npos != endPos) {
00553 dest.push_back(src.substr(endPos+1));
00554 }
00555 }
00556
00557 template<typename Cont>
00558 inline void tokenize(
00559 Cont& dest,
00560 const std::string& src
00561 )
00562 {
00563 return tokenize(dest, src, posixWs);
00564 }
00565
00566 template<typename Cont>
00567 void stringTokenize(
00568 Cont& dest,
00569 const std::string& src,
00570 const std::string& del,
00571 bool takeEmpty
00572 )
00573 {
00574 using std::string;
00575
00576 dest.clear();
00577
00578
00579
00580 if (del.empty()) {
00581 dest.push_back(src);
00582 if (!takeEmpty && dest.back().empty()) dest.pop_back();
00583 return;
00584 }
00585
00586 string::size_type srclen = src.length();
00587 string::size_type dellen = del.length();
00588 string::size_type startPos = 0;
00589
00590 while (startPos < srclen) {
00591
00592 string::size_type endPos = src.find(del, startPos);
00593
00594 if (string::npos == endPos) break;
00595
00596
00597 dest.push_back(src.substr(startPos, endPos-startPos));
00598 if (!takeEmpty && dest.back().empty()) dest.pop_back();
00599
00600 startPos = endPos + dellen;
00601 }
00602 dest.push_back(src.substr(startPos));
00603 if (!takeEmpty && dest.back().empty()) dest.pop_back();
00604 }
00605
00606 template<typename T>
00607 bool ston(
00608 T* dest,
00609 const std::string& src,
00610 std::string* reminder
00611 )
00612 {
00613 typedef std::istream_iterator<char> Iter;
00614
00615 bool rc = false;
00616 T t = T();
00617
00618 std::numeric_limits<T> limits;
00619 if (limits.is_integer) {
00620 char* err = 0;
00621
00622 if (limits.is_signed) t = strtol(src.c_str(), &err, 0);
00623 else t = strtoul(src.c_str(), &err, 0);
00624
00625 if (0 == err || 0 == *err) {
00626 rc = true;
00627 }
00628 else if (0 != reminder) {
00629 *reminder = std::string(err);
00630 }
00631 }
00632 else {
00633 std::istringstream is(src);
00634 is >> t;
00635 rc = is && is.eof();
00636
00637 if (!rc && 0 != reminder) {
00638 is.clear();
00639 is >> std::noskipws;
00640 std::copy(Iter(is), Iter(), std::back_inserter(*reminder));
00641 }
00642 }
00643
00644 if (rc) *dest = t;
00645 return rc;
00646 }
00647
00648 template<typename T>
00649 std::string mkStr(const T& src)
00650 {
00651 std::ostringstream rc;
00652 rc << src;
00653 return rc.str();
00654 }
00655
00656
00657
00658 template<typename S> int StrCmp<S>::operator()(
00659 const S& lhs,
00660 const S& rhs
00661 ) const
00662 {
00663 typedef typename S::const_iterator Iter;
00664
00665 if (!ignoreCase_) return lhs.compare(rhs);
00666
00667 Iter le = lhs.end();
00668 Iter re = rhs.end();
00669 Iter li = lhs.begin();
00670 Iter ri = rhs.begin();
00671
00672 for (;li != le && ri != re; ++li, ++ri) {
00673 char l = toupper(*li);
00674 char r = toupper(*ri);
00675 if (l != r) {
00676 return (l < r) ? -1 : 1;
00677 }
00678 }
00679
00680 if (li == le && ri == re) {
00681
00682 return 0;
00683 }
00684 else if (li == le) {
00685
00686 return -1;
00687 }
00688
00689 return 1;
00690 }
00691 }
00692 #endif // #ifndef _STRINGUTIL_H_