libzypp  17.28.4
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-core/base/Easy.h>
25 #include <zypp-core/base/PtrTypes.h>
26 #include <zypp-core/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 #ifdef __cpp_lib_string_view
102  C_Str( const std::string_view & str_r ) : _val( str_r.data() ), _sze( str_r.size() ) {}
103 #endif
104 
105  public:
106  bool isNull() const { return !_val; }
107  bool empty() const { return !(_val && *_val); }
108  size_type size() const
109  {
110  if ( _sze == std::string::npos )
111  { _sze = _val ? ::strlen( _val ) : 0; }
112  return _sze;
113  };
114 
115  operator const char *() const { return c_str(); }
116  const char * c_str() const { return _val ? _val : ""; }
117 
118  private:
119  const char *const _val;
120  mutable size_type _sze;
121  };
122 
124  inline std::ostream & operator<<( std::ostream & str, const C_Str & obj )
125  { return str << obj.c_str(); }
126 
128 
132  namespace str
133  {
134 
136 
139  inline const std::string & asString( const std::string & t )
140  { return t; }
141 
142  inline std::string && asString( std::string && t )
143  { return std::move(t); }
144 
145  inline std::string asString( const char * t )
146  { return t == nullptr ? std::string() : t; }
147 
148  inline std::string asString( char * t )
149  { return t == nullptr ? std::string() : t; }
150 
151  template<class Tp>
152  inline std::string asString( const Tp &t )
153  { return t.asString(); }
154 
155  template<class Tp>
156  inline std::string asString( const intrusive_ptr<Tp> &p )
157  { return p->asString(); }
158 
159  template<class Tp>
160  inline std::string asString( const weak_ptr<Tp> &p )
161  { return p->asString(); }
162 
163  template<>
164  inline std::string asString( const bool &t )
165  { return t ? "true" : "false"; }
166 
168 
169  std::string form( const char * format, ... )
170  __attribute__ ((format (printf, 1, 2)));
171 
173 
177  std::string strerror( int errno_r );
178 
180 
190  struct SafeBuf
191  {
192  char * _buf;
193  SafeBuf() : _buf( 0 ) {}
194  ~SafeBuf() { if ( _buf ) free( _buf ); }
195  std::string asString() const
196  { return _buf ? std::string(_buf) : std::string(); }
197  };
198 
211  struct Str
212  {
213  template<class Tp>
214  Str & operator<<( Tp && val )
215  { _str << std::forward<Tp>(val); return *this; }
216 
217  Str & operator<<( std::ostream& (*iomanip)( std::ostream& ) )
218  { _str << iomanip; return *this; }
219 
220  operator std::string() const { return _str.str(); }
221  std::string asString() const { return _str.str(); }
222  std::string str() const { return _str.str(); }
223 
224  const std::ostream & stream() const { return _str; }
225  std::ostream & stream() { return _str; }
226 
227  void clear() { _str.str( std::string() ); }
228 
229  private:
230  std::ostringstream _str;
231  };
232 
234  inline std::ostream & operator<<( std::ostream & str, const Str & obj )
235  { return str << obj.str(); }
236 
252  struct Format
253  {
254  Format() { _fmter.exceptions( boost::io::no_error_bits ); }
255  Format( const std::string & format_r ) : Format() { _fmter.parse( format_r ); }
256 
257  template<class Tp>
258  Format & operator%( Tp && arg )
259  { _fmter % std::forward<Tp>(arg); return *this; }
260 
261  operator std::string() const { return _fmter.str(); }
262  std::string asString() const { return _fmter.str(); }
263  std::string str() const { return _fmter.str(); }
264 
265  const boost::format & fmter() const { return _fmter; }
266  boost::format & fmter() { return _fmter; }
267 
268  protected:
269  boost::format _fmter;
270  };
271 
273  inline std::ostream & operator<<( std::ostream & str, const Format & obj )
274  { return str << obj.fmter(); }
275 
289  inline std::string numstring( char n, int w = 0 ) { return form( "%*hhd", w, n ); }
290  inline std::string numstring( unsigned char n, int w = 0 ) { return form( "%*hhu", w, n ); }
291  inline std::string numstring( short n, int w = 0 ) { return form( "%*hd", w, n ); }
292  inline std::string numstring( unsigned short n, int w = 0 ) { return form( "%*hu", w, n ); }
293  inline std::string numstring( int n, int w = 0 ) { return form( "%*d", w, n ); }
294  inline std::string numstring( unsigned n, int w = 0 ) { return form( "%*u", w, n ); }
295  inline std::string numstring( long n, int w = 0 ) { return form( "%*ld", w, n ); }
296  inline std::string numstring( unsigned long n, int w = 0 ) { return form( "%*lu", w, n ); }
297  inline std::string numstring( long long n, int w = 0 ) { return form( "%*lld", w, n ); }
298  inline std::string numstring( unsigned long long n, int w = 0 ) { return form( "%*llu", w, n ); }
299 
300  template<> inline std::string asString( const char & t ) { return numstring( t ); }
301  template<> inline std::string asString( const unsigned char & t ) { return numstring( t ); }
302  template<> inline std::string asString( const short & t ) { return numstring( t ); }
303  template<> inline std::string asString( const unsigned short & t ) { return numstring( t ); }
304  template<> inline std::string asString( const int & t ) { return numstring( t ); }
305  template<> inline std::string asString( const unsigned & t ) { return numstring( t ); }
306  template<> inline std::string asString( const long & t ) { return numstring( t ); }
307  template<> inline std::string asString( const unsigned long & t ) { return numstring( t ); }
308  template<> inline std::string asString( const long long & t ) { return numstring( t ); }
309  template<> inline std::string asString( const unsigned long long & t ) { return numstring( t ); }
311 
313 
324  inline std::string hexstring( char n, int w = 4 ) { return form( "%#0*hhx", w, n ); }
325  inline std::string hexstring( unsigned char n, int w = 4 ) { return form( "%#0*hhx", w, n ); }
326  inline std::string hexstring( short n, int w = 10 ){ return form( "%#0*hx", w, n ); }
327  inline std::string hexstring( unsigned short n, int w = 10 ){ return form( "%#0*hx", w, n ); }
328  inline std::string hexstring( int n, int w = 10 ){ return form( "%#0*x", w, n ); }
329  inline std::string hexstring( unsigned n, int w = 10 ){ return form( "%#0*x", w, n ); }
330  inline std::string hexstring( long n, int w = 10 ){ return form( "%#0*lx", w, n ); }
331  inline std::string hexstring( unsigned long n, int w = 10 ){ return form( "%#0*lx", w, n ); }
332  inline std::string hexstring( long long n, int w = 0 ) { return form( "%#0*llx", w, n ); }
333  inline std::string hexstring( unsigned long long n, int w = 0 ) { return form( "%#0*llx", w, n ); }
335 
337 
348  inline std::string octstring( char n, int w = 4 ) { return form( "%#0*hho", w, n ); }
349  inline std::string octstring( unsigned char n, int w = 4 ) { return form( "%#0*hho", w, n ); }
350  inline std::string octstring( short n, int w = 5 ) { return form( "%#0*ho", w, n ); }
351  inline std::string octstring( unsigned short n, int w = 5 ) { return form( "%#0*ho", w, n ); }
352  inline std::string octstring( int n, int w = 5 ) { return form( "%#0*o", w, n ); }
353  inline std::string octstring( unsigned n, int w = 5 ) { return form( "%#0*o", w, n ); }
354  inline std::string octstring( long n, int w = 5 ) { return form( "%#0*lo", w, n ); }
355  inline std::string octstring( unsigned long n, int w = 5 ) { return form( "%#0*lo", w, n ); }
356  inline std::string octstring( long long n, int w = 0 ) { return form( "%#0*llo", w, n ); }
357  inline std::string octstring( unsigned long long n, int w = 0 ) { return form( "%#0*llo", w, n ); }
359 
360 
362 
363  template <typename TInt>
364  std::string binstring( TInt val_r )
365  {
366  constexpr unsigned bits = sizeof(TInt)*8;
367  std::string ret( bits, ' ' );
368  TInt bit = 1;
369  for ( unsigned pos = bits; pos > 0; )
370  { --pos; ret[pos] = ((val_r & bit)?'1':'0'); bit = bit<<1; }
371  return ret;
372  }
373 
375 
384  template<typename TInt>
385  TInt strtonum( const C_Str & str );
386 
387  template<>
388  inline short strtonum( const C_Str & str ) { return ::strtol ( str, NULL, 0 ); }
389  template<>
390  inline int strtonum( const C_Str & str ) { return ::strtol ( str, NULL, 0 ); }
391  template<>
392  inline long strtonum( const C_Str & str ) { return ::strtol ( str, NULL, 0 ); }
393  template<>
394  inline long long strtonum( const C_Str & str ) { return ::strtoll ( str, NULL, 0 ); }
395 
396  template<>
397  inline unsigned short strtonum( const C_Str & str ) { return ::strtoul ( str, NULL, 0 ); }
398  template<>
399  inline unsigned strtonum( const C_Str & str ) { return ::strtoul ( str, NULL, 0 ); }
400  template<>
401  inline unsigned long strtonum( const C_Str & str ) { return ::strtoul ( str, NULL, 0 ); }
402  template<>
403  inline unsigned long long strtonum( const C_Str & str ) { return ::strtoull( str, NULL, 0 ); }
404 
410  template<typename TInt>
411  inline TInt strtonum( const C_Str & str, TInt & i )
412  { return i = strtonum<TInt>( str ); }
414 
416 
420  bool strToTrue( const C_Str & str );
421 
423  bool strToFalse( const C_Str & str );
424 
429  inline bool strToBool( const C_Str & str, bool default_r )
430  { return( default_r ? strToFalse( str ) : strToTrue( str ) ); }
431 
436  inline bool strToBoolNodefault( const C_Str & str, bool & return_r )
437  {
438  if ( strToTrue( str ) ) return (return_r = true);
439  if ( !strToFalse( str ) ) return (return_r = false);
440  return return_r;
441  }
442 
444  TriBool strToTriBool( const C_Str & str );
445 
447 
451  std::string gsub( const std::string & str_r, const std::string & from_r, const std::string & to_r );
452 
455  std::string gsubFun( const std::string & str_r, const std::string & from_r, function<std::string()> to_r );
456 
461  std::string & replaceAll( std::string & str_r, const std::string & from_r, const std::string & to_r );
462 
465  std::string & replaceAllFun( std::string & str_r, const std::string & from_r, function<std::string()> to_r );
466 
479  inline std::string gapify( std::string inp_r, std::string::size_type gap_r = 1, char gapchar = ' ' )
480  {
481  if ( gap_r && inp_r.size() > gap_r )
482  {
483  inp_r.reserve( inp_r.size() + (inp_r.size()-1)/gap_r );
484  for ( std::string::size_type pos = gap_r; pos < inp_r.size(); pos += gap_r+1 )
485  inp_r.insert( pos, 1, gapchar );
486  }
487  return inp_r;
488  }
489 
491 
496  enum Trim {
497  NO_TRIM = 0x00,
498  L_TRIM = 0x01,
499  R_TRIM = 0x02,
500  TRIM = (L_TRIM|R_TRIM)
501  };
502 
503  std::string trim( const std::string & s, const Trim trim_r = TRIM );
504  std::string trim( std::string && s, const Trim trim_r = TRIM );
505 
506  inline std::string ltrim( const std::string & s )
507  { return trim( s, L_TRIM ); }
508  inline std::string ltrim( std::string && s )
509  { return trim( std::move(s), L_TRIM ); }
510 
511  inline std::string rtrim( const std::string & s )
512  { return trim( s, R_TRIM ); }
513  inline std::string rtrim( std::string && s )
514  { return trim( std::move(s), R_TRIM ); }
516 
517 
519 
530  template<class TOutputIterator>
531  unsigned split( const C_Str & line_r, TOutputIterator result_r, const C_Str & sepchars_r = " \t", const Trim trim_r = NO_TRIM )
532  {
533  const char * beg = line_r;
534  const char * cur = beg;
535  // skip leading sepchars
536  while ( *cur && ::strchr( sepchars_r, *cur ) )
537  ++cur;
538  unsigned ret = 0;
539  for ( beg = cur; *beg; beg = cur, ++result_r, ++ret )
540  {
541  // skip non sepchars
542  while( *cur && !::strchr( sepchars_r, *cur ) )
543  ++cur;
544  // build string
545  *result_r = trim( std::string( beg, cur-beg ), trim_r );
546  // skip sepchars
547  while ( *cur && ::strchr( sepchars_r, *cur ) )
548  ++cur;
549  }
550  return ret;
551  }
552 
553  template<class TOutputIterator>
554  unsigned split( const C_Str & line_r, TOutputIterator result_r, const Trim trim_r )
555  { return split( line_r, result_r, " \t", trim_r ); }
556 
557 
594  template<class TOutputIterator>
595  unsigned splitEscaped( const C_Str & line_r, TOutputIterator result_r, const C_Str & sepchars_r = " \t", bool withEmpty = false)
596  {
597  const char * beg = line_r;
598  const char * cur = beg;
599  unsigned ret = 0;
600 
601  // skip leading sepchars
602  while ( *cur && ::strchr( sepchars_r, *cur ) )
603  {
604  ++cur;
605  if (withEmpty)
606  {
607  *result_r = "";
608  ++ret;
609  }
610  }
611 
612  // there were only sepchars in the string
613  if (!*cur && withEmpty)
614  {
615  *result_r = "";
616  return ++ret;
617  }
618 
619  // after the leading sepchars
620  enum class Quote { None, Slash, Single, Double, DoubleSlash };
621  std::vector<char> buf;
622  Quote quoting = Quote::None;
623  for ( beg = cur; *beg; beg = cur, ++result_r, ++ret )
624  {
625  // read next value until unquoted sepchar
626  buf.clear();
627  quoting = Quote::None;
628  do {
629  switch ( quoting )
630  {
631  case Quote::None:
632  switch ( *cur )
633  {
634  case '\\': quoting = Quote::Slash; break;
635  case '\'': quoting = Quote::Single; break;
636  case '"': quoting = Quote::Double; break;
637  default: buf.push_back( *cur ); break;
638  }
639  break;
640 
641  case Quote::Slash:
642  buf.push_back( *cur );
643  quoting = Quote::None;
644  break;
645 
646  case Quote::Single:
647  switch ( *cur )
648  {
649  case '\'': quoting = Quote::None; break;
650  default: buf.push_back( *cur ); break;
651  }
652  break;
653 
654  case Quote::Double:
655  switch ( *cur )
656  {
657  case '\"': quoting = Quote::None; break;
658  case '\\': quoting = Quote::DoubleSlash; break;
659  default: buf.push_back( *cur ); break;
660  }
661  break;
662 
663  case Quote::DoubleSlash:
664  switch ( *cur )
665  {
666  case '\"': /*fallthrough*/
667  case '\\': buf.push_back( *cur ); break;
668  default:
669  buf.push_back( '\\' );
670  buf.push_back( *cur );
671  break;
672  }
673  quoting = Quote::Double;
674  break;
675  }
676  ++cur;
677  } while ( *cur && ( quoting != Quote::None || !::strchr( sepchars_r, *cur ) ) );
678  *result_r = std::string( buf.begin(), buf.end() );
679 
680 
681  // skip sepchars
682  if ( *cur && ::strchr( sepchars_r, *cur ) )
683  ++cur;
684  while ( *cur && ::strchr( sepchars_r, *cur ) )
685  {
686  ++cur;
687  if (withEmpty)
688  {
689  *result_r = "";
690  ++ret;
691  }
692  }
693  // the last was a separator => one more field
694  if ( !*cur && withEmpty && ::strchr( sepchars_r, *(cur-1) ) )
695  {
696  *result_r = "";
697  ++ret;
698  }
699  }
700  return ret;
701  }
702 
724  template<class TOutputIterator>
725  unsigned splitFields( const C_Str & line_r, TOutputIterator result_r, const C_Str & sepchars_r = ":" )
726  {
727  const char * beg = line_r;
728  const char * cur = beg;
729  unsigned ret = 0;
730  for ( beg = cur; *beg; beg = cur, ++result_r )
731  {
732  // skip non sepchars
733  while( *cur && !::strchr( sepchars_r, *cur ) )
734  {
735  if ( *cur == '\\' && *(cur+1) )
736  ++cur;
737  ++cur;
738  }
739  // build string
740  *result_r = std::string( beg, cur-beg );
741  ++ret;
742  // skip sepchar
743  if ( *cur )
744  {
745  ++cur;
746  if ( ! *cur ) // ending with sepchar
747  {
748  *result_r = std::string(); // add final empty field
749  ++ret;
750  break;
751  }
752  }
753  }
754  return ret;
755  }
756 
763  template<class TOutputIterator>
764  unsigned splitFieldsEscaped( const C_Str & line_r, TOutputIterator result_r, const C_Str & sepchars_r = ":" )
765  {
766  return splitEscaped( line_r, result_r, sepchars_r, true /* withEmpty */ );
767  }
768 
770 
772 
775  template <class TIterator>
776  std::string join( TIterator begin, TIterator end, const C_Str & sep_r = " " )
777  {
778  std::string res;
779  for ( TIterator iter = begin; iter != end; ++ iter )
780  {
781  if ( iter != begin )
782  res += sep_r;
783  res += asString(*iter);
784  }
785  return res;
786  }
787 
789  template <class TContainer>
790  std::string join( const TContainer & cont_r, const C_Str & sep_r = " " )
791  { return join( cont_r.begin(), cont_r.end(), sep_r ); }
792 
797  template <class TIterator>
798  std::string joinEscaped( TIterator begin, TIterator end, const char sep_r = ' ' )
799  {
800  std::vector<char> buf;
801  for ( TIterator iter = begin; iter != end; ++ iter )
802  {
803  if ( iter != begin )
804  buf.push_back( sep_r );
805 
806  if ( iter->empty() )
807  {
808  // empty string goes ""
809  buf.push_back( '"' );
810  buf.push_back( '"' );
811  }
812  else
813  {
814  std::string toadd( asString(*iter) );
815  for_( ch, toadd.begin(), toadd.end() )
816  {
817  switch ( *ch )
818  {
819  case '"':
820  case '\'':
821  case '\\':
822  buf.push_back( '\\' );
823  buf.push_back( *ch );
824  break;
825  default:
826  if ( *ch == sep_r )
827  buf.push_back( '\\' );
828  buf.push_back( *ch );
829  }
830  }
831  }
832  }
833  return std::string( buf.begin(), buf.end() );
834  }
836 
837 
839 
845  inline std::ostream & printIndented( std::ostream & str, const std::string & text_r, const std::string & indent_r = " ", unsigned maxWitdh_r = 0 )
846  {
847  if ( maxWitdh_r )
848  {
849  if ( indent_r.size() >= maxWitdh_r )
850  maxWitdh_r = 0; // nonsense: indent larger than line witdh
851  else
852  maxWitdh_r -= indent_r.size();
853  }
854  unsigned width = 0;
855  for ( const char * e = text_r.c_str(), * s = e; *e; s = ++e )
856  {
857  for ( ; *e && *e != '\n'; ++e ) ;/*searching*/
858  width = e-s;
859  if ( maxWitdh_r && width > maxWitdh_r )
860  {
861  // must break line
862  width = maxWitdh_r;
863  for ( e = s+width; e > s && *e != ' '; --e ) ;/*searching*/
864  if ( e > s )
865  width = e-s; // on a ' ', replaced by '\n'
866  else
867  e = s+width-1; // cut line;
868  }
869  str << indent_r;
870  str.write( s, width );
871  str << "\n";
872  if ( !*e ) // on '\0'
873  break;
874  }
875  return str;
876  }
878  inline std::ostream & printIndented( std::ostream & str, const std::string & text_r, unsigned indent_r, char indentch_r = ' ', unsigned maxWitdh_r = 0 )
879  { return printIndented( str, text_r, std::string( indent_r, indentch_r ), maxWitdh_r ); }
881  inline std::ostream & printIndented( std::ostream & str, const std::string & text_r, unsigned indent_r, unsigned maxWitdh_r, char indentch_r = ' ' )
882  { return printIndented( str, text_r, std::string( indent_r, indentch_r ), maxWitdh_r ); }
883 
887  inline std::ostream & autoPrefix( std::ostream & str, const std::string & text_r, function<std::string(const char*, const char*)> fnc_r )
888  {
889  for ( const char * e = text_r.c_str(); *e; ++e )
890  {
891  const char * s = e;
892  for ( ; *e && *e != '\n'; ++e ) /*searching*/;
893  str << fnc_r( s, e );
894  str.write( s, e-s );
895  str << "\n";
896  if ( !*e ) // on '\0'
897  break;
898  }
899  return str;
900  }
902  inline std::ostream & autoPrefix0( std::ostream & str, const std::string & text_r, function<std::string()> fnc_r )
903  {
904  auto wrap = [&fnc_r]( const char*, const char* )-> std::string {
905  return fnc_r();
906  };
907  return autoPrefix( str, text_r, wrap );
908  }
910 
919  std::string escape( const C_Str & str_r, const char c = ' ' );
920 
922  inline void appendEscaped( std::string & str_r, const C_Str & next_r, const char sep_r = ' ' )
923  {
924  if ( ! str_r.empty() )
925  str_r += sep_r;
926  if ( next_r.empty() )
927  str_r += "\"\"";
928  else
929  str_r += escape( next_r, sep_r );
930  }
931 
933  std::string bEscape( std::string str_r, const C_Str & special_r );
934 
936  std::string rxEscapeStr( std::string str_r );
937 
939  std::string rxEscapeGlob( std::string str_r );
940 
942 
944 
954  std::string hexencode( const C_Str & str_r );
956  std::string hexdecode( const C_Str & str_r );
958 
965  std::string toLower( const std::string & s );
966  std::string toLower( std::string && s );
968  inline std::string toLower( const char * s )
969  { return( s ? toLower( std::string(s) ) : std::string() ); }
970 
974  std::string toUpper( const std::string & s );
975  std::string toUpper( std::string && s );
977  inline std::string toUpper( const char * s )
978  { return( s ? toUpper( std::string(s) ) : std::string() ); }
980 
981 
984  inline int compareCI( const C_Str & lhs, const C_Str & rhs )
985  { return ::strcasecmp( lhs, rhs ); }
987 
991  inline bool contains( const C_Str & str_r, const C_Str & val_r )
992  { return ::strstr( str_r, val_r ); }
994  inline bool containsCI( const C_Str & str_r, const C_Str & val_r )
995  { return ::strcasestr( str_r, val_r ); }
997 
998  std::string stripFirstWord( std::string & line, const bool ltrim_first = true );
999 
1000  std::string stripLastWord( std::string & line, const bool rtrim_first = true );
1001 
1005  std::string getline( std::istream & str, bool trim = false );
1006 
1010  std::string getline( std::istream & str, const Trim trim_r );
1011 
1019  std::string receiveUpTo( std::istream & str, const char delim_r, bool returnDelim_r = false );
1020 
1022 
1027  inline bool hasPrefix( const C_Str & str_r, const C_Str & prefix_r )
1028  { return( ::strncmp( str_r, prefix_r, prefix_r.size() ) == 0 ); }
1030  inline bool hasPrefixCI( const C_Str & str_r, const C_Str & prefix_r )
1031  { return( ::strncasecmp( str_r, prefix_r, prefix_r.size() ) == 0 ); }
1032 
1034  inline std::string stripPrefix( const C_Str & str_r, const C_Str & prefix_r )
1035  { return( hasPrefix( str_r, prefix_r ) ? str_r + prefix_r.size() : str_r.c_str() ); }
1037  inline std::string stripPrefixCI( const C_Str & str_r, const C_Str & prefix_r )
1038  { return( hasPrefixCI( str_r, prefix_r ) ? str_r + prefix_r.size() : str_r.c_str() ); }
1039 
1041  inline bool hasSuffix( const C_Str & str_r, const C_Str & suffix_r )
1042  { return( str_r.size() >= suffix_r.size() && ::strncmp( str_r + str_r.size() - suffix_r.size() , suffix_r, suffix_r.size() ) == 0 ); }
1044  inline bool hasSuffixCI( const C_Str & str_r, const C_Str & suffix_r )
1045  { return( str_r.size() >= suffix_r.size() && ::strncasecmp( str_r + str_r.size() - suffix_r.size() , suffix_r, suffix_r.size() ) == 0 ); }
1046 
1048  inline std::string stripSuffix( const C_Str & str_r, const C_Str & suffix_r )
1049  {
1050  if ( hasSuffix( str_r, suffix_r ) )
1051  return std::string( str_r, str_r.size() - suffix_r.size() );
1052  return str_r.c_str();
1053  }
1055  inline std::string stripSuffixCI( const C_Str & str_r, const C_Str & suffix_r )
1056  {
1057  if ( hasSuffixCI( str_r, suffix_r ) )
1058  return std::string( str_r, str_r.size() - suffix_r.size() );
1059  return str_r.c_str();
1060  }
1061 
1063  inline std::string::size_type commonPrefix( const C_Str & lhs, const C_Str & rhs )
1064  {
1065  const char * lp = lhs.c_str();
1066  const char * rp = rhs.c_str();
1067  std::string::size_type ret = 0;
1068  while ( *lp == *rp && *lp != '\0' )
1069  { ++lp, ++rp, ++ret; }
1070  return ret;
1071  }
1073  inline std::string::size_type commonPrefixCI( const C_Str & lhs, const C_Str & rhs )
1074  {
1075  const char * lp = lhs.c_str();
1076  const char * rp = rhs.c_str();
1077  std::string::size_type ret = 0;
1078  while ( tolower(*lp) == tolower(*rp) && *lp != '\0' )
1079  { ++lp, ++rp, ++ret; }
1080  return ret;
1081  }
1082 
1083 
1085  inline bool startsWith( const C_Str & str_r, const C_Str & prefix_r )
1086  { return hasPrefix( str_r, prefix_r ); }
1088  inline bool startsWithCI( const C_Str & str_r, const C_Str & prefix_r )
1089  { return hasPrefixCI( str_r, prefix_r ); }
1090 
1092  inline bool endsWith( const C_Str & str_r, const C_Str & prefix_r )
1093  { return hasSuffix( str_r, prefix_r ); }
1095  inline bool endsWithCI( const C_Str & str_r, const C_Str & prefix_r )
1096  { return hasSuffixCI( str_r, prefix_r ); }
1098  } // namespace str
1100 
1101  // drag into zypp:: namespace
1102  using str::asString;
1103 
1104 } // namespace zypp
1106 #endif // ZYPP_BASE_STRING_H
Convenience char* constructible from std::string and char*, it maps (char*)0 to an empty string.
Definition: String.h:91
std::ostream & operator<<(std::ostream &str, const C_Str &obj)
Stream output.
Definition: String.h:124
size_type size() const
Definition: String.h:108
bool empty() const
Definition: String.h:107
C_Str(const std::string &str_r)
Definition: String.h:99
C_Str(char *c_str_r)
Definition: String.h:97
C_Str(const boost::string_ref &str_r)
Definition: String.h:100
const char *const _val
Definition: String.h:119
C_Str(const char *c_str_r)
Definition: String.h:98
const char * c_str() const
Definition: String.h:116
bool isNull() const
Definition: String.h:106
std::string::size_type size_type
Definition: String.h:93
size_type _sze
Definition: String.h:120
boost::logic::tribool TriBool
3-state boolean logic (true, false and indeterminate).
Definition: String.h:30
Boost libraries.
Definition: Arch.h:348
String related utilities and Regular expression matching.
SolvableIdType size_type
Definition: PoolMember.h:126
std::string octstring(char n, int w=4)
Definition: String.h:348
std::string stripLastWord(std::string &line, const bool rtrim_first)
Definition: String.cc:296
std::string hexdecode(const C_Str &str_r)
Decode hexencoded XX sequences.
Definition: String.cc:145
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:1063
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:330
Trim
To define how to trim.
Definition: String.h:496
@ NO_TRIM
Definition: String.h:497
@ R_TRIM
Definition: String.h:499
@ TRIM
Definition: String.h:500
@ L_TRIM
Definition: String.h:498
std::string hexencode(const C_Str &str_r)
Encode all characters other than [a-zA-Z0-9] as XX.
Definition: String.cc:124
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:798
std::string stripPrefixCI(const C_Str &str_r, const C_Str &prefix_r)
Definition: String.h:1037
const std::string & asString(const std::string &t)
Global asString() that works with std::string too.
Definition: String.h:139
bool hasSuffix(const C_Str &str_r, const C_Str &suffix_r)
Return whether str_r has suffix suffix_r.
Definition: String.h:1041
unsigned splitFields(const C_Str &line_r, TOutputIterator result_r, const C_Str &sepchars_r=":")
Split line_r into fields.
Definition: String.h:725
std::string numstring(char n, int w=0)
Definition: String.h:289
std::string & replaceAllFun(std::string &str_r, const std::string &from_r, function< std::string()> to_r)
Definition: String.cc:353
std::string gsubFun(const std::string &str_r, const std::string &from_r, function< std::string()> to_r)
Definition: String.cc:347
std::string binstring(TInt val_r)
String representation of number as bit-string with leading '0's.
Definition: String.h:364
bool strToFalse(const C_Str &str)
Return false if str is 0, false, no, off, never.
Definition: String.cc:81
std::ostream & printIndented(std::ostream &str, const std::string &text_r, const std::string &indent_r=" ", unsigned maxWitdh_r=0)
Indent by string [" "] optionally wrap.
Definition: String.h:845
std::string::size_type commonPrefixCI(const C_Str &lhs, const C_Str &rhs)
Definition: String.h:1073
std::string stripFirstWord(std::string &line, const bool ltrim_first)
Definition: String.cc:263
std::string stripSuffixCI(const C_Str &str_r, const C_Str &suffix_r)
Definition: String.h:1055
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:887
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:922
std::ostream & autoPrefix0(std::ostream &str, const std::string &text_r, function< std::string()> fnc_r)
Definition: String.h:902
bool hasPrefix(const C_Str &str_r, const C_Str &prefix_r)
Return whether str_r has prefix prefix_r.
Definition: String.h:1027
std::string getline(std::istream &str, const Trim trim_r)
Return stream content up to (but not returning) the next newline.
Definition: String.cc:478
TriBool strToTriBool(const C_Str &str)
Parse str into a bool if it's a legal true or false string; else indterminate.
Definition: String.cc:93
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:764
bool startsWith(const C_Str &str_r, const C_Str &prefix_r)
alias for hasPrefix
Definition: String.h:1085
bool endsWith(const C_Str &str_r, const C_Str &prefix_r)
alias for hasSuffix
Definition: String.h:1092
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:1048
std::string bEscape(std::string str_r, const C_Str &special_r)
Return str_r with '\'-escaped chars occurring in special_r (and '\').
Definition: String.cc:394
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,...
Definition: String.cc:488
std::string rtrim(const std::string &s)
Definition: String.h:511
std::string strerror(int errno_r)
Return string describing the error_r code.
Definition: String.cc:53
std::string join(TIterator begin, TIterator end, const C_Str &sep_r=" ")
Join strings using separator sep_r (defaults to BLANK).
Definition: String.h:776
std::string escape(const C_Str &str_r, const char sep_r)
Escape desired character c using a backslash.
Definition: String.cc:371
std::string toUpper(const std::string &s)
Return uppercase version of s.
Definition: String.cc:200
std::string ltrim(const std::string &s)
Definition: String.h:506
std::string form(const char *format,...) __attribute__((format(printf
Printf style construction of std::string.
Definition: String.cc:36
std::string rxEscapeStr(std::string str_r)
Escape plain STRING str_r for use in a regex (not anchored by "^" or "$").
Definition: String.cc:415
bool strToBool(const C_Str &str, bool default_r)
Parse str into a bool depending on the default value.
Definition: String.h:429
bool hasPrefixCI(const C_Str &str_r, const C_Str &prefix_r)
Definition: String.h:1030
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:1034
std::string hexstring(char n, int w=4)
Definition: String.h:324
unsigned split(const C_Str &line_r, TOutputIterator result_r, const C_Str &sepchars_r=" \t", const Trim trim_r=NO_TRIM)
Split line_r into words.
Definition: String.h:531
TInt strtonum(const C_Str &str)
Parsing numbers from string.
Definition: String.h:388
std::string rxEscapeGlob(std::string str_r)
Escape GLOB str_r for use in a regex (not anchored by "^" or "$").
Definition: String.cc:420
bool containsCI(const C_Str &str_r, const C_Str &val_r)
Locate substring case insensitive.
Definition: String.h:994
bool contains(const C_Str &str_r, const C_Str &val_r)
Locate substring case sensitive.
Definition: String.h:991
std::string toLower(const std::string &s)
Return lowercase version of s.
Definition: String.cc:177
bool strToTrue(const C_Str &str)
Parsing boolean from string.
Definition: String.cc:63
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:324
unsigned splitEscaped(const C_Str &line_r, TOutputIterator result_r, const C_Str &sepchars_r=" \t", bool withEmpty=false)
Split line_r into words with respect to escape delimeters.
Definition: String.h:595
bool endsWithCI(const C_Str &str_r, const C_Str &prefix_r)
Definition: String.h:1095
bool hasSuffixCI(const C_Str &str_r, const C_Str &suffix_r)
Definition: String.h:1044
std::string trim(const std::string &s, const Trim trim_r)
Definition: String.cc:223
bool strToBoolNodefault(const C_Str &str, bool &return_r)
Parse str into a bool if it's a legal true or false string.
Definition: String.h:436
int compareCI(const C_Str &lhs, const C_Str &rhs)
Definition: String.h:984
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:479
bool startsWithCI(const C_Str &str_r, const C_Str &prefix_r)
Definition: String.h:1088
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:2
std::string asUserString(VendorSupportOption opt)
converts the support option to a name intended to be printed to the user.
Convenient building of std::string with boost::format.
Definition: String.h:253
std::string asString() const
Definition: String.h:262
std::ostream & operator<<(std::ostream &str, const Format &obj)
Stream output.
Definition: String.h:273
Format(const std::string &format_r)
Definition: String.h:255
Format & operator%(Tp &&arg)
Definition: String.h:258
boost::format & fmter()
Definition: String.h:266
std::string str() const
Definition: String.h:263
boost::format _fmter
Definition: String.h:269
const boost::format & fmter() const
Definition: String.h:265
Assert free called for allocated char *.
Definition: String.h:191
std::string asString() const
Definition: String.h:195
Convenient building of std::string via std::ostringstream Basically a std::ostringstream autoconverti...
Definition: String.h:212
std::ostream & operator<<(std::ostream &str, const Str &obj)
Stream output.
Definition: String.h:234
Str & operator<<(Tp &&val)
Definition: String.h:214
Str & operator<<(std::ostream &(*iomanip)(std::ostream &))
Definition: String.h:217
const std::ostream & stream() const
Definition: String.h:224
std::string asString() const
Definition: String.h:221
void clear()
Definition: String.h:227
std::string str() const
Definition: String.h:222
std::ostringstream _str
Definition: String.h:230
std::ostream & stream()
Definition: String.h:225
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
Definition: Easy.h:28