1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/base/String.cc
17 #include "zypp/base/String.h"
18 #include "zypp/base/LogTools.h"
22 ///////////////////////////////////////////////////////////////////
24 { /////////////////////////////////////////////////////////////////
25 ///////////////////////////////////////////////////////////////////
27 { /////////////////////////////////////////////////////////////////
29 /******************************************************************
31 ** FUNCTION NAME : form
32 ** FUNCTION TYPE : std::string
34 std::string form( const char * format, ... )
39 va_start( ap, format );
40 vasprintf( &safe._buf, format, ap );
43 return safe.asString();
46 /******************************************************************
48 ** FUNCTION NAME : strerror
49 ** FUNCTION TYPE : std::string
51 std::string strerror( int errno_r )
53 return form( "(%d)%s", errno_r, ::strerror( errno_r ) );
56 /******************************************************************
58 ** FUNCTION NAME : strToTrue
59 ** FUNCTION TYPE : bool
61 bool strToTrue( const C_Str & str )
63 std::string t( toLower( str ) );
69 || strtonum<long long>( str )
73 /******************************************************************
75 ** FUNCTION NAME : strToFalse
76 ** FUNCTION TYPE : bool
78 bool strToFalse( const C_Str & str )
80 std::string t( toLower( str ) );
89 ///////////////////////////////////////////////////////////////////
91 ///////////////////////////////////////////////////////////////////
93 /** What's not decoded. */
94 inline bool heIsAlNum( char ch )
96 return ( ( 'a' <= ch && ch <= 'z' )
97 ||( 'A' <= ch && ch <= 'Z' )
98 ||( '0' <= ch && ch <= '9' ) );
100 /** Hex-digit to number or -1. */
101 inline int heDecodeCh( char ch )
103 if ( '0' <= ch && ch <= '9' )
105 if ( 'A' <= ch && ch <= 'F' )
106 return( ch - 'A' + 10 );
107 if ( 'a' <= ch && ch <= 'f' )
108 return( ch - 'a' + 10 );
113 std::string hexencode( const C_Str & str_r )
115 static const char *const hdig = "0123456789ABCDEF";
117 res.reserve( str_r.size() );
118 for ( const char * it = str_r.c_str(); *it; ++it )
120 if ( heIsAlNum( *it ) )
127 res += hdig[(unsigned char)(*it)/16];
128 res += hdig[(unsigned char)(*it)%16];
134 std::string hexdecode( const C_Str & str_r )
137 res.reserve( str_r.size() );
138 for_( it, str_r.c_str(), str_r.c_str()+str_r.size() )
142 int d1 = heDecodeCh( *(it+1) );
145 int d2 = heDecodeCh( *(it+2) );
154 // verbatim if no %XX:
159 ///////////////////////////////////////////////////////////////////
161 /******************************************************************
163 ** FUNCTION NAME : toLower
164 ** FUNCTION TYPE : std::string
166 std::string toLower( const std::string & s )
171 std::string ret( s );
172 for ( std::string::size_type i = 0; i < ret.length(); ++i )
174 if ( isupper( ret[i] ) )
175 ret[i] = static_cast<char>(tolower( ret[i] ));
180 /******************************************************************
182 ** FUNCTION NAME : toUpper
183 ** FUNCTION TYPE : std::string
185 std::string toUpper( const std::string & s )
190 std::string ret( s );
191 for ( std::string::size_type i = 0; i < ret.length(); ++i )
193 if ( islower( ret[i] ) )
194 ret[i] = static_cast<char>(toupper( ret[i] ));
199 /******************************************************************
201 ** FUNCTION NAME : trim
202 ** FUNCTION TYPE : std::string
204 std::string trim( const std::string & s, const Trim trim_r )
206 if ( s.empty() || trim_r == NO_TRIM )
209 std::string ret( s );
211 if ( trim_r & L_TRIM )
213 std::string::size_type p = ret.find_first_not_of( " \t\n" );
214 if ( p == std::string::npos )
215 return std::string();
217 ret = ret.substr( p );
220 if ( trim_r & R_TRIM )
222 std::string::size_type p = ret.find_last_not_of( " \t\n" );
223 if ( p == std::string::npos )
224 return std::string();
226 ret = ret.substr( 0, p+1 );
232 /******************************************************************
234 ** FUNCTION NAME : stripFirstWord
235 ** FUNCTION TYPE : std::string
237 std::string stripFirstWord( std::string & line, const bool ltrim_first )
240 line = ltrim( line );
246 std::string::size_type p = line.find_first_of( " \t" );
248 if ( p == std::string::npos ) {
252 } else if ( p == 0 ) {
255 line = ltrim( line );
258 // strip word and ltim line
259 ret = line.substr( 0, p );
260 line = ltrim( line.erase( 0, p ) );
265 /******************************************************************
267 ** FUNCTION NAME : stripLastWord
268 ** FUNCTION TYPE : std::string
270 std::string stripLastWord( std::string & line, const bool rtrim_first )
273 line = rtrim( line );
279 std::string::size_type p = line.find_last_of( " \t" );
281 if ( p == std::string::npos ) {
285 } else if ( p == line.size()-1 ) {
288 line = rtrim( line );
291 // strip word and rtim line
292 ret = line.substr( p+1 );
293 line = rtrim( line.erase( p ) );
298 std::string gsub( const std::string & str_r, const std::string & from_r, const std::string & to_r )
300 std::string ret( str_r );
301 return replaceAll( ret, from_r, to_r );
304 std::string & replaceAll( std::string & str_r, const std::string & from_r, const std::string & to_r )
306 if ( ! from_r.empty() )
308 std::string::size_type pos = 0;
309 while ( (pos = str_r.find( from_r, pos )) != std::string::npos )
311 str_r.replace( pos, from_r.size(), to_r );
314 if ( pos >= str_r.length() )
321 std::string gsubFun( const std::string & str_r, const std::string & from_r, function<std::string()> to_r )
323 std::string ret( str_r );
324 return replaceAllFun( ret, from_r, to_r );
327 std::string & replaceAllFun( std::string & str_r, const std::string & from_r, function<std::string()> to_r )
329 if ( ! from_r.empty() )
331 std::string::size_type pos = 0;
332 while ( (pos = str_r.find( from_r, pos )) != std::string::npos )
334 std::string to( to_r() );
335 str_r.replace( pos, from_r.size(), to );
338 if ( pos >= str_r.length() )
345 std::string escape( const C_Str & str_r, const char sep_r )
347 std::vector<char> buf;
348 for_( s, str_r.c_str(), s+str_r.size() )
355 buf.push_back( '\\' );
360 buf.push_back( '\\' );
364 return std::string( buf.begin(), buf.end() );
367 std::string getline( std::istream & str, const Trim trim_r )
369 return trim( receiveUpTo( str, '\n' ), trim_r );
372 std::string getline( std::istream & str, bool trim_r )
374 return trim( receiveUpTo( str, '\n' ), trim_r?TRIM:NO_TRIM );
377 std::string receiveUpTo( std::istream & str, const char delim_r, bool returnDelim_r )
379 std::ostringstream datas;
392 break; // --> delimiter found
397 // clear fail bit if we read data before reaching EOF
398 if ( str.eof() && datas.tellp() )
399 str.clear( std::ios::eofbit );
400 break; // --> no consumable data.
406 /////////////////////////////////////////////////////////////////
408 ///////////////////////////////////////////////////////////////////
409 ////////////////////////////////////////////////////////////////
411 //////////////////////////////////////////////////////////////////