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 )
180 std::string ret( s );
181 for ( std::string::size_type i = 0; i < ret.length(); ++i )
183 if ( isupper( ret[i] ) )
184 ret[i] = static_cast<char>(tolower( ret[i] ));
189 /******************************************************************
191 ** FUNCTION NAME : toUpper
192 ** FUNCTION TYPE : std::string
194 std::string toUpper( const std::string & s )
199 std::string ret( s );
200 for ( std::string::size_type i = 0; i < ret.length(); ++i )
202 if ( islower( ret[i] ) )
203 ret[i] = static_cast<char>(toupper( ret[i] ));
208 /******************************************************************
210 ** FUNCTION NAME : trim
211 ** FUNCTION TYPE : std::string
213 std::string trim( const std::string & s, const Trim trim_r )
215 if ( s.empty() || trim_r == NO_TRIM )
218 std::string ret( s );
220 if ( trim_r & L_TRIM )
222 std::string::size_type p = ret.find_first_not_of( " \t\n" );
223 if ( p == std::string::npos )
224 return std::string();
226 ret = ret.substr( p );
229 if ( trim_r & R_TRIM )
231 std::string::size_type p = ret.find_last_not_of( " \t\n" );
232 if ( p == std::string::npos )
233 return std::string();
235 ret = ret.substr( 0, p+1 );
241 /******************************************************************
243 ** FUNCTION NAME : stripFirstWord
244 ** FUNCTION TYPE : std::string
246 std::string stripFirstWord( std::string & line, const bool ltrim_first )
249 line = ltrim( line );
255 std::string::size_type p = line.find_first_of( " \t" );
257 if ( p == std::string::npos ) {
261 } else if ( p == 0 ) {
264 line = ltrim( line );
267 // strip word and ltim line
268 ret = line.substr( 0, p );
269 line = ltrim( line.erase( 0, p ) );
274 /******************************************************************
276 ** FUNCTION NAME : stripLastWord
277 ** FUNCTION TYPE : std::string
279 std::string stripLastWord( std::string & line, const bool rtrim_first )
282 line = rtrim( line );
288 std::string::size_type p = line.find_last_of( " \t" );
290 if ( p == std::string::npos ) {
294 } else if ( p == line.size()-1 ) {
297 line = rtrim( line );
300 // strip word and rtim line
301 ret = line.substr( p+1 );
302 line = rtrim( line.erase( p ) );
307 std::string gsub( const std::string & str_r, const std::string & from_r, const std::string & to_r )
309 std::string ret( str_r );
310 return replaceAll( ret, from_r, to_r );
313 std::string & replaceAll( std::string & str_r, const std::string & from_r, const std::string & to_r )
315 if ( ! from_r.empty() )
317 std::string::size_type pos = 0;
318 while ( (pos = str_r.find( from_r, pos )) != std::string::npos )
320 str_r.replace( pos, from_r.size(), to_r );
323 if ( pos >= str_r.length() )
330 std::string gsubFun( const std::string & str_r, const std::string & from_r, function<std::string()> to_r )
332 std::string ret( str_r );
333 return replaceAllFun( ret, from_r, to_r );
336 std::string & replaceAllFun( std::string & str_r, const std::string & from_r, function<std::string()> to_r )
338 if ( ! from_r.empty() )
340 std::string::size_type pos = 0;
341 while ( (pos = str_r.find( from_r, pos )) != std::string::npos )
343 std::string to( to_r() );
344 str_r.replace( pos, from_r.size(), to );
347 if ( pos >= str_r.length() )
354 std::string escape( const C_Str & str_r, const char sep_r )
356 std::vector<char> buf;
357 for_( s, str_r.c_str(), s+str_r.size() )
364 buf.push_back( '\\' );
369 buf.push_back( '\\' );
373 return std::string( buf.begin(), buf.end() );
376 std::string getline( std::istream & str, const Trim trim_r )
378 return trim( receiveUpTo( str, '\n' ), trim_r );
381 std::string getline( std::istream & str, bool trim_r )
383 return trim( receiveUpTo( str, '\n' ), trim_r?TRIM:NO_TRIM );
386 std::string receiveUpTo( std::istream & str, const char delim_r, bool returnDelim_r )
388 std::ostringstream datas;
401 break; // --> delimiter found
406 // clear fail bit if we read data before reaching EOF
407 if ( str.eof() && datas.tellp() )
408 str.clear( std::ios::eofbit );
409 break; // --> no consumable data.
415 /////////////////////////////////////////////////////////////////
417 ///////////////////////////////////////////////////////////////////
418 ////////////////////////////////////////////////////////////////
420 //////////////////////////////////////////////////////////////////