00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }