libzypp  17.1.1
String.h
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
12 #ifndef ZYPP_BASE_STRING_H
13 #define ZYPP_BASE_STRING_H
14 
15 #include <cstring>
16 
17 #include <iosfwd>
18 #include <vector>
19 #include <string>
20 #include <sstream>
21 #include <boost/format.hpp>
22 #include <boost/utility/string_ref.hpp>
23 
24 #include "zypp/base/Easy.h"
25 #include "zypp/base/PtrTypes.h"
26 #include "zypp/base/Function.h"
27 
29 namespace boost { namespace logic { class tribool; } }
30 namespace zypp { typedef boost::logic::tribool TriBool; }
32 
34 namespace zypp
35 {
39  template <class Tp>
40  std::string asUserString( const Tp & val_r )
41  { return val_r.asUserString(); }
42 
43 }// namespace zypp
45 
47 namespace zypp
48 {
49 
90  class C_Str
91  {
92  public:
94 
95  public:
96  C_Str() : _val( 0 ), _sze( 0 ) {}
97  C_Str( char * c_str_r ) : _val( c_str_r ), _sze( std::string::npos ) {}
98  C_Str( const char * c_str_r ) : _val( c_str_r ), _sze( std::string::npos ) {}
99  C_Str( const std::string & str_r ) : _val( str_r.c_str() ), _sze( str_r.size() ) {}
100  C_Str( const boost::string_ref & str_r ) : _val( str_r.data() ), _sze( str_r.size() ) {}
101 
102  public:
103  bool isNull() const { return !_val; }
104  bool empty() const { return !(_val && *_val); }
105  size_type size() const
106  {
107  if ( _sze == std::string::npos )
108  { _sze = _val ? ::strlen( _val ) : 0; }
109  return _sze;
110  };
111 
112  operator const char *() const { return c_str(); }
113  const char * c_str() const { return _val ? _val : ""; }
114 
115  private:
116  const char *const _val;
117  mutable size_type _sze;
118  };
119 
121  inline std::ostream & operator<<( std::ostream & str, const C_Str & obj )
122  { return str << obj.c_str(); }
123 
125 
129  namespace str
130  {
131 
133 
136  inline const std::string & asString( const std::string & t )
137  { return t; }
138 
139 #ifndef SWIG // Swig treats it as syntax error
140  inline std::string && asString( std::string && t )
141  { return std::move(t); }
142 #endif
143 
144  inline std::string asString( const char * t )
145  { return t; }
146 
147  inline std::string asString( char * t )
148  { return t; }
149 
150  template<class Tp>
151  inline std::string asString( const Tp &t )
152  { return t.asString(); }
153 
154  template<class Tp>
155  inline std::string asString( const intrusive_ptr<Tp> &p )
156  { return p->asString(); }
157 
158  template<class Tp>
159  inline std::string asString( const weak_ptr<Tp> &p )
160  { return p->asString(); }
161 
162  template<>
163  inline std::string asString( const bool &t )
164  { return t ? "true" : "false"; }
165 
167 
168  std::string form( const char * format, ... )
169  __attribute__ ((format (printf, 1, 2)));
170 
172 
176  std::string strerror( int errno_r );
177 
179 
189  struct SafeBuf
190  {
191  char * _buf;
192  SafeBuf() : _buf( 0 ) {}
193  ~SafeBuf() { if ( _buf ) free( _buf ); }
194  std::string asString() const
195  { return _buf ? std::string(_buf) : std::string(); }
196  };
197 
210  struct Str
211  {
212  template<class Tp>
213  Str & operator<<( Tp && val )
214  { _str << std::forward<Tp>(val); return *this; }
215 
216  Str & operator<<( std::ostream& (*iomanip)( std::ostream& ) )
217  { _str << iomanip; return *this; }
218 
219  operator std::string() const { return _str.str(); }
220  std::string asString() const { return _str.str(); }
221  std::string str() const { return _str.str(); }
222 
223  const std::ostream & stream() const { return _str; }
224  std::ostream & stream() { return _str; }
225 
226  void clear() { _str.str( std::string() ); }
227 
228  private:
229  std::ostringstream _str;
230  };
231 
233  inline std::ostream & operator<<( std::ostream & str, const Str & obj )
234  { return str << obj.str(); }
235 
248  struct Format
249  {
250  Format() {}
251  Format( const std::string & format_r ) : _fmter( format_r ) {}
252 
253  template<class Tp>
254  Format & operator%( Tp && arg )
255  { _fmter % std::forward<Tp>(arg); return *this; }
256 
257  operator std::string() const { return _fmter.str(); }
258  std::string asString() const { return _fmter.str(); }
259  std::string str() const { return _fmter.str(); }
260 
261  const boost::format & fmter() const { return _fmter; }
262  boost::format & fmter() { return _fmter; }
263 
264  protected:
265  boost::format _fmter;
266  };
267 
269  inline std::ostream & operator<<( std::ostream & str, const Format & obj )
270  { return str << obj.fmter(); }
271 
279  struct FormatNAC : public Format
280  {
281  FormatNAC() { relax(); }
282  FormatNAC( const std::string & format_r ) : Format( format_r ) { relax(); }
283 
284  private:
285  void relax()
286  {
287  using namespace boost::io;
288  _fmter.exceptions( all_error_bits ^ ( too_many_args_bit | too_few_args_bit ) );
289  }
290  };
292 
305  inline std::string numstring( char n, int w = 0 ) { return form( "%*hhd", w, n ); }
306  inline std::string numstring( unsigned char n, int w = 0 ) { return form( "%*hhu", w, n ); }
307  inline std::string numstring( short n, int w = 0 ) { return form( "%*hd", w, n ); }
308  inline std::string numstring( unsigned short n, int w = 0 ) { return form( "%*hu", w, n ); }
309  inline std::string numstring( int n, int w = 0 ) { return form( "%*d", w, n ); }
310  inline std::string numstring( unsigned n, int w = 0 ) { return form( "%*u", w, n ); }
311  inline std::string numstring( long n, int w = 0 ) { return form( "%*ld", w, n ); }
312  inline std::string numstring( unsigned long n, int w = 0 ) { return form( "%*lu", w, n ); }
313  inline std::string numstring( long long n, int w = 0 ) { return form( "%*lld", w, n ); }
314  inline std::string numstring( unsigned long long n, int w = 0 ) { return form( "%*llu", w, n ); }
315 
316  template<> inline std::string asString( const char & t ) { return numstring( t ); }
317  template<> inline std::string asString( const unsigned char & t ) { return numstring( t ); }
318  template<> inline std::string asString( const short & t ) { return numstring( t ); }
319  template<> inline std::string asString( const unsigned short & t ) { return numstring( t ); }
320  template<> inline std::string asString( const int & t ) { return numstring( t ); }
321  template<> inline std::string asString( const unsigned & t ) { return numstring( t ); }
322  template<> inline std::string asString( const long & t ) { return numstring( t ); }
323  template<> inline std::string asString( const unsigned long & t ) { return numstring( t ); }
324  template<> inline std::string asString( const long long & t ) { return numstring( t ); }
325  template<> inline std::string asString( const unsigned long long & t ) { return numstring( t ); }
327 
329 
340  inline std::string hexstring( char n, int w = 4 ) { return form( "%#0*hhx", w, n ); }
341  inline std::string hexstring( unsigned char n, int w = 4 ) { return form( "%#0*hhx", w, n ); }
342  inline std::string hexstring( short n, int w = 10 ){ return form( "%#0*hx", w, n ); }
343  inline std::string hexstring( unsigned short n, int w = 10 ){ return form( "%#0*hx", w, n ); }
344  inline std::string hexstring( int n, int w = 10 ){ return form( "%#0*x", w, n ); }
345  inline std::string hexstring( unsigned n, int w = 10 ){ return form( "%#0*x", w, n ); }
346  inline std::string hexstring( long n, int w = 10 ){ return form( "%#0*lx", w, n ); }
347  inline std::string hexstring( unsigned long n, int w = 10 ){ return form( "%#0*lx", w, n ); }
348  inline std::string hexstring( long long n, int w = 0 ) { return form( "%#0*llx", w, n ); }
349  inline std::string hexstring( unsigned long long n, int w = 0 ) { return form( "%#0*llx", w, n ); }
351 
353 
364  inline std::string octstring( char n, int w = 4 ) { return form( "%#0*hho", w, n ); }
365  inline std::string octstring( unsigned char n, int w = 4 ) { return form( "%#0*hho", w, n ); }
366  inline std::string octstring( short n, int w = 5 ) { return form( "%#0*ho", w, n ); }
367  inline std::string octstring( unsigned short n, int w = 5 ) { return form( "%#0*ho", w, n ); }
368  inline std::string octstring( int n, int w = 5 ) { return form( "%#0*o", w, n ); }
369  inline std::string octstring( unsigned n, int w = 5 ) { return form( "%#0*o", w, n ); }
370  inline std::string octstring( long n, int w = 5 ) { return form( "%#0*lo", w, n ); }
371  inline std::string octstring( unsigned long n, int w = 5 ) { return form( "%#0*lo", w, n ); }
372  inline std::string octstring( long long n, int w = 0 ) { return form( "%#0*llo", w, n ); }
373  inline std::string octstring( unsigned long long n, int w = 0 ) { return form( "%#0*llo", w, n ); }
375 
376 
378 
379  template <typename TInt>
380  std::string binstring( TInt val_r )
381  {
382  constexpr unsigned bits = sizeof(TInt)*8;
383  std::string ret( bits, ' ' );
384  TInt bit = 1;
385  for ( unsigned pos = bits; pos > 0; )
386  { --pos; ret[pos] = ((val_r & bit)?'1':'0'); bit = bit<<1; }
387  return ret;
388  }
389 
391 
400  template<typename TInt>
401  TInt strtonum( const C_Str & str );
402 
403  template<>
404  inline short strtonum( const C_Str & str ) { return ::strtol ( str, NULL, 0 ); }
405  template<>
406  inline int strtonum( const C_Str & str ) { return ::strtol ( str, NULL, 0 ); }
407  template<>
408  inline long strtonum( const C_Str & str ) { return ::strtol ( str, NULL, 0 ); }
409  template<>
410  inline long long strtonum( const C_Str & str ) { return ::strtoll ( str, NULL, 0 ); }
411 
412  template<>
413  inline unsigned short strtonum( const C_Str & str ) { return ::strtoul ( str, NULL, 0 ); }
414  template<>
415  inline unsigned strtonum( const C_Str & str ) { return ::strtoul ( str, NULL, 0 ); }
416  template<>
417  inline unsigned long strtonum( const C_Str & str ) { return ::strtoul ( str, NULL, 0 ); }
418  template<>
419  inline unsigned long long strtonum( const C_Str & str ) { return ::strtoull( str, NULL, 0 ); }
420 
426  template<typename TInt>
427  inline TInt strtonum( const C_Str & str, TInt & i )
428  { return i = strtonum<TInt>( str ); }
430 
432 
436  bool strToTrue( const C_Str & str );
437 
439  bool strToFalse( const C_Str & str );
440 
445  inline bool strToBool( const C_Str & str, bool default_r )
446  { return( default_r ? strToFalse( str ) : strToTrue( str ) ); }
447 
452  inline bool strToBoolNodefault( const C_Str & str, bool & return_r )
453  {
454  if ( strToTrue( str ) ) return (return_r = true);
455  if ( !strToFalse( str ) ) return (return_r = false);
456  return return_r;
457  }
458 
460  TriBool strToTriBool( const C_Str & str );
461 
463 
467  std::string gsub( const std::string & str_r, const std::string & from_r, const std::string & to_r );
468 
471  std::string gsubFun( const std::string & str_r, const std::string & from_r, function<std::string()> to_r );
472 
477  std::string & replaceAll( std::string & str_r, const std::string & from_r, const std::string & to_r );
478 
481  std::string & replaceAllFun( std::string & str_r, const std::string & from_r, function<std::string()> to_r );
482 
495  inline std::string gapify( std::string inp_r, std::string::size_type gap_r = 1, char gapchar = ' ' )
496  {
497  if ( gap_r && inp_r.size() > gap_r )
498  {
499  inp_r.reserve( inp_r.size() + (inp_r.size()-1)/gap_r );
500  for ( std::string::size_type pos = gap_r; pos < inp_r.size(); pos += gap_r+1 )
501  inp_r.insert( pos, 1, gapchar );
502  }
503  return inp_r;
504  }
505 
507 
518  template<class TOutputIterator>
519  unsigned split( const C_Str & line_r, TOutputIterator result_r, const C_Str & sepchars_r = " \t" )
520  {
521  const char * beg = line_r;
522  const char * cur = beg;
523  // skip leading sepchars
524  while ( *cur && ::strchr( sepchars_r, *cur ) )
525  ++cur;
526  unsigned ret = 0;
527  for ( beg = cur; *beg; beg = cur, ++result_r, ++ret )
528  {
529  // skip non sepchars
530  while( *cur && !::strchr( sepchars_r, *cur ) )
531  ++cur;
532  // build string
533  *result_r = std::string( beg, cur-beg );
534  // skip sepchars
535  while ( *cur && ::strchr( sepchars_r, *cur ) )
536  ++cur;
537  }
538  return ret;
539  }
540 
577  template<class TOutputIterator>
578  unsigned splitEscaped( const C_Str & line_r, TOutputIterator result_r, const C_Str & sepchars_r = " \t", bool withEmpty = false)
579  {
580  const char * beg = line_r;
581  const char * cur = beg;
582  unsigned ret = 0;
583 
584  // skip leading sepchars
585  while ( *cur && ::strchr( sepchars_r, *cur ) )
586  {
587  ++cur;
588  if (withEmpty)
589  {
590  *result_r = "";
591  ++ret;
592  }
593  }
594 
595  // there were only sepchars in the string
596  if (!*cur && withEmpty)
597  {
598  *result_r = "";
599  return ++ret;
600  }
601 
602  // after the leading sepchars
603  enum class Quote { None, Slash, Single, Double, DoubleSlash };
604  std::vector<char> buf;
605  Quote quoting = Quote::None;
606  for ( beg = cur; *beg; beg = cur, ++result_r, ++ret )
607  {
608  // read next value until unquoted sepchar
609  buf.clear();
610  quoting = Quote::None;
611  do {
612  switch ( quoting )
613  {
614  case Quote::None:
615  switch ( *cur )
616  {
617  case '\\': quoting = Quote::Slash; break;
618  case '\'': quoting = Quote::Single; break;
619  case '"': quoting = Quote::Double; break;
620  default: buf.push_back( *cur ); break;
621  }
622  break;
623 
624  case Quote::Slash:
625  buf.push_back( *cur );
626  quoting = Quote::None;
627  break;
628 
629  case Quote::Single:
630  switch ( *cur )
631  {
632  case '\'': quoting = Quote::None; break;
633  default: buf.push_back( *cur ); break;
634  }
635  break;
636 
637  case Quote::Double:
638  switch ( *cur )
639  {
640  case '\"': quoting = Quote::None; break;
641  case '\\': quoting = Quote::DoubleSlash; break;
642  default: buf.push_back( *cur ); break;
643  }
644  break;
645 
646  case Quote::DoubleSlash:
647  switch ( *cur )
648  {
649  case '\"': /*fallthrough*/
650  case '\\': buf.push_back( *cur ); break;
651  default:
652  buf.push_back( '\\' );
653  buf.push_back( *cur );
654  break;
655  }
656  quoting = Quote::Double;
657  break;
658  }
659  ++cur;
660  } while ( *cur && ( quoting != Quote::None || !::strchr( sepchars_r, *cur ) ) );
661  *result_r = std::string( buf.begin(), buf.end() );
662 
663 
664  // skip sepchars
665  if ( *cur && ::strchr( sepchars_r, *cur ) )
666  ++cur;
667  while ( *cur && ::strchr( sepchars_r, *cur ) )
668  {
669  ++cur;
670  if (withEmpty)
671  {
672  *result_r = "";
673  ++ret;
674  }
675  }
676  // the last was a separator => one more field
677  if ( !*cur && withEmpty && ::strchr( sepchars_r, *(cur-1) ) )
678  {
679  *result_r = "";
680  ++ret;
681  }
682  }
683  return ret;
684  }
685 
707  template<class TOutputIterator>
708  unsigned splitFields( const C_Str & line_r, TOutputIterator result_r, const C_Str & sepchars_r = ":" )
709  {
710  const char * beg = line_r;
711  const char * cur = beg;
712  unsigned ret = 0;
713  for ( beg = cur; *beg; beg = cur, ++result_r )
714  {
715  // skip non sepchars
716  while( *cur && !::strchr( sepchars_r, *cur ) )
717  {
718  if ( *cur == '\\' && *(cur+1) )
719  ++cur;
720  ++cur;
721  }
722  // build string
723  *result_r = std::string( beg, cur-beg );
724  ++ret;
725  // skip sepchar
726  if ( *cur )
727  {
728  ++cur;
729  if ( ! *cur ) // ending with sepchar
730  {
731  *result_r = std::string(); // add final empty field
732  ++ret;
733  break;
734  }
735  }
736  }
737  return ret;
738  }
739 
746  template<class TOutputIterator>
747  unsigned splitFieldsEscaped( const C_Str & line_r, TOutputIterator result_r, const C_Str & sepchars_r = ":" )
748  {
749  return splitEscaped( line_r, result_r, sepchars_r, true /* withEmpty */ );
750  }
751 
753 
755 
758  template <class TIterator>
759  std::string join( TIterator begin, TIterator end, const C_Str & sep_r = " " )
760  {
761  std::string res;
762  for ( TIterator iter = begin; iter != end; ++ iter )
763  {
764  if ( iter != begin )
765  res += sep_r;
766  res += asString(*iter);
767  }
768  return res;
769  }
770 
772  template <class TContainer>
773  std::string join( const TContainer & cont_r, const C_Str & sep_r = " " )
774  { return join( cont_r.begin(), cont_r.end(), sep_r ); }
775 
780  template <class TIterator>
781  std::string joinEscaped( TIterator begin, TIterator end, const char sep_r = ' ' )
782  {
783  std::vector<char> buf;
784  for ( TIterator iter = begin; iter != end; ++ iter )
785  {
786  if ( iter != begin )
787  buf.push_back( sep_r );
788 
789  if ( iter->empty() )
790  {
791  // empty string goes ""
792  buf.push_back( '"' );
793  buf.push_back( '"' );
794  }
795  else
796  {
797  std::string toadd( asString(*iter) );
798  for_( ch, toadd.begin(), toadd.end() )
799  {
800  switch ( *ch )
801  {
802  case '"':
803  case '\'':
804  case '\\':
805  buf.push_back( '\\' );
806  buf.push_back( *ch );
807  break;
808  default:
809  if ( *ch == sep_r )
810  buf.push_back( '\\' );
811  buf.push_back( *ch );
812  }
813  }
814  }
815  }
816  return std::string( buf.begin(), buf.end() );
817  }
819 
820 
822 
828  inline std::ostream & printIndented( std::ostream & str, const std::string & text_r, const std::string & indent_r = " ", unsigned maxWitdh_r = 0 )
829  {
830  if ( maxWitdh_r )
831  {
832  if ( indent_r.size() >= maxWitdh_r )
833  maxWitdh_r = 0; // nonsense: indent larger than line witdh
834  else
835  maxWitdh_r -= indent_r.size();
836  }
837  unsigned width = 0;
838  for ( const char * e = text_r.c_str(), * s = e; *e; s = ++e )
839  {
840  for ( ; *e && *e != '\n'; ++e ) ;/*searching*/
841  width = e-s;
842  if ( maxWitdh_r && width > maxWitdh_r )
843  {
844  // must break line
845  width = maxWitdh_r;
846  for ( e = s+width; e > s && *e != ' '; --e ) ;/*searching*/
847  if ( e > s )
848  width = e-s; // on a ' ', replaced by '\n'
849  else
850  e = s+width-1; // cut line;
851  }
852  str << indent_r;
853  str.write( s, width );
854  str << "\n";
855  if ( !*e ) // on '\0'
856  break;
857  }
858  return str;
859  }
861  inline std::ostream & printIndented( std::ostream & str, const std::string & text_r, unsigned indent_r, char indentch_r = ' ', unsigned maxWitdh_r = 0 )
862  { return printIndented( str, text_r, std::string( indent_r, indentch_r ), maxWitdh_r ); }
864  inline std::ostream & printIndented( std::ostream & str, const std::string & text_r, unsigned indent_r, unsigned maxWitdh_r, char indentch_r = ' ' )
865  { return printIndented( str, text_r, std::string( indent_r, indentch_r ), maxWitdh_r ); }
866 
870  inline std::ostream & autoPrefix( std::ostream & str, const std::string & text_r, function<std::string(const char*, const char*)> fnc_r )
871  {
872  for ( const char * e = text_r.c_str(); *e; ++e )
873  {
874  const char * s = e;
875  for ( ; *e && *e != '\n'; ++e ) /*searching*/;
876  str << fnc_r( s, e );
877  str.write( s, e-s );
878  str << "\n";
879  if ( !*e ) // on '\0'
880  break;
881  }
882  return str;
883  }
885  inline std::ostream & autoPrefix0( std::ostream & str, const std::string & text_r, function<std::string()> fnc_r )
886  {
887  auto wrap = [&fnc_r]( const char*, const char* )-> std::string {
888  return fnc_r();
889  };
890  return autoPrefix( str, text_r, wrap );
891  }
893 
902  std::string escape( const C_Str & str_r, const char c = ' ' );
903 
905  inline void appendEscaped( std::string & str_r, const C_Str & next_r, const char sep_r = ' ' )
906  {
907  if ( ! str_r.empty() )
908  str_r += sep_r;
909  if ( next_r.empty() )
910  str_r += "\"\"";
911  else
912  str_r += escape( next_r, sep_r );
913  }
914 
916 
918 
928  std::string hexencode( const C_Str & str_r );
930  std::string hexdecode( const C_Str & str_r );
932 
939  std::string toLower( const std::string & s );
940  std::string toLower( std::string && s );
942  inline std::string toLower( const char * s )
943  { return( s ? toLower( std::string(s) ) : std::string() ); }
944 
948  std::string toUpper( const std::string & s );
949  std::string toUpper( std::string && s );
951  inline std::string toUpper( const char * s )
952  { return( s ? toUpper( std::string(s) ) : std::string() ); }
954 
955 
958  inline int compareCI( const C_Str & lhs, const C_Str & rhs )
959  { return ::strcasecmp( lhs, rhs ); }
961 
965  inline bool contains( const C_Str & str_r, const C_Str & val_r )
966  { return ::strstr( str_r, val_r ); }
968  inline bool containsCI( const C_Str & str_r, const C_Str & val_r )
969  { return ::strcasestr( str_r, val_r ); }
971 
973 
978  enum Trim {
979  NO_TRIM = 0x00,
980  L_TRIM = 0x01,
981  R_TRIM = 0x02,
983  };
984 
985  std::string trim( const std::string & s, const Trim trim_r = TRIM );
986  std::string trim( std::string && s, const Trim trim_r = TRIM );
987 
988  inline std::string ltrim( const std::string & s )
989  { return trim( s, L_TRIM ); }
990  inline std::string ltrim( std::string && s )
991  { return trim( std::move(s), L_TRIM ); }
992 
993  inline std::string rtrim( const std::string & s )
994  { return trim( s, R_TRIM ); }
995  inline std::string rtrim( std::string && s )
996  { return trim( std::move(s), R_TRIM ); }
998 
999  std::string stripFirstWord( std::string & line, const bool ltrim_first = true );
1000 
1001  std::string stripLastWord( std::string & line, const bool rtrim_first = true );
1002 
1006  std::string getline( std::istream & str, bool trim = false );
1007 
1011  std::string getline( std::istream & str, const Trim trim_r );
1012 
1020  std::string receiveUpTo( std::istream & str, const char delim_r, bool returnDelim_r = false );
1021 
1023 
1028  inline bool hasPrefix( const C_Str & str_r, const C_Str & prefix_r )
1029  { return( ::strncmp( str_r, prefix_r, prefix_r.size() ) == 0 ); }
1031  inline bool hasPrefixCI( const C_Str & str_r, const C_Str & prefix_r )
1032  { return( ::strncasecmp( str_r, prefix_r, prefix_r.size() ) == 0 ); }
1033 
1035  inline std::string stripPrefix( const C_Str & str_r, const C_Str & prefix_r )
1036  { return( hasPrefix( str_r, prefix_r ) ? str_r + prefix_r.size() : str_r.c_str() ); }
1038  inline std::string stripPrefixCI( const C_Str & str_r, const C_Str & prefix_r )
1039  { return( hasPrefixCI( str_r, prefix_r ) ? str_r + prefix_r.size() : str_r.c_str() ); }
1040 
1042  inline bool hasSuffix( const C_Str & str_r, const C_Str & suffix_r )
1043  { return( str_r.size() >= suffix_r.size() && ::strncmp( str_r + str_r.size() - suffix_r.size() , suffix_r, suffix_r.size() ) == 0 ); }
1045  inline bool hasSuffixCI( const C_Str & str_r, const C_Str & suffix_r )
1046  { return( str_r.size() >= suffix_r.size() && ::strncasecmp( str_r + str_r.size() - suffix_r.size() , suffix_r, suffix_r.size() ) == 0 ); }
1047 
1049  inline std::string stripSuffix( const C_Str & str_r, const C_Str & suffix_r )
1050  {
1051  if ( hasSuffix( str_r, suffix_r ) )
1052  return std::string( str_r, str_r.size() - suffix_r.size() );
1053  return str_r.c_str();
1054  }
1056  inline std::string stripSuffixCI( const C_Str & str_r, const C_Str & suffix_r )
1057  {
1058  if ( hasSuffixCI( str_r, suffix_r ) )
1059  return std::string( str_r, str_r.size() - suffix_r.size() );
1060  return str_r.c_str();
1061  }
1062 
1064  inline std::string::size_type commonPrefix( const C_Str & lhs, const C_Str & rhs )
1065  {
1066  const char * lp = lhs.c_str();
1067  const char * rp = rhs.c_str();
1068  std::string::size_type ret = 0;
1069  while ( *lp == *rp && *lp != '\0' )
1070  { ++lp, ++rp, ++ret; }
1071  return ret;
1072  }
1074  inline std::string::size_type commonPrefixCI( const C_Str & lhs, const C_Str & rhs )
1075  {
1076  const char * lp = lhs.c_str();
1077  const char * rp = rhs.c_str();
1078  std::string::size_type ret = 0;
1079  while ( tolower(*lp) == tolower(*rp) && *lp != '\0' )
1080  { ++lp, ++rp, ++ret; }
1081  return ret;
1082  }
1083 
1084 
1086  inline bool startsWith( const C_Str & str_r, const C_Str & prefix_r )
1087  { return hasPrefix( str_r, prefix_r ); }
1089  inline bool startsWithCI( const C_Str & str_r, const C_Str & prefix_r )
1090  { return hasPrefixCI( str_r, prefix_r ); }
1091 
1093  inline bool endsWith( const C_Str & str_r, const C_Str & prefix_r )
1094  { return hasSuffix( str_r, prefix_r ); }
1096  inline bool endsWithCI( const C_Str & str_r, const C_Str & prefix_r )
1097  { return hasSuffixCI( str_r, prefix_r ); }
1099  } // namespace str
1101 
1102  // drag into zypp:: namespace
1103  using str::asString;
1104 
1105 } // namespace zypp
1107 #endif // ZYPP_BASE_STRING_H
TriBool strToTriBool(const C_Str &str)
Parse str into a bool if it&#39;s a legal true or false string; else indterminate.
Definition: String.cc:91
bool contains(const C_Str &str_r, const C_Str &val_r)
Locate substring case sensitive.
Definition: String.h:965
std::string str() const
Definition: String.h:221
std::string asString() const
Definition: String.h:220
unsigned splitEscaped(const C_Str &line_r, TOutputIterator result_r, const C_Str &sepchars_r=" \, bool withEmpty=false)
Split line_r into words with respect to escape delimeters.
Definition: String.h:578
C_Str(const boost::string_ref &str_r)
Definition: String.h:100
Boost libraries.
bool strToBoolNodefault(const C_Str &str, bool &return_r)
Parse str into a bool if it&#39;s a legal true or false string.
Definition: String.h:452
std::string stripPrefix(const C_Str &str_r, const C_Str &prefix_r)
Strip a prefix_r from str_r and return the resulting string.
Definition: String.h:1035
bool hasPrefixCI(const C_Str &str_r, const C_Str &prefix_r)
Definition: String.h:1031
std::string::size_type size_type
Definition: String.h:93
boost::format _fmter
Definition: String.h:265
bool hasSuffixCI(const C_Str &str_r, const C_Str &suffix_r)
Definition: String.h:1045
bool startsWithCI(const C_Str &str_r, const C_Str &prefix_r)
Definition: String.h:1089
std::string stripSuffixCI(const C_Str &str_r, const C_Str &suffix_r)
Definition: String.h:1056
std::string ltrim(std::string &&s)
Definition: String.h:990
std::string::size_type commonPrefix(const C_Str &lhs, const C_Str &rhs)
Return size of the common prefix of lhs and rhs.
Definition: String.h:1064
std::string stripSuffix(const C_Str &str_r, const C_Str &suffix_r)
Strip a suffix_r from str_r and return the resulting string.
Definition: String.h:1049
std::ostream & autoPrefix0(std::ostream &str, const std::string &text_r, function< std::string()> fnc_r)
Definition: String.h:885
String related utilities and Regular expression matching.
std::string rtrim(std::string &&s)
Definition: String.h:995
C_Str(const std::string &str_r)
Definition: String.h:99
Definition: Arch.h:344
unsigned split(const C_Str &line_r, TOutputIterator result_r, const C_Str &sepchars_r=" \)
Split line_r into words.
Definition: String.h:519
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
Definition: Easy.h:27
FormatNAC(const std::string &format_r)
Definition: String.h:282
Convenient building of std::string with boost::format.
Definition: String.h:248
Format & operator%(Tp &&arg)
Definition: String.h:254
const char * c_str() const
Definition: String.h:113
std::string form(const char *format,...) __attribute__((format(printf
Printf style construction of std::string.
Definition: String.cc:36
Trim
To define how to trim.
Definition: String.h:978
const boost::format & fmter() const
Definition: String.h:261
std::string asString() const
Definition: String.h:258
const std::ostream & stream() const
Definition: String.h:223
std::string joinEscaped(TIterator begin, TIterator end, const char sep_r=' ')
Join strings using separator sep_r, quoting or escaping the values.
Definition: String.h:781
bool endsWithCI(const C_Str &str_r, const C_Str &prefix_r)
Definition: String.h:1096
boost::logic::tribool TriBool
3-state boolean logic (true, false and indeterminate).
Definition: String.h:30
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:328
size_type size() const
Definition: String.h:105
std::string asString() const
Definition: String.h:194
std::string getline(std::istream &str)
Read one line from stream.
Definition: IOStream.cc:33
std::string stripFirstWord(std::string &line, const bool ltrim_first)
Definition: String.cc:261
std::string escape(const C_Str &str_r, const char sep_r)
Escape desired character c using a backslash.
Definition: String.cc:369
std::string asString(const unsigned long long &t)
Definition: String.h:325
Convenient building of std::string via std::ostringstream Basically a std::ostringstream autoconverti...
Definition: String.h:210
std::string trim(const std::string &s, const Trim trim_r)
Definition: String.cc:221
boost::format & fmter()
Definition: String.h:262
Convenience char* constructible from std::string and char*, it maps (char*)0 to an empty string...
Definition: String.h:90
std::ostream & operator<<(std::ostream &str, const Format &obj)
Definition: String.h:269
bool startsWith(const C_Str &str_r, const C_Str &prefix_r)
alias for hasPrefix
Definition: String.h:1086
const char *const _val
Definition: String.h:116
std::string stripLastWord(std::string &line, const bool rtrim_first)
Definition: String.cc:294
bool strToFalse(const C_Str &str)
Return false if str is 0, false, no, off.
Definition: String.cc:80
bool containsCI(const C_Str &str_r, const C_Str &val_r)
Locate substring case insensitive.
Definition: String.h:968
std::string gsubFun(const std::string &str_r, const std::string &from_r, function< std::string()> to_r)
Definition: String.cc:345
bool endsWith(const C_Str &str_r, const C_Str &prefix_r)
alias for hasSuffix
Definition: String.h:1093
size_type _sze
Definition: String.h:117
std::ostream & printIndented(std::ostream &str, const std::string &text_r, unsigned indent_r, unsigned maxWitdh_r, char indentch_r=' ')
Definition: String.h:864
int compareCI(const C_Str &lhs, const C_Str &rhs)
Definition: String.h:958
SolvableIdType size_type
Definition: PoolMember.h:126
Str & operator<<(Tp &&val)
Definition: String.h:213
std::ostream & operator<<(std::ostream &str, const Str &obj)
Definition: String.h:233
bool strToTrue(const C_Str &str)
Parsing boolean from string.
Definition: String.cc:63
unsigned splitFields(const C_Str &line_r, TOutputIterator result_r, const C_Str &sepchars_r=":")
Split line_r into fields.
Definition: String.h:708
std::string & replaceAllFun(std::string &str_r, const std::string &from_r, function< std::string()> to_r)
Definition: String.cc:351
bool hasSuffix(const C_Str &str_r, const C_Str &suffix_r)
Return whether str_r has suffix suffix_r.
Definition: String.h:1042
std::string hexstring(unsigned long long n, int w=0)
Definition: String.h:349
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:322
std::string str() const
Definition: String.h:259
C_Str(const char *c_str_r)
Definition: String.h:98
TInt strtonum(const C_Str &str, TInt &i)
String to integer type detemined 2nd function arg i.
Definition: String.h:427
bool isNull() const
Definition: String.h:103
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:401
bool strToBool(const C_Str &str, bool default_r)
Parse str into a bool depending on the default value.
Definition: String.h:445
std::string hexencode(const C_Str &str_r)
Encode all characters other than [a-zA-Z0-9] as XX.
Definition: String.cc:122
Str & operator<<(std::ostream &(*iomanip)(std::ostream &))
Definition: String.h:216
std::string binstring(TInt val_r)
String representation of number as bit-string with leading &#39;0&#39;s.
Definition: String.h:380
bool empty() const
Definition: String.h:104
std::string octstring(unsigned long long n, int w=0)
Definition: String.h:373
std::ostream & operator<<(std::ostream &str, const C_Str &obj)
Definition: String.h:121
std::string stripPrefixCI(const C_Str &str_r, const C_Str &prefix_r)
Definition: String.h:1038
std::ostream & autoPrefix(std::ostream &str, const std::string &text_r, function< std::string(const char *, const char *)> fnc_r)
Prefix lines by string computed by function taking line begin/end [std::string(const char*...
Definition: String.h:870
std::string strerror(int errno_r)
Return string describing the error_r code.
Definition: String.cc:53
C_Str(char *c_str_r)
Definition: String.h:97
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:1
std::string asUserString(const Tp &val_r)
Request a human readable (translated) string representation of Tp [Tp.asUserString()] Classes may imp...
Definition: String.h:40
std::ostream & stream()
Definition: String.h:224
std::string join(const TContainer &cont_r, const C_Str &sep_r=" ")
Join strings using separator sep_r (defaults to BLANK).
Definition: String.h:773
std::string toUpper(const char *s)
Definition: String.h:951
Assert free called for allocated char *.
Definition: String.h:189
bool hasPrefix(const C_Str &str_r, const C_Str &prefix_r)
Return whether str_r has prefix prefix_r.
Definition: String.h:1028
std::string toLower(const char *s)
Definition: String.h:942
void clear()
Definition: String.h:226
Format with (N)o (A)rgument (C)heck.
Definition: String.h:279
void appendEscaped(std::string &str_r, const C_Str &next_r, const char sep_r=' ')
Escape next_r and append it to str_r using separator sep_r.
Definition: String.h:905
std::ostringstream _str
Definition: String.h:229
std::string hexdecode(const C_Str &str_r)
Decode hexencoded XX sequences.
Definition: String.cc:143
std::string numstring(unsigned long long n, int w=0)
Definition: String.h:314
std::string::size_type commonPrefixCI(const C_Str &lhs, const C_Str &rhs)
Definition: String.h:1074
unsigned splitFieldsEscaped(const C_Str &line_r, TOutputIterator result_r, const C_Str &sepchars_r=":")
Split line_r into fields handling also escaped separators.
Definition: String.h:747
std::string gapify(std::string inp_r, std::string::size_type gap_r=1, char gapchar=' ')
Enhance readability: insert gaps at regular distance.
Definition: String.h:495
Format(const std::string &format_r)
Definition: String.h:251