00001 #pragma ident "$Id: String.hpp 2972 2011-11-10 12:10:39Z yanweignss $"
00002
00008 #ifndef GPSTK_STRING_HPP
00009 #define GPSTK_STRING_HPP
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include <stdio.h>
00034 #include <string>
00035 #include <cstring>
00036 #include "Ascii.hpp"
00037 #include "StringUtils.hpp"
00038
00039 namespace gpstk
00040 {
00042 template <class S>
00043 S trimLeft(const S& str)
00044 {
00045 typename S::const_iterator it = str.begin();
00046 typename S::const_iterator end = str.end();
00047
00048 while (it != end && Ascii::isSpace(*it)) ++it;
00049 return S(it, end);
00050 }
00051
00053 template <class S>
00054 S& trimLeftInPlace(S& str)
00055 {
00056 typename S::iterator it = str.begin();
00057 typename S::iterator end = str.end();
00058
00059 while (it != end && Ascii::isSpace(*it)) ++it;
00060 str.erase(str.begin(), it);
00061 return str;
00062 }
00063
00065 template <class S>
00066 S trimRight(const S& str)
00067 {
00068 int pos = int(str.size()) - 1;
00069
00070 while (pos >= 0 && Ascii::isSpace(str[pos])) --pos;
00071 return S(str, 0, pos + 1);
00072 }
00073
00075 template <class S>
00076 S& trimRightInPlace(S& str)
00077 {
00078 int pos = int(str.size()) - 1;
00079
00080 while (pos >= 0 && Ascii::isSpace(str[pos])) --pos;
00081 str.resize(pos + 1);
00082
00083 return str;
00084 }
00085
00087 template <class S>
00088 S trim(const S& str)
00089 {
00090 int first = 0;
00091 int last = int(str.size()) - 1;
00092
00093 while (first <= last && Ascii::isSpace(str[first])) ++first;
00094 while (last >= first && Ascii::isSpace(str[last])) --last;
00095
00096 return S(str, first, last - first + 1);
00097 }
00098
00100 template <class S>
00101 S& trimInPlace(S& str)
00102 {
00103 int first = 0;
00104 int last = int(str.size()) - 1;
00105
00106 while (first <= last && Ascii::isSpace(str[first])) ++first;
00107 while (last >= first && Ascii::isSpace(str[last])) --last;
00108
00109 str.resize(last + 1);
00110 str.erase(0, first);
00111
00112 return str;
00113 }
00114
00116 template <class S>
00117 S toUpper(const S& str)
00118 {
00119 typename S::const_iterator it = str.begin();
00120 typename S::const_iterator end = str.end();
00121
00122 S result;
00123 result.reserve(str.size());
00124 while (it != end) result += Ascii::toUpper(*it++);
00125 return result;
00126 }
00127
00129 template <class S>
00130 S& toUpperInPlace(S& str)
00131 {
00132 typename S::iterator it = str.begin();
00133 typename S::iterator end = str.end();
00134
00135 while (it != end) { *it = Ascii::toUpper(*it); ++it; }
00136 return str;
00137 }
00138
00140 template <class S>
00141 S toLower(const S& str)
00142 {
00143 typename S::const_iterator it = str.begin();
00144 typename S::const_iterator end = str.end();
00145
00146 S result;
00147 result.reserve(str.size());
00148 while (it != end) result += Ascii::toLower(*it++);
00149 return result;
00150 }
00151
00153 template <class S>
00154 S& toLowerInPlace(S& str)
00155 {
00156 typename S::iterator it = str.begin();
00157 typename S::iterator end = str.end();
00158
00159 while (it != end) { *it = Ascii::toLower(*it); ++it; }
00160 return str;
00161 }
00162
00168 template <class S>
00169 S translate(const S& str, const S& from, const S& to)
00170 {
00171 S result;
00172 result.reserve(str.size());
00173 typename S::const_iterator it = str.begin();
00174 typename S::const_iterator end = str.end();
00175 typename S::size_type toSize = to.size();
00176 while (it != end)
00177 {
00178 typename S::size_type pos = from.find(*it);
00179 if (pos == S::npos)
00180 {
00181 result += *it;
00182 }
00183 else
00184 {
00185 if (pos < toSize) result += to[pos];
00186 }
00187 ++it;
00188 }
00189 return result;
00190 }
00191
00192
00193 template <class S>
00194 S translate(const S& str, const typename S::value_type* from, const typename S::value_type* to)
00195 {
00196 GPSTK_CHECK_PTR (from);
00197 GPSTK_CHECK_PTR (to);
00198 return translate(str, S(from), S(to));
00199 }
00200
00205 template <class S>
00206 S& translateInPlace(S& str, const S& from, const S& to)
00207 {
00208 str = translate(str, from, to);
00209 return str;
00210 }
00211
00212
00213 template <class S>
00214 S translateInPlace(S& str, const typename S::value_type* from, const typename S::value_type* to)
00215 {
00216 GPSTK_CHECK_PTR (from);
00217 GPSTK_CHECK_PTR (to);
00218 str = translate(str, S(from), S(to));
00219 return str;
00220 }
00221
00222 template <class S>
00223 S& replaceInPlace(S& str, const S& from, const S& to, typename S::size_type start = 0)
00224 {
00225 poco_assert (from.size() > 0);
00226
00227 S result;
00228 typename S::size_type pos = 0;
00229 result.append(str, 0, start);
00230 do
00231 {
00232 pos = str.find(from, start);
00233 if (pos != S::npos)
00234 {
00235 result.append(str, start, pos - start);
00236 result.append(to);
00237 start = pos + from.length();
00238 }
00239 else result.append(str, start, str.size() - start);
00240 }
00241 while (pos != S::npos);
00242 str.swap(result);
00243 return str;
00244 }
00245
00246
00247 template <class S>
00248 S& replaceInPlace(S& str, const typename S::value_type* from, const typename S::value_type* to, typename S::size_type start = 0)
00249 {
00250 poco_assert (*from);
00251
00252 S result;
00253 typename S::size_type pos = 0;
00254 typename S::size_type fromLen = std::strlen(from);
00255 result.append(str, 0, start);
00256 do
00257 {
00258 pos = str.find(from, start);
00259 if (pos != S::npos)
00260 {
00261 result.append(str, start, pos - start);
00262 result.append(to);
00263 start = pos + fromLen;
00264 }
00265 else result.append(str, start, str.size() - start);
00266 }
00267 while (pos != S::npos);
00268 str.swap(result);
00269 return str;
00270 }
00271
00272
00273 template <class S>
00274 S replace(const S& str, const S& from, const S& to, typename S::size_type start = 0)
00277 {
00278 S result(str);
00279 replaceInPlace(result, from, to, start);
00280 return result;
00281 }
00282
00283
00284 template <class S>
00285 S replace(const S& str, const typename S::value_type* from, const typename S::value_type* to, typename S::size_type start = 0)
00286 {
00287 S result(str);
00288 replaceInPlace(result, from, to, start);
00289 return result;
00290 }
00291
00292
00293 template <class S>
00294 S cat(const S& s1, const S& s2)
00295 {
00296 S result = s1;
00297 result.reserve(s1.size() + s2.size());
00298 result.append(s2);
00299 return result;
00300 }
00301
00302
00303 template <class S>
00304 S cat(const S& s1, const S& s2, const S& s3)
00305 {
00306 S result = s1;
00307 result.reserve(s1.size() + s2.size() + s3.size());
00308 result.append(s2);
00309 result.append(s3);
00310 return result;
00311 }
00312
00313
00314 template <class S>
00315 S cat(const S& s1, const S& s2, const S& s3, const S& s4)
00316 {
00317 S result = s1;
00318 result.reserve(s1.size() + s2.size() + s3.size() + s4.size());
00319 result.append(s2);
00320 result.append(s3);
00321 result.append(s4);
00322 return result;
00323 }
00324
00325
00326 template <class S>
00327 S cat(const S& s1, const S& s2, const S& s3, const S& s4, const S& s5)
00328 {
00329 S result = s1;
00330 result.reserve(s1.size() + s2.size() + s3.size() + s4.size() + s5.size());
00331 result.append(s2);
00332 result.append(s3);
00333 result.append(s4);
00334 result.append(s5);
00335 return result;
00336 }
00337
00338
00339 template <class S>
00340 S cat(const S& s1, const S& s2, const S& s3, const S& s4, const S& s5, const S& s6)
00341 {
00342 S result = s1;
00343 result.reserve(s1.size() + s2.size() + s3.size() + s4.size() + s5.size() + s6.size());
00344 result.append(s2);
00345 result.append(s3);
00346 result.append(s4);
00347 result.append(s5);
00348 result.append(s6);
00349 return result;
00350 }
00351
00352
00353 template <class S, class It>
00354 S cat(const S& delim, const It& begin, const It& end)
00355 {
00356 S result;
00357 for (It it = begin; it != end; ++it)
00358 {
00359 if (!result.empty()) result.append(delim);
00360 result += *it;
00361 }
00362 return result;
00363 }
00364
00365
00372 inline std::vector<std::string> split(const std::string& aStr,
00373 const std::string& theDelimiters=" ",
00374 bool trimWhitespace = false,
00375 bool ignoreEmpty = true)
00376 {
00377 std::vector<std::string> toReturn;
00378
00379 std::string::size_type lastPos = aStr.find_first_not_of(theDelimiters, 0);
00380 std::string::size_type pos = aStr.find_first_of(theDelimiters, lastPos);
00381
00382 while (std::string::npos != pos || std::string::npos != lastPos)
00383 {
00384 std::string token = aStr.substr(lastPos, pos - lastPos);
00385
00386 if(trimWhitespace) token = trim(token);
00387
00388 if(!token.empty() || !ignoreEmpty) toReturn.push_back(token);
00389
00390 lastPos = aStr.find_first_not_of(theDelimiters, pos);
00391 pos = aStr.find_first_of(theDelimiters, lastPos);
00392 }
00393
00394 return toReturn;
00395 }
00396
00397 template <class S, class It>
00398 int icompare(
00399 const S& str,
00400 typename S::size_type pos,
00401 typename S::size_type n,
00402 It it2,
00403 It end2)
00405 {
00406 typename S::size_type sz = str.size();
00407 if (pos > sz) pos = sz;
00408 if (pos + n > sz) n = sz - pos;
00409 It it1 = str.begin() + pos;
00410 It end1 = str.begin() + pos + n;
00411 while (it1 != end1 && it2 != end2)
00412 {
00413 typename S::value_type c1(Ascii::toLower(*it1));
00414 typename S::value_type c2(Ascii::toLower(*it2));
00415 if (c1 < c2)
00416 return -1;
00417 else if (c1 > c2)
00418 return 1;
00419 ++it1; ++it2;
00420 }
00421
00422 if (it1 == end1)
00423 return it2 == end2 ? 0 : -1;
00424 else
00425 return 1;
00426 }
00427
00428
00429 template <class S>
00430 int icompare(const S& str1, const S& str2)
00431
00432 {
00433 typename S::const_iterator it1(str1.begin());
00434 typename S::const_iterator end1(str1.end());
00435 typename S::const_iterator it2(str2.begin());
00436 typename S::const_iterator end2(str2.end());
00437 while (it1 != end1 && it2 != end2)
00438 {
00439 typename S::value_type c1(Ascii::toLower(*it1));
00440 typename S::value_type c2(Ascii::toLower(*it2));
00441 if (c1 < c2)
00442 return -1;
00443 else if (c1 > c2)
00444 return 1;
00445 ++it1; ++it2;
00446 }
00447
00448 if (it1 == end1)
00449 return it2 == end2 ? 0 : -1;
00450 else
00451 return 1;
00452 }
00453
00454
00455 template <class S>
00456 int icompare(const S& str1, typename S::size_type n1, const S& str2, typename S::size_type n2)
00457 {
00458 if (n2 > str2.size()) n2 = str2.size();
00459 return icompare(str1, 0, n1, str2.begin(), str2.begin() + n2);
00460 }
00461
00462
00463 template <class S>
00464 int icompare(const S& str1, typename S::size_type n, const S& str2)
00465 {
00466 if (n > str2.size()) n = str2.size();
00467 return icompare(str1, 0, n, str2.begin(), str2.begin() + n);
00468 }
00469
00470
00471 template <class S>
00472 int icompare(const S& str1, typename S::size_type pos, typename S::size_type n, const S& str2)
00473 {
00474 return icompare(str1, pos, n, str2.begin(), str2.end());
00475 }
00476
00477
00478 template <class S>
00479 int icompare(
00480 const S& str1,
00481 typename S::size_type pos1,
00482 typename S::size_type n1,
00483 const S& str2,
00484 typename S::size_type pos2,
00485 typename S::size_type n2)
00486 {
00487 typename S::size_type sz2 = str2.size();
00488 if (pos2 > sz2) pos2 = sz2;
00489 if (pos2 + n2 > sz2) n2 = sz2 - pos2;
00490 return icompare(str1, pos1, n1, str2.begin() + pos2, str2.begin() + pos2 + n2);
00491 }
00492
00493
00494 template <class S>
00495 int icompare(
00496 const S& str1,
00497 typename S::size_type pos1,
00498 typename S::size_type n,
00499 const S& str2,
00500 typename S::size_type pos2)
00501 {
00502 typename S::size_type sz2 = str2.size();
00503 if (pos2 > sz2) pos2 = sz2;
00504 if (pos2 + n > sz2) n = sz2 - pos2;
00505 return icompare(str1, pos1, n, str2.begin() + pos2, str2.begin() + pos2 + n);
00506 }
00507
00508
00509 template <class S>
00510 int icompare(
00511 const S& str,
00512 typename S::size_type pos,
00513 typename S::size_type n,
00514 const typename S::value_type* ptr)
00515 {
00516 GPSTK_CHECK_PTR (ptr);
00517 typename S::size_type sz = str.size();
00518 if (pos > sz) pos = sz;
00519 if (pos + n > sz) n = sz - pos;
00520 typename S::const_iterator it = str.begin() + pos;
00521 typename S::const_iterator end = str.begin() + pos + n;
00522 while (it != end && *ptr)
00523 {
00524 typename S::value_type c1(Ascii::toLower(*it));
00525 typename S::value_type c2(Ascii::toLower(*ptr));
00526 if (c1 < c2)
00527 return -1;
00528 else if (c1 > c2)
00529 return 1;
00530 ++it; ++ptr;
00531 }
00532
00533 if (it == end)
00534 return *ptr == 0 ? 0 : -1;
00535 else
00536 return 1;
00537 }
00538
00539
00540 template <class S>
00541 int icompare(
00542 const S& str,
00543 typename S::size_type pos,
00544 const typename S::value_type* ptr)
00545 {
00546 return icompare(str, pos, str.size() - pos, ptr);
00547 }
00548
00549
00550 template <class S>
00551 int icompare(
00552 const S& str,
00553 const typename S::value_type* ptr)
00554 {
00555 return icompare(str, 0, str.size(), ptr);
00556 }
00557
00558
00559 }
00560
00561
00562 #endif //GPSTK_STRING_HPP
00563