libzypp  13.10.6
String.cc
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
12 #include <cstdio>
13 #include <cstdarg>
14 
15 #include <iostream>
16 
17 #include "zypp/base/String.h"
18 #include "zypp/base/LogTools.h"
19 
20 using std::string;
21 
23 namespace zypp
24 {
25  namespace str
27  {
28 
29  /******************************************************************
30  **
31  ** FUNCTION NAME : form
32  ** FUNCTION TYPE : std::string
33  */
34  std::string form( const char * format, ... )
35  {
36  SafeBuf safe;
37 
38  va_list ap;
39  va_start( ap, format );
40  vasprintf( &safe._buf, format, ap );
41  va_end( ap );
42 
43  return safe.asString();
44  }
45 
46  /******************************************************************
47  **
48  ** FUNCTION NAME : strerror
49  ** FUNCTION TYPE : std::string
50  */
51  std::string strerror( int errno_r )
52  {
53  return form( "(%d)%s", errno_r, ::strerror( errno_r ) );
54  }
55 
56  /******************************************************************
57  **
58  ** FUNCTION NAME : strToTrue
59  ** FUNCTION TYPE : bool
60  */
61  bool strToTrue( const C_Str & str )
62  {
63  std::string t( toLower( str ) );
64  return( t == "1"
65  || t == "yes"
66  || t == "true"
67  || t == "on"
68  || t == "+"
69  || strtonum<long long>( str )
70  );
71  }
72 
73  /******************************************************************
74  **
75  ** FUNCTION NAME : strToFalse
76  ** FUNCTION TYPE : bool
77  */
78  bool strToFalse( const C_Str & str )
79  {
80  std::string t( toLower( str ) );
81  return ! ( t == "0"
82  || t == "no"
83  || t == "false"
84  || t == "off"
85  || t == "-"
86  );
87  }
88 
90  // Hexencode
92  namespace {
94  inline bool heIsAlNum( char ch )
95  {
96  return ( ( 'a' <= ch && ch <= 'z' )
97  ||( 'A' <= ch && ch <= 'Z' )
98  ||( '0' <= ch && ch <= '9' ) );
99  }
101  inline int heDecodeCh( char ch )
102  {
103  if ( '0' <= ch && ch <= '9' )
104  return( ch - '0' );
105  if ( 'A' <= ch && ch <= 'F' )
106  return( ch - 'A' + 10 );
107  if ( 'a' <= ch && ch <= 'f' )
108  return( ch - 'a' + 10 );
109  return -1;
110  }
111  }
112 
113  std::string hexencode( const C_Str & str_r )
114  {
115  static const char *const hdig = "0123456789ABCDEF";
116  std::string res;
117  res.reserve( str_r.size() );
118  for ( const char * it = str_r.c_str(); *it; ++it )
119  {
120  if ( heIsAlNum( *it ) )
121  {
122  res += *it;
123  }
124  else
125  {
126  res += '%';
127  res += hdig[(unsigned char)(*it)/16];
128  res += hdig[(unsigned char)(*it)%16];
129  }
130  }
131  return res;
132  }
133 
134  std::string hexdecode( const C_Str & str_r )
135  {
136  std::string res;
137  res.reserve( str_r.size() );
138  for_( it, str_r.c_str(), str_r.c_str()+str_r.size() )
139  {
140  if ( *it == '%' )
141  {
142  int d1 = heDecodeCh( *(it+1) );
143  if ( d1 != -1 )
144  {
145  int d2 = heDecodeCh( *(it+2) );
146  if ( d2 != -1 )
147  {
148  res += (d1<<4)|d2;
149  it += 2;
150  continue;
151  }
152  }
153  }
154  // verbatim if no %XX:
155  res += *it;
156  }
157  return res;
158  }
160 
161  /******************************************************************
162  **
163  ** FUNCTION NAME : toLower
164  ** FUNCTION TYPE : std::string
165  */
166  std::string toLower( const std::string & s )
167  {
168  if ( s.empty() )
169  return s;
170 
171  std::string ret( s );
172  for ( std::string::size_type i = 0; i < ret.length(); ++i )
173  {
174  if ( isupper( ret[i] ) )
175  ret[i] = static_cast<char>(tolower( ret[i] ));
176  }
177  return ret;
178  }
179 
180  /******************************************************************
181  **
182  ** FUNCTION NAME : toUpper
183  ** FUNCTION TYPE : std::string
184  */
185  std::string toUpper( const std::string & s )
186  {
187  if ( s.empty() )
188  return s;
189 
190  std::string ret( s );
191  for ( std::string::size_type i = 0; i < ret.length(); ++i )
192  {
193  if ( islower( ret[i] ) )
194  ret[i] = static_cast<char>(toupper( ret[i] ));
195  }
196  return ret;
197  }
198 
199  /******************************************************************
200  **
201  ** FUNCTION NAME : trim
202  ** FUNCTION TYPE : std::string
203  */
204  std::string trim( const std::string & s, const Trim trim_r )
205  {
206  if ( s.empty() || trim_r == NO_TRIM )
207  return s;
208 
209  std::string ret( s );
210 
211  if ( trim_r & L_TRIM )
212  {
213  std::string::size_type p = ret.find_first_not_of( " \t\n" );
214  if ( p == std::string::npos )
215  return std::string();
216 
217  ret = ret.substr( p );
218  }
219 
220  if ( trim_r & R_TRIM )
221  {
222  std::string::size_type p = ret.find_last_not_of( " \t\n" );
223  if ( p == std::string::npos )
224  return std::string();
225 
226  ret = ret.substr( 0, p+1 );
227  }
228 
229  return ret;
230  }
231 
232  /******************************************************************
233  **
234  ** FUNCTION NAME : stripFirstWord
235  ** FUNCTION TYPE : std::string
236  */
237  std::string stripFirstWord( std::string & line, const bool ltrim_first )
238  {
239  if ( ltrim_first )
240  line = ltrim( line );
241 
242  if ( line.empty() )
243  return line;
244 
245  std::string ret;
246  std::string::size_type p = line.find_first_of( " \t" );
247 
248  if ( p == std::string::npos ) {
249  // no ws on line
250  ret = line;
251  line.erase();
252  } else if ( p == 0 ) {
253  // starts with ws
254  // ret remains empty
255  line = ltrim( line );
256  }
257  else {
258  // strip word and ltim line
259  ret = line.substr( 0, p );
260  line = ltrim( line.erase( 0, p ) );
261  }
262  return ret;
263  }
264 
265  /******************************************************************
266  **
267  ** FUNCTION NAME : stripLastWord
268  ** FUNCTION TYPE : std::string
269  */
270  std::string stripLastWord( std::string & line, const bool rtrim_first )
271  {
272  if ( rtrim_first )
273  line = rtrim( line );
274 
275  if ( line.empty() )
276  return line;
277 
278  std::string ret;
279  std::string::size_type p = line.find_last_of( " \t" );
280 
281  if ( p == std::string::npos ) {
282  // no ws on line
283  ret = line;
284  line.erase();
285  } else if ( p == line.size()-1 ) {
286  // ends with ws
287  // ret remains empty
288  line = rtrim( line );
289  }
290  else {
291  // strip word and rtim line
292  ret = line.substr( p+1 );
293  line = rtrim( line.erase( p ) );
294  }
295  return ret;
296  }
297 
298  std::string gsub( const std::string & str_r, const std::string & from_r, const std::string & to_r )
299  {
300  std::string ret( str_r );
301  return replaceAll( ret, from_r, to_r );
302  }
303 
304  std::string & replaceAll( std::string & str_r, const std::string & from_r, const std::string & to_r )
305  {
306  std::string::size_type pos = 0;
307  while ( (pos = str_r.find( from_r, pos )) != std::string::npos )
308  {
309  str_r.replace( pos, from_r.size(), to_r );
310  pos += to_r.size();
311 
312  if ( pos >= str_r.length() )
313  break;
314  }
315  return str_r;
316  }
317 
318  std::string gsubFun( const std::string & str_r, const std::string & from_r, function<std::string()> to_r )
319  {
320  std::string ret( str_r );
321  return replaceAllFun( ret, from_r, to_r );
322  }
323 
324  std::string & replaceAllFun( std::string & str_r, const std::string & from_r, function<std::string()> to_r )
325  {
326  std::string::size_type pos = 0;
327  while ( (pos = str_r.find( from_r, pos )) != std::string::npos )
328  {
329  std::string to( to_r() );
330  str_r.replace( pos, from_r.size(), to );
331  pos += to.size();
332 
333  if ( pos >= str_r.length() )
334  break;
335  }
336  return str_r;
337  }
338 
339  std::string escape( const C_Str & str_r, const char sep_r )
340  {
341  std::vector<char> buf;
342  for_( s, str_r.c_str(), s+str_r.size() )
343  {
344  switch ( *s )
345  {
346  case '"':
347  case '\'':
348  case '\\':
349  buf.push_back( '\\' );
350  buf.push_back( *s );
351  break;
352  default:
353  if ( *s == sep_r )
354  buf.push_back( '\\' );
355  buf.push_back( *s );
356  }
357  }
358  return std::string( buf.begin(), buf.end() );
359  }
360 
361  std::string getline( std::istream & str, const Trim trim_r )
362  {
363  return trim( receiveUpTo( str, '\n' ), trim_r );
364  }
365 
366  std::string getline( std::istream & str, bool trim_r )
367  {
368  return trim( receiveUpTo( str, '\n' ), trim_r?TRIM:NO_TRIM );
369  }
370 
371  std::string receiveUpTo( std::istream & str, const char delim_r, bool returnDelim_r )
372  {
373  std::ostringstream datas;
374  do {
375  char ch;
376  if ( str.get( ch ) )
377  {
378  if ( ch != delim_r )
379  {
380  datas.put( ch );
381  }
382  else
383  {
384  if ( returnDelim_r )
385  datas.put( ch );
386  break; // --> delimiter found
387  }
388  }
389  else
390  {
391  // clear fail bit if we read data before reaching EOF
392  if ( str.eof() && datas.tellp() )
393  str.clear( std::ios::eofbit );
394  break; // --> no consumable data.
395  }
396  } while ( true );
397  return datas.str();
398  }
399 
401  } // namespace str
404 } // namespace zypp
std::string escape(const C_Str &str_r, const char sep_r)
Escape desired character c using a backslash.
Definition: String.cc:339
std::string asString() const
Definition: String.h:178
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
Definition: Easy.h:27
Trim
To define how to trim.
Definition: String.h:783
std::string ltrim(const std::string &s)
Definition: String.h:792
std::string & replaceAll(std::string &str_r, const std::string &from_r, const std::string &to_r)
Replace all occurrences of from_r with to_r in str_r (inplace).
Definition: String.cc:304
std::string stripFirstWord(std::string &line, const bool ltrim_first)
Definition: String.cc:237
std::string trim(const std::string &s, const Trim trim_r)
Definition: String.cc:204
Convenience char* constructible from std::string and char*, it maps (char*)0 to an empty string...
Definition: String.h:81
std::string getline(std::istream &str, const Trim trim_r)
Return stream content up to (but not returning) the next newline.
Definition: String.cc:361
std::string stripLastWord(std::string &line, const bool rtrim_first)
Definition: String.cc:270
bool strToFalse(const C_Str &str)
Return false if str is 0, false, no, off.
Definition: String.cc:78
std::string gsubFun(const std::string &str_r, const std::string &from_r, function< std::string()> to_r)
Definition: String.cc:318
std::string toLower(const std::string &s)
Return lowercase version of s.
Definition: String.cc:166
SolvableIdType size_type
Definition: PoolMember.h:99
std::string rtrim(const std::string &s)
Definition: String.h:795
bool strToTrue(const C_Str &str)
Parsing boolean from string.
Definition: String.cc:61
std::string form(const char *format,...)
Printf style construction of std::string.
Definition: String.cc:34
std::string & replaceAllFun(std::string &str_r, const std::string &from_r, function< std::string()> to_r)
Definition: String.cc:324
std::string gsub(const std::string &str_r, const std::string &from_r, const std::string &to_r)
Return a string with all occurrences of from_r replaced with to_r.
Definition: String.cc:298
std::string receiveUpTo(std::istream &str, const char delim_r, bool returnDelim_r)
Return stream content up to the next ocurrence of delim_r or EOF delim_r, if found, is always read from the stream.
Definition: String.cc:371
const char * c_str() const
Definition: String.h:103
std::string hexencode(const C_Str &str_r)
Encode all characters other than [a-zA-Z0-9] as XX.
Definition: String.cc:113
size_type size() const
Definition: String.h:95
std::string strerror(int errno_r)
Return string describing the error_r code.
Definition: String.cc:51
std::string toUpper(const std::string &s)
Return uppercase version of s.
Definition: String.cc:185
Assert free called for allocated char *.
Definition: String.h:173
std::string hexdecode(const C_Str &str_r)
Decode hexencoded XX sequences.
Definition: String.cc:134