1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/base/String.cc
17 #include "zypp/base/String.h"
18 #include "zypp/base/LogTools.h"
20 #include "zypp/TriBool.h"
24 ///////////////////////////////////////////////////////////////////
26 { /////////////////////////////////////////////////////////////////
27 ///////////////////////////////////////////////////////////////////
29 { /////////////////////////////////////////////////////////////////
31 /******************************************************************
33 ** FUNCTION NAME : form
34 ** FUNCTION TYPE : std::string
36 std::string form( const char * format, ... )
41 va_start( ap, format );
42 vasprintf( &safe._buf, format, ap );
45 return safe.asString();
48 /******************************************************************
50 ** FUNCTION NAME : strerror
51 ** FUNCTION TYPE : std::string
53 std::string strerror( int errno_r )
55 return form( "(%d)%s", errno_r, ::strerror( errno_r ) );
58 /******************************************************************
60 ** FUNCTION NAME : strToTrue
61 ** FUNCTION TYPE : bool
63 bool strToTrue( const C_Str & str )
65 std::string t( toLower( str ) );
71 || strtonum<long long>( str )
75 /******************************************************************
77 ** FUNCTION NAME : strToFalse
78 ** FUNCTION TYPE : bool
80 bool strToFalse( const C_Str & str )
82 std::string t( toLower( str ) );
91 TriBool strToTriBool( const C_Str & str ) // from TriBool.h
93 if ( strToTrue( str ) ) return true;
94 if ( !strToFalse( str ) ) return false;
98 ///////////////////////////////////////////////////////////////////
100 ///////////////////////////////////////////////////////////////////
102 /** What's not decoded. */
103 inline bool heIsAlNum( char ch )
105 return ( ( 'a' <= ch && ch <= 'z' )
106 ||( 'A' <= ch && ch <= 'Z' )
107 ||( '0' <= ch && ch <= '9' ) );
109 /** Hex-digit to number or -1. */
110 inline int heDecodeCh( char ch )
112 if ( '0' <= ch && ch <= '9' )
114 if ( 'A' <= ch && ch <= 'F' )
115 return( ch - 'A' + 10 );
116 if ( 'a' <= ch && ch <= 'f' )
117 return( ch - 'a' + 10 );
122 std::string hexencode( const C_Str & str_r )
124 static const char *const hdig = "0123456789ABCDEF";
126 res.reserve( str_r.size() );
127 for ( const char * it = str_r.c_str(); *it; ++it )
129 if ( heIsAlNum( *it ) )
136 res += hdig[(unsigned char)(*it)/16];
137 res += hdig[(unsigned char)(*it)%16];
143 std::string hexdecode( const C_Str & str_r )
146 res.reserve( str_r.size() );
147 for_( it, str_r.c_str(), str_r.c_str()+str_r.size() )
151 int d1 = heDecodeCh( *(it+1) );
154 int d2 = heDecodeCh( *(it+2) );
163 // verbatim if no %XX:
168 ///////////////////////////////////////////////////////////////////
170 /******************************************************************
172 ** FUNCTION NAME : toLower
173 ** FUNCTION TYPE : std::string
175 std::string toLower( const std::string & s )
176 { return toLower( std::string(s) ); }
178 std::string toLower( std::string && s )
180 std::string ret( std::move(s) );
185 for ( std::string::size_type i = 0; i < ret.length(); ++i )
187 if ( isupper( ret[i] ) )
188 ret[i] = static_cast<char>(tolower( ret[i] ));
193 /******************************************************************
195 ** FUNCTION NAME : toUpper
196 ** FUNCTION TYPE : std::string
198 std::string toUpper( const std::string & s )
199 { return toUpper( std::string(s) ); }
201 std::string toUpper( std::string && s )
203 std::string ret( std::move(s) );
208 for ( std::string::size_type i = 0; i < ret.length(); ++i )
210 if ( islower( ret[i] ) )
211 ret[i] = static_cast<char>(toupper( ret[i] ));
216 /******************************************************************
218 ** FUNCTION NAME : trim
219 ** FUNCTION TYPE : std::string
221 std::string trim( const std::string & s, const Trim trim_r )
222 { return trim( std::string(s), trim_r ); }
224 std::string trim( std::string && s, const Trim trim_r )
226 std::string ret( std::move(s) );
228 if ( ret.empty() || trim_r == NO_TRIM )
231 if ( trim_r & L_TRIM )
233 std::string::size_type p = ret.find_first_not_of( " \t\n" );
234 if ( p == std::string::npos )
242 if ( trim_r & R_TRIM )
244 std::string::size_type p = ret.find_last_not_of( " \t\n" );
245 if ( p == std::string::npos )
250 ret = ret.erase( p+1 );
256 /******************************************************************
258 ** FUNCTION NAME : stripFirstWord
259 ** FUNCTION TYPE : std::string
261 std::string stripFirstWord( std::string & line, const bool ltrim_first )
264 line = ltrim( line );
270 std::string::size_type p = line.find_first_of( " \t" );
272 if ( p == std::string::npos ) {
276 } else if ( p == 0 ) {
279 line = ltrim( line );
282 // strip word and ltim line
283 ret = line.substr( 0, p );
284 line = ltrim( line.erase( 0, p ) );
289 /******************************************************************
291 ** FUNCTION NAME : stripLastWord
292 ** FUNCTION TYPE : std::string
294 std::string stripLastWord( std::string & line, const bool rtrim_first )
297 line = rtrim( line );
303 std::string::size_type p = line.find_last_of( " \t" );
305 if ( p == std::string::npos ) {
309 } else if ( p == line.size()-1 ) {
312 line = rtrim( line );
315 // strip word and rtim line
316 ret = line.substr( p+1 );
317 line = rtrim( line.erase( p ) );
322 std::string gsub( const std::string & str_r, const std::string & from_r, const std::string & to_r )
324 std::string ret( str_r );
325 return replaceAll( ret, from_r, to_r );
328 std::string & replaceAll( std::string & str_r, const std::string & from_r, const std::string & to_r )
330 if ( ! from_r.empty() )
332 std::string::size_type pos = 0;
333 while ( (pos = str_r.find( from_r, pos )) != std::string::npos )
335 str_r.replace( pos, from_r.size(), to_r );
338 if ( pos >= str_r.length() )
345 std::string gsubFun( const std::string & str_r, const std::string & from_r, function<std::string()> to_r )
347 std::string ret( str_r );
348 return replaceAllFun( ret, from_r, to_r );
351 std::string & replaceAllFun( std::string & str_r, const std::string & from_r, function<std::string()> to_r )
353 if ( ! from_r.empty() )
355 std::string::size_type pos = 0;
356 while ( (pos = str_r.find( from_r, pos )) != std::string::npos )
358 std::string to( to_r() );
359 str_r.replace( pos, from_r.size(), to );
362 if ( pos >= str_r.length() )
369 std::string escape( const C_Str & str_r, const char sep_r )
371 std::vector<char> buf;
372 for_( s, str_r.c_str(), s+str_r.size() )
379 buf.push_back( '\\' );
384 buf.push_back( '\\' );
388 return std::string( buf.begin(), buf.end() );
391 std::string getline( std::istream & str, const Trim trim_r )
393 return trim( receiveUpTo( str, '\n' ), trim_r );
396 std::string getline( std::istream & str, bool trim_r )
398 return trim( receiveUpTo( str, '\n' ), trim_r?TRIM:NO_TRIM );
401 std::string receiveUpTo( std::istream & str, const char delim_r, bool returnDelim_r )
403 std::ostringstream datas;
416 break; // --> delimiter found
421 // clear fail bit if we read data before reaching EOF
422 if ( str.eof() && datas.tellp() )
423 str.clear( std::ios::eofbit );
424 break; // --> no consumable data.
430 /////////////////////////////////////////////////////////////////
432 ///////////////////////////////////////////////////////////////////
433 ////////////////////////////////////////////////////////////////
435 //////////////////////////////////////////////////////////////////