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
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #ifndef Foundation_String_INCLUDED
00040 #define Foundation_String_INCLUDED
00041
00042
00043 #include "Poco/Foundation.h"
00044 #include <cstring>
00045 #include <cctype>
00046
00047
00048 namespace Poco {
00049
00050
00051 template <class S>
00052 S trimLeft(const S& str)
00055 {
00056 typename S::const_iterator it = str.begin();
00057 typename S::const_iterator end = str.end();
00058
00059 while (it != end && std::isspace(*it)) ++it;
00060 return S(it, end);
00061 }
00062
00063
00064 template <class S>
00065 S& trimLeftInPlace(S& str)
00067 {
00068 typename S::iterator it = str.begin();
00069 typename S::iterator end = str.end();
00070
00071 while (it != end && std::isspace(*it)) ++it;
00072 str.erase(str.begin(), it);
00073 return str;
00074 }
00075
00076
00077 template <class S>
00078 S trimRight(const S& str)
00081 {
00082 int pos = int(str.size()) - 1;
00083
00084 while (pos >= 0 && std::isspace(str[pos])) --pos;
00085 return S(str, 0, pos + 1);
00086 }
00087
00088
00089 template <class S>
00090 S& trimRightInPlace(S& str)
00092 {
00093 int pos = int(str.size()) - 1;
00094
00095 while (pos >= 0 && std::isspace(str[pos])) --pos;
00096 str.resize(pos + 1);
00097
00098 return str;
00099 }
00100
00101
00102 template <class S>
00103 S trim(const S& str)
00106 {
00107 int first = 0;
00108 int last = int(str.size()) - 1;
00109
00110 while (first <= last && std::isspace(str[first])) ++first;
00111 while (last >= first && std::isspace(str[last])) --last;
00112
00113 return S(str, first, last - first + 1);
00114 }
00115
00116
00117 template <class S>
00118 S& trimInPlace(S& str)
00120 {
00121 int first = 0;
00122 int last = int(str.size()) - 1;
00123
00124 while (first <= last && std::isspace(str[first])) ++first;
00125 while (last >= first && std::isspace(str[last])) --last;
00126
00127 str.resize(last + 1);
00128 str.erase(0, first);
00129
00130 return str;
00131 }
00132
00133
00134 template <class S>
00135 S toUpper(const S& str)
00137 {
00138 typename S::const_iterator it = str.begin();
00139 typename S::const_iterator end = str.end();
00140
00141 S result;
00142 result.reserve(str.size());
00143 while (it != end) result += std::toupper(*it++);
00144 return result;
00145 }
00146
00147
00148 template <class S>
00149 S& toUpperInPlace(S& str)
00151 {
00152 typename S::iterator it = str.begin();
00153 typename S::iterator end = str.end();
00154
00155 while (it != end) { *it = std::toupper(*it); ++it; }
00156 return str;
00157 }
00158
00159
00160 template <class S>
00161 S toLower(const S& str)
00163 {
00164 typename S::const_iterator it = str.begin();
00165 typename S::const_iterator end = str.end();
00166
00167 S result;
00168 result.reserve(str.size());
00169 while (it != end) result += std::tolower(*it++);
00170 return result;
00171 }
00172
00173
00174 template <class S>
00175 S& toLowerInPlace(S& str)
00177 {
00178 typename S::iterator it = str.begin();
00179 typename S::iterator end = str.end();
00180
00181 while (it != end) { *it = std::tolower(*it); ++it; }
00182 return str;
00183 }
00184
00185
00186 #if !defined(POCO_NO_TEMPLATE_ICOMPARE)
00187
00188
00189 template <class S, class It>
00190 int icompare(
00191 const S& str,
00192 typename S::size_type pos,
00193 typename S::size_type n,
00194 It it2,
00195 It end2)
00197 {
00198 typename S::size_type sz = str.size();
00199 if (pos > sz) pos = sz;
00200 if (pos + n > sz) n = sz - pos;
00201 It it1 = str.begin() + pos;
00202 It end1 = str.begin() + pos + n;
00203 while (it1 != end1 && it2 != end2)
00204 {
00205 typename S::value_type c1(std::tolower(*it1));
00206 typename S::value_type c2(std::tolower(*it2));
00207 if (c1 < c2)
00208 return -1;
00209 else if (c1 > c2)
00210 return 1;
00211 ++it1; ++it2;
00212 }
00213
00214 if (it1 == end1)
00215 return it2 == end2 ? 0 : -1;
00216 else
00217 return 1;
00218 }
00219
00220
00221 template <class S>
00222 int icompare(const S& str1, const S& str2)
00223
00224 {
00225 typename S::const_iterator it1(str1.begin());
00226 typename S::const_iterator end1(str1.end());
00227 typename S::const_iterator it2(str2.begin());
00228 typename S::const_iterator end2(str2.end());
00229 while (it1 != end1 && it2 != end2)
00230 {
00231 typename S::value_type c1(std::tolower(*it1));
00232 typename S::value_type c2(std::tolower(*it2));
00233 if (c1 < c2)
00234 return -1;
00235 else if (c1 > c2)
00236 return 1;
00237 ++it1; ++it2;
00238 }
00239
00240 if (it1 == end1)
00241 return it2 == end2 ? 0 : -1;
00242 else
00243 return 1;
00244 }
00245
00246
00247 template <class S>
00248 int icompare(const S& str1, typename S::size_type n1, const S& str2, typename S::size_type n2)
00249 {
00250 if (n2 > str2.size()) n2 = str2.size();
00251 return icompare(str1, 0, n1, str2.begin(), str2.begin() + n2);
00252 }
00253
00254
00255 template <class S>
00256 int icompare(const S& str1, typename S::size_type n, const S& str2)
00257 {
00258 if (n > str2.size()) n = str2.size();
00259 return icompare(str1, 0, n, str2.begin(), str2.begin() + n);
00260 }
00261
00262
00263 template <class S>
00264 int icompare(const S& str1, typename S::size_type pos, typename S::size_type n, const S& str2)
00265 {
00266 return icompare(str1, pos, n, str2.begin(), str2.end());
00267 }
00268
00269
00270 template <class S>
00271 int icompare(
00272 const S& str1,
00273 typename S::size_type pos1,
00274 typename S::size_type n1,
00275 const S& str2,
00276 typename S::size_type pos2,
00277 typename S::size_type n2)
00278 {
00279 typename S::size_type sz2 = str2.size();
00280 if (pos2 > sz2) pos2 = sz2;
00281 if (pos2 + n2 > sz2) n2 = sz2 - pos2;
00282 return icompare(str1, pos1, n1, str2.begin() + pos2, str2.begin() + pos2 + n2);
00283 }
00284
00285
00286 template <class S>
00287 int icompare(
00288 const S& str1,
00289 typename S::size_type pos1,
00290 typename S::size_type n,
00291 const S& str2,
00292 typename S::size_type pos2)
00293 {
00294 typename S::size_type sz2 = str2.size();
00295 if (pos2 > sz2) pos2 = sz2;
00296 if (pos2 + n > sz2) n = sz2 - pos2;
00297 return icompare(str1, pos1, n, str2.begin() + pos2, str2.begin() + pos2 + n);
00298 }
00299
00300
00301 template <class S>
00302 int icompare(
00303 const S& str,
00304 typename S::size_type pos,
00305 typename S::size_type n,
00306 const typename S::value_type* ptr)
00307 {
00308 poco_check_ptr (ptr);
00309 typename S::size_type sz = str.size();
00310 if (pos > sz) pos = sz;
00311 if (pos + n > sz) n = sz - pos;
00312 typename S::const_iterator it = str.begin() + pos;
00313 typename S::const_iterator end = str.begin() + pos + n;
00314 while (it != end && *ptr)
00315 {
00316 typename S::value_type c1(std::tolower(*it));
00317 typename S::value_type c2(std::tolower(*ptr));
00318 if (c1 < c2)
00319 return -1;
00320 else if (c1 > c2)
00321 return 1;
00322 ++it; ++ptr;
00323 }
00324
00325 if (it == end)
00326 return *ptr == 0 ? 0 : -1;
00327 else
00328 return 1;
00329 }
00330
00331
00332 template <class S>
00333 int icompare(
00334 const S& str,
00335 typename S::size_type pos,
00336 const typename S::value_type* ptr)
00337 {
00338 return icompare(str, pos, str.size() - pos, ptr);
00339 }
00340
00341
00342 template <class S>
00343 int icompare(
00344 const S& str,
00345 const typename S::value_type* ptr)
00346 {
00347 return icompare(str, 0, str.size(), ptr);
00348 }
00349
00350
00351 #else
00352
00353
00354 int Foundation_API icompare(const std::string& str, std::string::size_type pos, std::string::size_type n, std::string::const_iterator it2, std::string::const_iterator end2);
00355 int Foundation_API icompare(const std::string& str1, const std::string& str2);
00356 int Foundation_API icompare(const std::string& str1, std::string::size_type n1, const std::string& str2, std::string::size_type n2);
00357 int Foundation_API icompare(const std::string& str1, std::string::size_type n, const std::string& str2);
00358 int Foundation_API icompare(const std::string& str1, std::string::size_type pos, std::string::size_type n, const std::string& str2);
00359 int Foundation_API icompare(const std::string& str1, std::string::size_type pos1, std::string::size_type n1, const std::string& str2, std::string::size_type pos2, std::string::size_type n2);
00360 int Foundation_API icompare(const std::string& str1, std::string::size_type pos1, std::string::size_type n, const std::string& str2, std::string::size_type pos2);
00361 int Foundation_API icompare(const std::string& str, std::string::size_type pos, std::string::size_type n, const std::string::value_type* ptr);
00362 int Foundation_API icompare(const std::string& str, std::string::size_type pos, const std::string::value_type* ptr);
00363 int Foundation_API icompare(const std::string& str, const std::string::value_type* ptr);
00364
00365
00366 #endif
00367
00368
00369 template <class S>
00370 S translate(const S& str, const S& from, const S& to)
00376 {
00377 S result;
00378 result.reserve(str.size());
00379 typename S::const_iterator it = str.begin();
00380 typename S::const_iterator end = str.end();
00381 typename S::size_type toSize = to.size();
00382 while (it != end)
00383 {
00384 typename S::size_type pos = from.find(*it);
00385 if (pos == S::npos)
00386 {
00387 result += *it;
00388 }
00389 else
00390 {
00391 if (pos < toSize) result += to[pos];
00392 }
00393 ++it;
00394 }
00395 return result;
00396 }
00397
00398
00399 template <class S>
00400 S translate(const S& str, const typename S::value_type* from, const typename S::value_type* to)
00401 {
00402 poco_check_ptr (from);
00403 poco_check_ptr (to);
00404 return translate(str, S(from), S(to));
00405 }
00406
00407
00408 template <class S>
00409 S& translateInPlace(S& str, const S& from, const S& to)
00414 {
00415 str = translate(str, from, to);
00416 return str;
00417 }
00418
00419
00420 template <class S>
00421 S translateInPlace(S& str, const typename S::value_type* from, const typename S::value_type* to)
00422 {
00423 poco_check_ptr (from);
00424 poco_check_ptr (to);
00425 str = translate(str, S(from), S(to));
00426 return str;
00427 }
00428
00429
00430 #if !defined(POCO_NO_TEMPLATE_ICOMPARE)
00431
00432
00433 template <class S>
00434 S replace(const S& str, const S& from, const S& to, typename S::size_type start = 0)
00437 {
00438 S result(str);
00439 replaceInPlace(result, from, to, start);
00440 return result;
00441 }
00442
00443
00444 template <class S>
00445 S replace(const S& str, const typename S::value_type* from, const typename S::value_type* to, typename S::size_type start = 0)
00446 {
00447 S result(str);
00448 replaceInPlace(result, from, to, start);
00449 return result;
00450 }
00451
00452
00453 template <class S>
00454 S& replaceInPlace(S& str, const S& from, const S& to, typename S::size_type start = 0)
00455 {
00456 poco_assert (from.size() > 0);
00457
00458 S result;
00459 typename S::size_type pos = 0;
00460 result.append(str, 0, start);
00461 do
00462 {
00463 pos = str.find(from, start);
00464 if (pos != S::npos)
00465 {
00466 result.append(str, start, pos - start);
00467 result.append(to);
00468 start = pos + from.length();
00469 }
00470 else result.append(str, start, str.size() - start);
00471 }
00472 while (pos != S::npos);
00473 str.swap(result);
00474 return str;
00475 }
00476
00477
00478 template <class S>
00479 S& replaceInPlace(S& str, const typename S::value_type* from, const typename S::value_type* to, typename S::size_type start = 0)
00480 {
00481 poco_assert (*from);
00482
00483 S result;
00484 typename S::size_type pos = 0;
00485 typename S::size_type fromLen = std::strlen(from);
00486 result.append(str, 0, start);
00487 do
00488 {
00489 pos = str.find(from, start);
00490 if (pos != S::npos)
00491 {
00492 result.append(str, start, pos - start);
00493 result.append(to);
00494 start = pos + fromLen;
00495 }
00496 else result.append(str, start, str.size() - start);
00497 }
00498 while (pos != S::npos);
00499 str.swap(result);
00500 return str;
00501 }
00502
00503
00504 #else
00505
00506
00507 std::string Foundation_API replace(const std::string& str, const std::string& from, const std::string& to, std::string::size_type start = 0);
00508 std::string Foundation_API replace(const std::string& str, const std::string::value_type* from, const std::string::value_type* to, std::string::size_type start = 0);
00509 std::string& Foundation_API replaceInPlace(std::string& str, const std::string& from, const std::string& to, std::string::size_type start = 0);
00510 std::string& Foundation_API replaceInPlace(std::string& str, const std::string::value_type* from, const std::string::value_type* to, std::string::size_type start = 0);
00511
00512
00513 #endif
00514
00515
00516 template <class S>
00517 S cat(const S& s1, const S& s2)
00519 {
00520 S result = s1;
00521 result.reserve(s1.size() + s2.size());
00522 result.append(s2);
00523 return result;
00524 }
00525
00526
00527 template <class S>
00528 S cat(const S& s1, const S& s2, const S& s3)
00530 {
00531 S result = s1;
00532 result.reserve(s1.size() + s2.size() + s3.size());
00533 result.append(s2);
00534 result.append(s3);
00535 return result;
00536 }
00537
00538
00539 template <class S>
00540 S cat(const S& s1, const S& s2, const S& s3, const S& s4)
00542 {
00543 S result = s1;
00544 result.reserve(s1.size() + s2.size() + s3.size() + s4.size());
00545 result.append(s2);
00546 result.append(s3);
00547 result.append(s4);
00548 return result;
00549 }
00550
00551
00552 template <class S>
00553 S cat(const S& s1, const S& s2, const S& s3, const S& s4, const S& s5)
00555 {
00556 S result = s1;
00557 result.reserve(s1.size() + s2.size() + s3.size() + s4.size() + s5.size());
00558 result.append(s2);
00559 result.append(s3);
00560 result.append(s4);
00561 result.append(s5);
00562 return result;
00563 }
00564
00565
00566 template <class S>
00567 S cat(const S& s1, const S& s2, const S& s3, const S& s4, const S& s5, const S& s6)
00569 {
00570 S result = s1;
00571 result.reserve(s1.size() + s2.size() + s3.size() + s4.size() + s5.size() + s6.size());
00572 result.append(s2);
00573 result.append(s3);
00574 result.append(s4);
00575 result.append(s5);
00576 result.append(s6);
00577 return result;
00578 }
00579
00580
00581 template <class S, class It>
00582 S cat(const S& delim, const It& begin, const It& end)
00585 {
00586 S result;
00587 for (It it = begin; it != end; ++it)
00588 {
00589 if (!result.empty()) result.append(delim);
00590 result += *it;
00591 }
00592 return result;
00593 }
00594
00595
00596 }
00597
00598
00599 #endif // Foundation_String_INCLUDED