String.hpp

Go to the documentation of this file.
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 //  This file is part of GPSTk, the GPS Toolkit.
00014 //
00015 //  The GPSTk is free software; you can redistribute it and/or modify
00016 //  it under the terms of the GNU Lesser General Public License as published
00017 //  by the Free Software Foundation; either version 2.1 of the License, or
00018 //  any later version.
00019 //
00020 //  The GPSTk is distributed in the hope that it will be useful,
00021 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00022 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023 //  GNU Lesser General Public License for more details.
00024 //
00025 //  You should have received a copy of the GNU Lesser General Public
00026 //  License along with GPSTk; if not, write to the Free Software Foundation,
00027 //  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00028 //
00029 //  Wei Yan - Chinese Academy of Sciences . 2011
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       // A special optimization for an often used case.
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 }   // End of namespace gpstk
00560 
00561 
00562 #endif  //GPSTK_STRING_HPP
00563 

Generated on Tue May 22 03:31:02 2012 for GPS ToolKit Software Library by  doxygen 1.3.9.1