00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00035
00036
00037 #ifndef _MBOSTRHELPER_H_
00038 #define _MBOSTRHELPER_H_
00039
00040 #include "Mbo.h"
00041 #include "MboTString.h"
00042 #include <string>
00043 #include <sstream>
00044 #include <functional>
00045 #include <assert.h>
00046
00047 #if defined(_MSC_VER)
00048 # pragma warning(push)
00049 # pragma warning(disable: 4251) // disable warning C4251: '...' : class '...' needs to have dll-interface to be used by clients of class '...'
00050 # pragma warning(disable: 4275) // non dll-interface class '...' used as base for dll-interface class '...'
00051 #endif
00052
00053 #if defined(_MSC_VER) && (_MSC_VER < 1300 || !defined(snprintf))
00054 # define snprintf _snprintf
00055 #endif
00056
00057 namespace mbo {
00058
00059 template<class _E>
00060 inline _E* StrUpper(_IN _E *str)
00061 {
00062 #ifdef _STLPORT_VERSION
00063 MBO_MT_LOCAL_OR_STATIC const std::locale loc = std::locale::empty();
00064 #else
00065 MBO_MT_LOCAL_OR_STATIC const std::ctype<_E>& facet = get_facet<_E>();
00066 #endif
00067
00068 for (_E *pos = str; *pos; ++pos)
00069 {
00070 #ifdef _STLPORT_VERSION
00071 *pos = std::toupper(*pos, loc);
00072 #else
00073 *pos = facet.toupper(*pos);
00074 #endif
00075 }
00076 return str;
00077 }
00078
00079 template<>
00080 inline char* StrUpper(_IN char *str)
00081 {
00082 return _strupr(str);
00083 }
00084
00085 template<>
00086 inline unsigned char* StrUpper(_IN unsigned char *str)
00087 {
00088 return _mbsupr(str);
00089 }
00090
00091 template<>
00092 inline wchar_t* StrUpper(_IN wchar_t *str)
00093 {
00094 return _wcsupr(str);
00095 }
00096
00097 template<class _E, class _Tr, class _A>
00098 inline std::basic_string<_E, _Tr, _A> & StrUpper(_IN std::basic_string<_E, _Tr, _A> & str)
00099 {
00100 StrUpper(const_cast<_E*>(str.c_str()));
00101 return str;
00102 }
00103
00104 template<class _E>
00105 inline _E* StrLower(_E *str)
00106 {
00107 #ifdef _STLPORT_VERSION
00108 MBO_MT_LOCAL_OR_STATIC const std::locale loc = std::locale::empty();
00109 #else
00110 MBO_MT_LOCAL_OR_STATIC const std::ctype<_E>& facet = get_facet<_E>();
00111 #endif
00112
00113 for (_E *pos = str; *pos; ++pos)
00114 {
00115 #ifdef _STLPORT_VERSION
00116 *pos = std::tolower(*pos, loc);
00117 #else
00118 *pos = facet.tolower(*pos);
00119 #endif
00120 }
00121 return str;
00122 }
00123
00124 template<>
00125 inline char* StrLower(_IN char *str)
00126 {
00127 return _strlwr(str);
00128 }
00129
00130 template<>
00131 inline unsigned char* StrLower(_IN unsigned char *str)
00132 {
00133 return _mbslwr(str);
00134 }
00135
00136 template<>
00137 inline wchar_t* StrLower(_IN wchar_t *str)
00138 {
00139 return _wcslwr(str);
00140 }
00141
00142 template<class _E, class _Tr, class _A>
00143 inline std::basic_string<_E, _Tr, _A> & StrLower(_IN std::basic_string<_E, _Tr, _A> & str)
00144 {
00145 StrLower(const_cast<_E*>(str.c_str()));
00146 return str;
00147 }
00148
00149 template<class _E>
00150 inline int StrCompareIC(_IN const _E *lhs, _IN const _E *rhs)
00151 {
00152 #ifdef _STLPORT_VERSION
00153 MBO_MT_LOCAL_OR_STATIC const std::locale loc = std::locale::empty();
00154 #else
00155 MBO_MT_LOCAL_OR_STATIC const std::ctype<_E>& facet = get_facet<_E>();
00156 #endif
00157
00158 for (; *lhs && *rhs; ++lhs, ++rhs)
00159 {
00160 #ifdef _STLPORT_VERSION
00161 int i = std::tolower(*lhs, loc)
00162 - std::tolower(*rhs, loc);
00163 #else
00164 int i = facet.tolower(*lhs) - facet.tolower(*rhs);
00165 #endif
00166
00167 if (i)
00168 {
00169 return i;
00170 }
00171 }
00172
00173 return static_cast<int>(*lhs != 0) - static_cast<int>(*rhs != 0);
00174 }
00175
00176 template<>
00177 inline int StrCompareIC(_IN const char *lhs, _IN const char *rhs)
00178 {
00179 return _stricmp(lhs, rhs);
00180 }
00181
00182 template<>
00183 inline int StrCompareIC(_IN const unsigned char *lhs, _IN const unsigned char *rhs)
00184 {
00185 return _mbsicmp(lhs, rhs);
00186 }
00187
00188 template<>
00189 inline int StrCompareIC(_IN const wchar_t *lhs, _IN const wchar_t *rhs)
00190 {
00191 return _wcsicmp(lhs, rhs);
00192 }
00193
00194 template<class _E, class _Tr, class _A>
00195 inline int StrCompareIC(_IN const std::basic_string<_E, _Tr, _A>& lhs, _IN const _E *rhs)
00196 {
00197 return StrCompareIC(lhs.c_str(), rhs);
00198 }
00199
00200 template<class _E, class _Tr, class _A>
00201 inline int StrCompareIC(_IN const _E *lhs, _IN const std::basic_string<_E, _Tr, _A>& rhs)
00202 {
00203 return StrCompareIC(lhs, rhs.c_str());
00204 }
00205
00206 template<class _E, class _Tr, class _A>
00207 inline int StrCompareIC(
00208 _IN const std::basic_string<_E, _Tr, _A>& lhs,
00209 _IN const std::basic_string<_E, _Tr, _A>& rhs
00210 )
00211 {
00212 return StrCompareIC(lhs.c_str(), rhs.c_str());
00213 }
00214
00215 template<class _Ty>
00216 struct less_ic: std::less<_Ty>
00217 {
00218 bool operator() (const _Ty& lhs, const _Ty& rhs) const
00219 {
00220 return StrCompareIC(lhs, rhs) < 0;
00221 }
00222 };
00223
00224 template<class _E, class _Tr, class _A>
00225 inline std::basic_string<_E, _Tr, _A> & StrTrimLeft(_IN std::basic_string<_E, _Tr, _A> & str)
00226 {
00227 MBO_MT_LOCAL_OR_STATIC const std::basic_string<_E, _Tr, _A> strTrimChars(StrCreate<_E, _Tr, _A>(" \r\n\t"));
00228
00229 return str.erase(0, str.find_first_not_of(strTrimChars));
00230 }
00231
00232 template<class _E, class _Tr, class _A>
00233 inline std::basic_string<_E, _Tr, _A> & StrTrimRight(_IN std::basic_string<_E, _Tr, _A> & str)
00234 {
00235 MBO_MT_LOCAL_OR_STATIC const std::basic_string<_E, _Tr, _A> strTrimChars(StrCreate<_E, _Tr, _A>(" \r\n\t"));
00236
00237 std::basic_string<_E, _Tr, _A>::size_type pos = str.find_last_not_of(strTrimChars);
00238
00239 if (pos != std::basic_string<_E, _Tr, _A>::npos)
00240 {
00241 str.resize(pos + 1);
00242 return str;
00243 }
00244 else
00245 {
00246 str.resize(0);
00247 return str;
00248 }
00249 }
00250
00251 template<class _E, class _Tr, class _A>
00252 inline std::basic_string<_E, _Tr, _A> & StrTrim(_IN std::basic_string<_E, _Tr, _A> & str)
00253 {
00254 return StrTrimLeft(StrTrimRight(str));
00255 }
00256
00257 template<class _E, typename _ValType>
00258 inline std::basic_string<_E> StrFrom(_IN const _ValType & val)
00259 {
00260 std::basic_stringbuf<_E> buf;
00261 std::basic_ostream<_E> out(&buf);
00262 out << val;
00263 return buf.str();
00264 }
00265
00266 template<>
00267 inline std::basic_string<char> StrFrom(_IN const int & val)
00268 {
00269 char buf[32];
00270
00271 snprintf(buf, sizeof(buf), "%d", val);
00272 return std::basic_string<char>(buf);
00273 }
00274
00275 template<>
00276 inline std::basic_string<char> StrFrom(_IN const long & val)
00277 {
00278 char buf[32];
00279
00280 snprintf(buf, sizeof(buf), "%ld", val);
00281 return std::basic_string<char>(buf);
00282 }
00283
00284 template<>
00285 inline std::basic_string<char> StrFrom(_IN const bool & val)
00286 {
00287 return val ? std::basic_string<char>("1") : std::basic_string<char>("0");
00288 }
00289
00290 template<typename _ValType, class _E, class _Tr, class _A>
00291 inline _ValType StrTo(_IN const std::basic_string<_E, _Tr, _A> & str)
00292 {
00293 using std::basic_stringbuf;
00294 using std::basic_istream;
00295 basic_stringbuf<_E> buf(str, std::ios_base::in | std::ios_base::out);
00296 basic_istream<_E> in(&buf);
00297 _ValType val;
00298 in >> val;
00299 return val;
00300 }
00301
00302 template<class _E, class _Tr, class _A>
00303 inline int StrToInt(_IN const std::basic_string<_E, _Tr, _A> & str)
00304 {
00305 return StrTo<int, _E, _Tr, _A>(str);
00306 }
00307
00308 template<class _E, class _Tr, class _A>
00309 inline long StrToLong(_IN const std::basic_string<_E, _Tr, _A> & str)
00310 {
00311 return StrTo<long, _E, _Tr, _A>(str.c_str());
00312 }
00313
00314 template<class _E, class _Tr, class _A>
00315 inline float StrToFloat(_IN const std::basic_string<_E, _Tr, _A> & str)
00316 {
00317 return StrTo<float, _E, _Tr, _A>(str.c_str());
00318 }
00319
00320 template<>
00321 inline float StrToFloat(_IN const std::basic_string<char> & str)
00322 {
00323 float val;
00324 sscanf(str.c_str(), "%f", &val);
00325 return val;
00326 }
00327
00328 template<class _E>
00329 inline std::basic_string<_E> StrFromDouble(
00330 _IN double val,
00331 _IN int iWidth = -16,
00332 _IN int iPrecision = 10
00333 )
00334 {
00335 typedef std::basic_string<_E> string_type;
00336 typedef string_type::size_type size_type;
00337
00338 const size_type npos = string_type::npos;
00339
00340 char szTemp[128];
00341
00342 assert(abs(iWidth) < sizeof(szTemp));
00343 assert(iPrecision >= 0);
00344
00345 if (iWidth < 0)
00346 {
00347 snprintf(szTemp, sizeof(szTemp)-1, "%0g", val);
00348 std::basic_string<_E> str(szTemp);
00349 StrTrim(str);
00350 size_type pos = str.find('.');
00351 size_type nok = str.find('e') & str.find('E') & (pos>=0 ? str.find('-', pos) : -1) & str.find('+', pos) & str.find(' ', pos);
00352 if (nok == npos && iPrecision)
00353 {
00354 if (pos == npos)
00355 {
00356 pos = str.length();
00357 str += '.';
00358 }
00359 int len = static_cast<int>(str.length() - pos - 1);
00360
00361 while(len < iPrecision)
00362 {
00363 str += '0';
00364 len++;
00365 }
00366
00367 if (len > iPrecision)
00368 {
00369 str.resize(len--);
00370 }
00371
00372 len = - static_cast<int>(str.length());
00373 while(str[0] == ' ' && len < iWidth)
00374 {
00375 str.erase(0, 1);
00376 len++;
00377 }
00378 }
00379 return str;
00380 }
00381 else
00382 {
00383 snprintf(szTemp, sizeof(szTemp)-1, "%*.*g", iWidth, iPrecision, val);
00384 return std::basic_string<_E>(szTemp);
00385 }
00386 }
00387
00388 template<class _E>
00389 inline std::basic_string<_E> StrFromFloat(
00390 _IN double val,
00391 _IN int iWidth = -10,
00392 _IN int iPrecision = 6
00393 )
00394 {
00395 return StrFromDouble<_E>(static_cast<double>(val), iWidth, iPrecision);
00396 }
00397
00398 template<class _E>
00399 inline std::basic_string<_E> StrFromBool(_IN bool val)
00400 {
00401 return StrCreate<_E, std::char_traits<_E>, std::allocator<_E> >(val ? "true" : "false");
00402 }
00403
00404 template<class _E, class _Tr, class _A>
00405 inline std::basic_string<_E, _Tr, _A> StrUCFirst(_IN const std::basic_string<_E, _Tr, _A> & str)
00406 {
00407 #ifdef _STLPORT_VERSION
00408 MBO_MT_LOCAL_OR_STATIC const std::locale loc = std::locale::empty();
00409 #else
00410 MBO_MT_LOCAL_OR_STATIC const std::ctype<_E>& facet = get_facet<_E>();
00411 #endif
00412
00413 typedef std::basic_string<_E, _Tr, _A> _Str;
00414
00415 _Str res(str);
00416 int bWasAlnum = false;
00417
00418 for(_Str::iterator it = res.begin(); it != res.end(); ++it)
00419 {
00420 #ifdef _STLPORT_VERSION
00421 int bIsAlnum = std::isalnum(*it, loc);
00422 #else
00423 int bIsAlnum = facet.is(std::ctype<_E>::alnum, *it);
00424 #endif
00425
00426 if (!bWasAlnum && bIsAlnum)
00427 {
00428 #ifdef _STLPORT_VERSION
00429 *it = std::toupper(*it, loc);
00430 #else
00431 *it = facet.toupper(*it);
00432 #endif
00433 }
00434 else
00435 {
00436 #ifdef _STLPORT_VERSION
00437 int bIsUpper = std::isupper(*it, loc);;
00438 #else
00439 int bIsUpper = facet.is(std::ctype<_E>::upper, *it);
00440 #endif
00441 if (bIsUpper)
00442 {
00443 #ifdef _STLPORT_VERSION
00444 *it = std::tolower(*it, loc);
00445 #else
00446 *it = facet.tolower(*it);
00447 #endif
00448 }
00449 }
00450 bWasAlnum = bIsAlnum;
00451 }
00452 return res;
00453 }
00454
00455 template<class _E, class _Tr, class _A>
00456 inline bool StrStartsWith(
00457 _IN const std::basic_string<_E, _Tr, _A> & str,
00458 _IN const std::basic_string<_E, _Tr, _A> & strPrefix,
00459 _IN bool bCaseSensitive = true
00460 )
00461 {
00462 std::basic_string<_E, _Tr, _A>::size_type preflen = strPrefix.length();
00463
00464 if (preflen <= str.length())
00465 {
00466 if (!bCaseSensitive)
00467 {
00468 return !str.compare(0, preflen, strPrefix);
00469 }
00470 else
00471 {
00472 std::basic_string<_E, _Tr, _A> strIn(str.substr(0, preflen));
00473 std::basic_string<_E, _Tr, _A> strPr(strPrefix);
00474 return !StrLower(strIn).compare(StrLower(strPr));
00475 }
00476 }
00477 else
00478 {
00479 return !preflen;
00480 }
00481 }
00482
00483 template<class _E, class _Tr, class _A>
00484 inline bool StrEndsWith(
00485 _IN const std::basic_string<_E, _Tr, _A> & str,
00486 _IN const std::basic_string<_E, _Tr, _A> & strPostfix,
00487 _IN bool bCaseSensitive = true
00488 )
00489 {
00490 std::basic_string<_E, _Tr, _A>::size_type postlen = strPostfix.length();
00491
00492 if (postlen <= str.length())
00493 {
00494 if (!bCaseSensitive)
00495 {
00496 return !str.compare(str.length() - postlen, postlen, strPostfix);
00497 }
00498 else
00499 {
00500 std::basic_string<_E, _Tr, _A> strIn(str.substr(str.length() - postlen));
00501 std::basic_string<_E, _Tr, _A> strPr(strPostfix);
00502 return !StrLower(strIn).compare(StrLower(strPr));
00503 }
00504 }
00505 else
00506 {
00507 return !postlen;
00508 }
00509 }
00510
00511 template<class _E, class _Tr, class _A>
00512 inline std::basic_string<_E, _Tr, _A> LeftString(
00513 _IN const std::basic_string<_E, _Tr, _A> & str,
00514 _IN typename _A::size_type nLength,
00515 _IN const std::basic_string<_E, _Tr, _A> * strMore = NULL,
00516 _IN const std::basic_string<_E, _Tr, _A> * strAppend = NULL
00517 )
00518 {
00519 if (str.length() > nLength && strMore && strMore->length())
00520 {
00521 if (strMore->length() >= nLength)
00522 {
00523 return strMore->substr(0, nLength);
00524 }
00525 else
00526 {
00527 return str.substr(0, nLength - strMore->length()) + *strMore;
00528 }
00529 }
00530 else
00531 {
00532 if (strAppend && strAppend->length())
00533 {
00534
00535
00536 std::basic_string<_E, _Tr, _A> strConcat = str + *strAppend;
00537 std::basic_string<_E, _Tr, _A> strResult = strConcat.substr(0, nLength);
00538 return strResult;
00539 }
00540 else
00541 {
00542
00543
00544 std::basic_string<_E, _Tr, _A> strResult = str.substr(0, nLength);
00545 return strResult;
00546 }
00547 }
00548 }
00549
00550 template<class _E, class _Tr, class _A>
00551 inline std::basic_string<_E, _Tr, _A> LeftString(
00552 _IN const std::basic_string<_E, _Tr, _A> & str,
00553 _IN typename _A::size_type nLength,
00554 _IN const std::basic_string<_E, _Tr, _A> & strMore
00555 )
00556 {
00557 return LeftString<_E, _Tr, _A>(str, nLength, &strMore, NULL);
00558 }
00559
00560 template<class _E, class _Tr, class _A>
00561 inline std::basic_string<_E, _Tr, _A> LeftString(
00562 _IN const std::basic_string<_E, _Tr, _A> & str,
00563 _IN typename _A::size_type nLength,
00564 _IN const std::basic_string<_E, _Tr, _A> & strMore,
00565 _IN const std::basic_string<_E, _Tr, _A> & strAppend
00566 )
00567 {
00568 return LeftString<_E, _Tr, _A>(str, nLength, &strMore, &strAppend);
00569 }
00570
00571 template<class _E, class _Tr, class _A>
00572 inline bool StrSplit(
00573 _IN const std::basic_string<_E, _Tr, _A> & strValue,
00574 _IN const std::basic_string<_E, _Tr, _A> & strSplit,
00575 _OUT std::basic_string<_E, _Tr, _A> & strLeft,
00576 _OUT std::basic_string<_E, _Tr, _A> & strRight,
00577 _IN bool bTrim = false
00578 )
00579 {
00580 bool bFoundEq;
00581
00582 if (strSplit.empty())
00583 {
00584 strLeft = strValue;
00585 strRight = "";
00586 bFoundEq = false;
00587 }
00588 else
00589 {
00590 std::basic_string<_E, _Tr, _A>::size_type p = strValue.find(strSplit);
00591
00592 if (p == std::basic_string<_E, _Tr, _A>::npos)
00593 {
00594 strLeft = strValue;
00595 strRight = "";
00596 bFoundEq = false;
00597 }
00598 else if (!p)
00599 {
00600 strLeft = "";
00601 strRight = strValue.substr(strSplit.size());
00602 bFoundEq = true;
00603 }
00604 else
00605 {
00606 strRight = strValue.substr(p + strSplit.size());
00607 strLeft = strValue.substr(0, p);
00608 bFoundEq = true;
00609 }
00610 }
00611 if (bTrim)
00612 {
00613 StrTrim(strLeft);
00614 StrTrim(strRight);
00615 }
00616 return bFoundEq;
00617 }
00618
00619 template<class _E, class _Tr, class _A>
00620 inline size_t StrOccurences(
00621 _IN std::basic_string<_E, _Tr, _A> & str,
00622 _IN std::basic_string<_E, _Tr, _A> & strFind
00623 )
00624 {
00625 size_t nOccurences = 0;
00626 std::basic_string<_E, _Tr, _A>::size_type pos = 0;
00627
00628 while ((pos = str.find(strFind, pos)) != std::basic_string<_E, _Tr, _A>::npos)
00629 {
00630 nOccurences++;
00631 pos++;
00632 }
00633 return nOccurences;
00634 }
00635
00636 template<class _E, class _Tr, class _A>
00637 std::basic_string<_E, _Tr, _A> & StrReplace(
00638 _IN _OUT std::basic_string<_E, _Tr, _A> & str,
00639 _IN const std::basic_string<_E, _Tr, _A> & strOld,
00640 _IN const std::basic_string<_E, _Tr, _A> & strNew
00641 )
00642 {
00643 std::basic_string<_E, _Tr, _A>::size_type pos = 0;
00644
00645 while ((pos = str.find_first_of(strOld, pos)) != std::basic_string<_E, _Tr, _A>::npos)
00646 {
00647 str.erase(pos, strOld.length());
00648 str.insert(pos, strNew);
00649 pos += strNew.length();
00650 }
00651
00652 return str;
00653 }
00654
00655 template<class _E, class _Tr, class _A>
00656 inline std::basic_string<_E, _Tr, _A> & StrReplace(
00657 _IN _OUT std::basic_string<_E, _Tr, _A> & str,
00658 _IN const _E * strOld,
00659 _IN const _E * strNew
00660 )
00661 {
00662 return StrReplace(str, std::basic_string<_E, _Tr, _A>(strOld), std::basic_string<_E, _Tr, _A>(strNew));
00663 }
00664
00665 template<class _E, class _Tr, class _A>
00666 std::basic_string<_E, _Tr, _A> StrEncodeXML(
00667 _IN const std::basic_string<_E, _Tr, _A> & _str
00668 )
00669 {
00670 std::basic_string<_E, _Tr, _A> str(_str);
00671 mbo::StrReplace(str, "&", "&");
00672 mbo::StrReplace(str, "<", "<");
00673 mbo::StrReplace(str, ">", ">");
00674 mbo::StrReplace(str, "'", "'");
00675 mbo::StrReplace(str, "\"", """);
00676 return str;
00677 }
00678
00679 inline std::string & StrParseEnvVars(
00680 _IN std::string & str,
00681 _IN char cOpen,
00682 _IN char cClose
00683 )
00684 {
00685 for(;;)
00686 {
00687 std::string::size_type n1 = str.find(cOpen);
00688 std::string::size_type n2 = (n1 != std::string::npos) ? str.find(cClose, n1) : std::string::npos;
00689
00690 if (n2 != std::string::npos)
00691 {
00692 std::string env(str.substr(n1 + 1, n2 - n1 - 1));
00693 return str.replace(n1, n2 - n1 + 1, getenv(env.c_str()));
00694 }
00695 else
00696 {
00697 return str;
00698 }
00699 }
00700 }
00701
00702 };
00703
00704 #if defined(_MSC_VER)
00705 # pragma warning(pop)
00706 #endif
00707
00708 #endif //_MBOSTRHELPER_H_