Claw
1.7.3
|
00001 /* 00002 CLAW - a C++ Library Absolutely Wonderful 00003 00004 CLAW is a free library without any particular aim but being useful to 00005 anyone. 00006 00007 Copyright (C) 2005-2011 Julien Jorge 00008 00009 This library is free software; you can redistribute it and/or 00010 modify it under the terms of the GNU Lesser General Public 00011 License as published by the Free Software Foundation; either 00012 version 2.1 of the License, or (at your option) any later version. 00013 00014 This library is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 Lesser General Public License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public 00020 License along with this library; if not, write to the Free Software 00021 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00022 00023 contact: julien.jorge@gamned.org 00024 */ 00031 #include <claw/algorithm.hpp> 00032 #include <claw/glob.hpp> 00033 00034 #include <sstream> 00035 #include <string> 00036 #include <iterator> 00037 00038 /*----------------------------------------------------------------------------*/ 00045 template<typename StreamType, typename StringType> 00046 StreamType& claw::text::getline( StreamType& is, StringType& str ) 00047 { 00048 std::getline( is, str ); 00049 00050 if ( !str.empty() ) 00051 if ( str[ str.size() - 1 ] == typename StringType::value_type('\r') ) 00052 str.erase( str.size() - 1 ); 00053 00054 return is; 00055 } // getline() 00056 00057 /*----------------------------------------------------------------------------*/ 00063 template<typename StringType> 00064 void claw::text::trim_left( StringType& str, 00065 const typename StringType::value_type* const s ) 00066 { 00067 typename StringType::size_type p = str.find_first_not_of(s); 00068 00069 if (p != StringType::npos) 00070 str = str.substr(p); 00071 } // trim_left() 00072 00073 /*----------------------------------------------------------------------------*/ 00079 template<typename StringType> 00080 void claw::text::trim_right( StringType& str, 00081 const typename StringType::value_type* const s ) 00082 { 00083 typename StringType::size_type p = str.find_last_not_of(s); 00084 00085 if (p != StringType::npos) 00086 str = str.substr( 0, p+1 ); 00087 } // trim_right() 00088 00089 /*----------------------------------------------------------------------------*/ 00095 template<typename StringType> 00096 void claw::text::trim( StringType& str, 00097 const typename StringType::value_type* const s ) 00098 { 00099 typename StringType::size_type first = str.find_first_not_of(s); 00100 typename StringType::size_type last = str.find_last_not_of(s); 00101 00102 if (first != StringType::npos) 00103 str = str.substr( first, last - first + 1 ); 00104 } // trim() 00105 00106 /*----------------------------------------------------------------------------*/ 00119 template<typename StringType> 00120 void claw::text::squeeze( StringType& str, 00121 const typename StringType::value_type* const s ) 00122 { 00123 typedef typename StringType::size_type size_type; 00124 00125 size_type first(0); 00126 00127 do 00128 { 00129 first = str.find_first_of(s, first); 00130 00131 if ( first != StringType::npos ) 00132 { 00133 size_type last = str.find_first_not_of(str[first], first+1); 00134 00135 if ( last == StringType::npos ) 00136 str = str.substr(0, first+1); 00137 else if ( last - first > 1 ) 00138 str = str.substr(0, first+1) + str.substr(last); 00139 00140 ++first; 00141 } 00142 } 00143 while ( (first != StringType::npos) && (first != str.length()) ); 00144 } // squeeze() 00145 00146 /*----------------------------------------------------------------------------*/ 00165 template<typename StringType> 00166 std::size_t claw::text::replace 00167 ( StringType& str, const StringType& e1, const StringType& e2 ) 00168 { 00169 return 00170 claw::replace 00171 ( str.begin(), str.end(), e1.begin(), e1.end(), e2.begin(), e2.end() ); 00172 } // replace() 00173 00174 /*----------------------------------------------------------------------------*/ 00179 template<typename T, typename StringType> 00180 bool claw::text::is_of_type( const StringType& str ) 00181 { 00182 std::basic_istringstream< typename StringType::value_type, 00183 typename StringType::traits_type, 00184 typename StringType::allocator_type > iss(str); 00185 00186 T val; 00187 bool result = false; 00188 00189 if ( iss >> val ) 00190 result = iss.eof(); 00191 00192 return result; 00193 } // is_of_type() 00194 00195 /*----------------------------------------------------------------------------*/ 00203 template<typename Sequence> 00204 void claw::text::split 00205 ( Sequence& sequence, const typename Sequence::value_type& str, 00206 const typename Sequence::value_type::value_type sep ) 00207 { 00208 split(sequence, str.begin(), str.end(), sep); 00209 } // split() 00210 00211 /*----------------------------------------------------------------------------*/ 00220 template<typename Sequence> 00221 void claw::text::split 00222 ( Sequence& sequence, typename Sequence::value_type::const_iterator first, 00223 typename Sequence::value_type::const_iterator last, 00224 const typename Sequence::value_type::value_type sep ) 00225 { 00226 typedef typename Sequence::value_type string_type; 00227 00228 string_type line; 00229 std::basic_istringstream< typename string_type::value_type, 00230 typename string_type::traits_type, 00231 typename string_type::allocator_type > iss( string_type(first, last) ); 00232 00233 while ( std::getline(iss, line, sep) ) 00234 *std::insert_iterator<Sequence>(sequence, sequence.end()) = line; 00235 } // split() 00236 00237 /*----------------------------------------------------------------------------*/ 00259 template<typename InputIterator, typename OutputIterator> 00260 void claw::text::c_escape 00261 ( InputIterator first, InputIterator last, OutputIterator out ) 00262 { 00263 typedef typename std::iterator_traits<InputIterator>::value_type char_type; 00264 typedef std::basic_string<char_type> string_type; 00265 00266 const string_type oct("01234567"); 00267 const string_type hex("0123456789ABCDEFabcdef"); 00268 00269 bool escape(false); 00270 00271 for ( ; first!=last; ++out ) 00272 if ( escape ) 00273 { 00274 switch( *first ) 00275 { 00276 case 'a': *out = '\a'; ++first; break; 00277 case 'b': *out = '\b'; ++first; break; 00278 case 'f': *out = '\f'; ++first; break; 00279 case 'n': *out = '\n'; ++first; break; 00280 case 'r': *out = '\r'; ++first; break; 00281 case 't': *out = '\t'; ++first; break; 00282 case 'v': *out = '\v'; ++first; break; 00283 case 'o': 00284 { 00285 ++first; 00286 int v(0); 00287 const InputIterator e 00288 ( find_first_not_of(first, last, oct.begin(), oct.end()) ); 00289 00290 std::basic_istringstream<char_type> iss( string_type(first, e) ); 00291 iss >> std::oct >> v; 00292 *out = (char_type)v; 00293 first = e; 00294 break; 00295 } 00296 case 'x': 00297 { 00298 ++first; 00299 int v(0); 00300 const InputIterator e 00301 ( find_first_not_of(first, last, hex.begin(), hex.end()) ); 00302 00303 std::basic_istringstream<char_type> iss( string_type(first, e) ); 00304 iss >> std::hex >> v; 00305 *out = (char_type)v; 00306 first = e; 00307 break; 00308 } 00309 default: *out = *first; ++first; 00310 } 00311 00312 escape = false; 00313 } 00314 else if ( *first == '\\' ) 00315 { 00316 escape = true; 00317 ++first; 00318 } 00319 else 00320 { 00321 *out = *first; 00322 ++first; 00323 } 00324 } // c_escape() 00325 00326 /*----------------------------------------------------------------------------*/ 00336 template<typename StringType> 00337 bool claw::text::glob_match 00338 ( const StringType& pattern, const StringType& text, 00339 const typename StringType::value_type any_sequence, 00340 const typename StringType::value_type zero_or_one, 00341 const typename StringType::value_type any ) 00342 { 00343 return claw::glob_match 00344 ( pattern.begin(), pattern.end(), text.begin(), text.end(), any_sequence, 00345 zero_or_one, any ); 00346 } // glob_match() 00347 00348 /*----------------------------------------------------------------------------*/ 00358 template<typename StringType> 00359 bool claw::text::glob_potential_match 00360 ( const StringType& pattern, const StringType& text, 00361 const typename StringType::value_type any_sequence, 00362 const typename StringType::value_type zero_or_one, 00363 const typename StringType::value_type any ) 00364 { 00365 return claw::glob_potential_match 00366 ( pattern.begin(), pattern.end(), text.begin(), text.end(), any_sequence, 00367 zero_or_one, any ); 00368 } // glob_potential_match()