libzypp  17.37.5
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 <optional>
22 #include <boost/format.hpp>
23 #include <boost/utility/string_ref.hpp>
24 
25 #include <zypp-core/base/Easy.h>
28 
30 namespace boost { namespace logic { class tribool; } }
31 namespace zypp { using TriBool = boost::logic::tribool; }
33 
35 namespace zypp
36 {
40  template <class Tp>
41  std::string asUserString( const Tp & val_r )
42  { return val_r.asUserString(); }
43 
44 }// namespace zypp
46 
48 namespace zypp
49 {
50 
91  class C_Str
92  {
93  public:
95 
96  public:
97  C_Str() : _val( 0 ), _sze( 0 ) {}
98  C_Str( char * c_str_r ) : _val( c_str_r ), _sze( std::string::npos ) {}
99  C_Str( const char * c_str_r ) : _val( c_str_r ), _sze( std::string::npos ) {}
100  C_Str( const std::string & str_r ) : _val( str_r.c_str() ), _sze( str_r.size() ) {}
101  C_Str( const boost::string_ref & str_r ) : _val( str_r.data() ), _sze( str_r.size() ) {}
102 #ifdef __cpp_lib_string_view
103  C_Str( const std::string_view & str_r ) : _val( str_r.data() ), _sze( str_r.size() ) {}
104 #endif
105 
106  public:
107  bool isNull() const { return !_val; }
108  bool empty() const { return !(_val && *_val); }
109  size_type size() const
110  {
111  if ( _sze == std::string::npos )
112  { _sze = _val ? ::strlen( _val ) : 0; }
113  return _sze;
114  };
115 
116  operator const char *() const { return c_str(); }
117  const char * c_str() const { return _val ? _val : ""; }
118 
119  private:
120  const char *const _val;
121  mutable size_type _sze;
122  };
123 
125  inline std::ostream & operator<<( std::ostream & str, const C_Str & obj )
126  { return str << obj.c_str(); }
127 
129 
133  namespace str
134  {
135 
137 
140  inline const std::string & asString( const std::string & t )
141  { return t; }
142 
143  inline std::string && asString( std::string && t )
144  { return std::move(t); }
145 
146  inline std::string asString( const char * t )
147  { return t == nullptr ? std::string() : t; }
148 
149  inline std::string asString( char * t )
150  { return t == nullptr ? std::string() : t; }
151 
152  template<class Tp>
153  inline std::string asString( const Tp &t )
154  { return t.asString(); }
155 
156  template<class Tp>
157  inline std::string asString( const intrusive_ptr<Tp> &p )
158  { return p->asString(); }
159 
160  template<class Tp>
161  inline std::string asString( const weak_ptr<Tp> &p )
162  { return p->asString(); }
163 
164  template<>
165  inline std::string asString( const bool &t )
166  { return t ? "true" : "false"; }
167 
169 
170  std::string form( const char * format, ... )
171  __attribute__ ((format (printf, 1, 2))) ZYPP_API;
172 
174 
178  std::string strerror( int errno_r ) ZYPP_API;
179 
181 
191  struct SafeBuf
192  {
193  char * _buf;
194  SafeBuf() : _buf( 0 ) {}
195  ~SafeBuf() { if ( _buf ) free( _buf ); }
196  std::string asString() const
197  { return _buf ? std::string(_buf) : std::string(); }
198  };
199 
212  struct Str
213  {
214  template<class Tp>
215  Str & operator<<( Tp && val )
216  { _str << std::forward<Tp>(val); return *this; }
217 
218  Str & operator<<( std::ostream& (*iomanip)( std::ostream& ) )
219  { _str << iomanip; return *this; }
220 
221  operator std::string() const { return _str.str(); }
222  std::string asString() const { return _str.str(); }
223  std::string str() const { return _str.str(); }
224 
225  const std::ostream & stream() const { return _str; }
226  std::ostream & stream() { return _str; }
227 
228  void clear() { _str.str( std::string() ); }
229 
230  private:
231  std::ostringstream _str;
232  };
233 
235  inline std::ostream & operator<<( std::ostream & str, const Str & obj )
236  { return str << obj.str(); }
237 
253  struct Format
254  {
255  Format() { _fmter.exceptions( boost::io::no_error_bits ); }
256  Format( const std::string & format_r ) : Format() { _fmter.parse( format_r ); }
257 
258  template<class Tp>
259  Format & operator%( Tp && arg )
260  { _fmter % std::forward<Tp>(arg); return *this; }
261 
262  operator std::string() const { return _fmter.str(); }
263  std::string asString() const { return _fmter.str(); }
264  std::string str() const { return _fmter.str(); }
265 
266  const boost::format & fmter() const { return _fmter; }
267  boost::format & fmter() { return _fmter; }
268 
269  protected:
270  boost::format _fmter;
271  };
272 
274  inline std::ostream & operator<<( std::ostream & str, const Format & obj )
275  { return str << obj.fmter(); }
276 
290  inline std::string numstring( char n, int w = 0 ) { return form( "%*hhd", w, n ); }
291  inline std::string numstring( unsigned char n, int w = 0 ) { return form( "%*hhu", w, n ); }
292  inline std::string numstring( short n, int w = 0 ) { return form( "%*hd", w, n ); }
293  inline std::string numstring( unsigned short n, int w = 0 ) { return form( "%*hu", w, n ); }
294  inline std::string numstring( int n, int w = 0 ) { return form( "%*d", w, n ); }
295  inline std::string numstring( unsigned n, int w = 0 ) { return form( "%*u", w, n ); }
296  inline std::string numstring( long n, int w = 0 ) { return form( "%*ld", w, n ); }
297  inline std::string numstring( unsigned long n, int w = 0 ) { return form( "%*lu", w, n ); }
298  inline std::string numstring( long long n, int w = 0 ) { return form( "%*lld", w, n ); }
299  inline std::string numstring( unsigned long long n, int w = 0 ) { return form( "%*llu", w, n ); }
300 
301  template<> inline std::string asString( const char & t ) { return numstring( t ); }
302  template<> inline std::string asString( const unsigned char & t ) { return numstring( t ); }
303  template<> inline std::string asString( const short & t ) { return numstring( t ); }
304  template<> inline std::string asString( const unsigned short & t ) { return numstring( t ); }
305  template<> inline std::string asString( const int & t ) { return numstring( t ); }
306  template<> inline std::string asString( const unsigned & t ) { return numstring( t ); }
307  template<> inline std::string asString( const long & t ) { return numstring( t ); }
308  template<> inline std::string asString( const unsigned long & t ) { return numstring( t ); }
309  template<> inline std::string asString( const long long & t ) { return numstring( t ); }
310  template<> inline std::string asString( const unsigned long long & t ) { return numstring( t ); }
312 
314 
325  inline std::string hexstring( char n, int w = 4 ) { return form( "%#0*hhx", w, n ); }
326  inline std::string hexstring( unsigned char n, int w = 4 ) { return form( "%#0*hhx", w, n ); }
327  inline std::string hexstring( short n, int w = 10 ){ return form( "%#0*hx", w, n ); }
328  inline std::string hexstring( unsigned short n, int w = 10 ){ return form( "%#0*hx", w, n ); }
329  inline std::string hexstring( int n, int w = 10 ){ return form( "%#0*x", w, n ); }
330  inline std::string hexstring( unsigned n, int w = 10 ){ return form( "%#0*x", w, n ); }
331  inline std::string hexstring( long n, int w = 10 ){ return form( "%#0*lx", w, n ); }
332  inline std::string hexstring( unsigned long n, int w = 10 ){ return form( "%#0*lx", w, n ); }
333  inline std::string hexstring( long long n, int w = 0 ) { return form( "%#0*llx", w, n ); }
334  inline std::string hexstring( unsigned long long n, int w = 0 ) { return form( "%#0*llx", w, n ); }
336 
337 #ifdef __cpp_lib_string_view
338 
339  inline constexpr char hexCharToByte( char c ){
340  return (((c)>='0' && (c)<='9') ? ((c)-'0')
341  : ((c)>='a' && (c)<='f') ? ((c)-('a'-10))
342  : ((c)>='A' && (c)<='F') ? ((c)-('A'-10))
343  : -1);
344  }
345 
346  template <typename BArr = std::string>
347  BArr hexstringToByteArray ( std::string_view str ) {
348  BArr bytes;
349  for ( std::string::size_type i = 0; i < str.length(); i+=2 )
350  {
351  int v = hexCharToByte(str[i]);
352  if (v < 0)
353  return {};
354  bytes.push_back(v);
355  v = hexCharToByte(str[i+1]);
356  if (v < 0)
357  return {};
358  bytes.back() = (bytes.back() << 4) | v;
359  }
360  return bytes;
361  }
362 
363 
369  template<typename T=uint32_t>
370  constexpr std::enable_if_t< std::is_integral_v<T>, std::optional<T> > hexCharToValue( std::string_view hexChar ) {
371 
372  // the max length of the hexChar array for the target type
373  constexpr auto l = sizeof(T) * 2;
374  if ( hexChar.length() == 0 || hexChar.length() % 2 || hexChar.length() > l )
375  return {};
376 
377  int cp = 0;
378  int shift = 0;
379  for ( const auto c : hexChar ) {
380  const char b = hexCharToByte(c);
381  if ( b < 0 )
382  return {};
383  cp = (cp << shift) | b;
384  shift = 4;
385  }
386 
387  return cp;
388  }
389 
393  std::string hexCodepointToUtf8String( std::string_view hexChar );
394 
398  std::string codepointToUtf8String( uint32_t unichar );
399 
403  bool validateUtf8( std::string_view str );
404 
405 #endif
406 
408 
419  inline std::string octstring( char n, int w = 4 ) { return form( "%#0*hho", w, n ); }
420  inline std::string octstring( unsigned char n, int w = 4 ) { return form( "%#0*hho", w, n ); }
421  inline std::string octstring( short n, int w = 5 ) { return form( "%#0*ho", w, n ); }
422  inline std::string octstring( unsigned short n, int w = 5 ) { return form( "%#0*ho", w, n ); }
423  inline std::string octstring( int n, int w = 5 ) { return form( "%#0*o", w, n ); }
424  inline std::string octstring( unsigned n, int w = 5 ) { return form( "%#0*o", w, n ); }
425  inline std::string octstring( long n, int w = 5 ) { return form( "%#0*lo", w, n ); }
426  inline std::string octstring( unsigned long n, int w = 5 ) { return form( "%#0*lo", w, n ); }
427  inline std::string octstring( long long n, int w = 0 ) { return form( "%#0*llo", w, n ); }
428  inline std::string octstring( unsigned long long n, int w = 0 ) { return form( "%#0*llo", w, n ); }
430 
431 
433 
434  template <typename TInt>
435  std::string binstring( TInt val_r )
436  {
437  constexpr unsigned bits = sizeof(TInt)*8;
438  std::string ret( bits, ' ' );
439  TInt bit = 1;
440  for ( unsigned pos = bits; pos > 0; )
441  { --pos; ret[pos] = ((val_r & bit)?'1':'0'); bit = bit<<1; }
442  return ret;
443  }
444 
446 
455  template<typename TInt>
456  TInt strtonum( const C_Str & str );
457 
458  template<>
459  inline short strtonum( const C_Str & str ) { return ::strtol ( str, NULL, 0 ); }
460  template<>
461  inline int strtonum( const C_Str & str ) { return ::strtol ( str, NULL, 0 ); }
462  template<>
463  inline long strtonum( const C_Str & str ) { return ::strtol ( str, NULL, 0 ); }
464  template<>
465  inline long long strtonum( const C_Str & str ) { return ::strtoll ( str, NULL, 0 ); }
466 
467  template<>
468  inline unsigned short strtonum( const C_Str & str ) { return ::strtoul ( str, NULL, 0 ); }
469  template<>
470  inline unsigned strtonum( const C_Str & str ) { return ::strtoul ( str, NULL, 0 ); }
471  template<>
472  inline unsigned long strtonum( const C_Str & str ) { return ::strtoul ( str, NULL, 0 ); }
473  template<>
474  inline unsigned long long strtonum( const C_Str & str ) { return ::strtoull( str, NULL, 0 ); }
475 
481  template<typename TInt>
482  inline TInt strtonum( const C_Str & str, TInt & i )
483  { return i = strtonum<TInt>( str ); }
485 
487 
491  bool strToTrue( const C_Str & str ) ZYPP_API;
492 
494  bool strToFalse( const C_Str & str ) ZYPP_API;
495 
500  inline bool strToBool( const C_Str & str, bool default_r )
501  { return( default_r ? strToFalse( str ) : strToTrue( str ) ); }
502 
507  inline bool strToBoolNodefault( const C_Str & str, bool & return_r )
508  {
509  if ( strToTrue( str ) ) return (return_r = true);
510  if ( !strToFalse( str ) ) return (return_r = false);
511  return return_r;
512  }
513 
516 
518 
522  std::string gsub( const std::string & str_r, const std::string & from_r, const std::string & to_r ) ZYPP_API;
523 
526  std::string gsubFun( const std::string & str_r, const std::string & from_r, function<std::string()> to_r ) ZYPP_API;
527 
532  std::string & replaceAll( std::string & str_r, const std::string & from_r, const std::string & to_r ) ZYPP_API;
533 
536  std::string & replaceAllFun( std::string & str_r, const std::string & from_r, const function<std::string()>& to_r ) ZYPP_API;
537 
550  inline std::string gapify( std::string inp_r, std::string::size_type gap_r = 1, char gapchar = ' ' )
551  {
552  if ( gap_r && inp_r.size() > gap_r )
553  {
554  inp_r.reserve( inp_r.size() + (inp_r.size()-1)/gap_r );
555  for ( std::string::size_type pos = gap_r; pos < inp_r.size(); pos += gap_r+1 )
556  inp_r.insert( pos, 1, gapchar );
557  }
558  return inp_r;
559  }
560 
562 
567  enum Trim {
568  NO_TRIM = 0x00,
569  L_TRIM = 0x01,
570  R_TRIM = 0x02,
572  };
573 
574  std::string trim( const std::string & s, const Trim trim_r = TRIM ) ZYPP_API;
575  std::string trim( std::string && s, const Trim trim_r = TRIM ) ZYPP_API;
576 
577  inline std::string ltrim( const std::string & s )
578  { return trim( s, L_TRIM ); }
579  inline std::string ltrim( std::string && s )
580  { return trim( std::move(s), L_TRIM ); }
581 
582  inline std::string rtrim( const std::string & s )
583  { return trim( s, R_TRIM ); }
584  inline std::string rtrim( std::string && s )
585  { return trim( std::move(s), R_TRIM ); }
587 
588 
590 
601  template<class TOutputIterator>
602  unsigned split( const C_Str & line_r, TOutputIterator result_r, const C_Str & sepchars_r = " \t", const Trim trim_r = NO_TRIM )
603  {
604  const char * beg = line_r;
605  const char * cur = beg;
606  // skip leading sepchars
607  while ( *cur && ::strchr( sepchars_r, *cur ) )
608  ++cur;
609  unsigned ret = 0;
610  for ( beg = cur; *beg; beg = cur, ++result_r, ++ret )
611  {
612  // skip non sepchars
613  while( *cur && !::strchr( sepchars_r, *cur ) )
614  ++cur;
615  // build string
616  *result_r = trim( std::string( beg, cur-beg ), trim_r );
617  // skip sepchars
618  while ( *cur && ::strchr( sepchars_r, *cur ) )
619  ++cur;
620  }
621  return ret;
622  }
623 
624  template<class TOutputIterator>
625  unsigned split( const C_Str & line_r, TOutputIterator result_r, const Trim trim_r )
626  { return split( line_r, result_r, " \t", trim_r ); }
627 
628 
665  template<class TOutputIterator>
666  unsigned splitEscaped( const C_Str & line_r, TOutputIterator result_r, const C_Str & sepchars_r = " \t", bool withEmpty = false)
667  {
668  const char * beg = line_r;
669  const char * cur = beg;
670  unsigned ret = 0;
671 
672  // skip leading sepchars
673  while ( *cur && ::strchr( sepchars_r, *cur ) )
674  {
675  ++cur;
676  if (withEmpty)
677  {
678  *result_r = "";
679  ++ret;
680  }
681  }
682 
683  // there were only sepchars in the string
684  if (!*cur && withEmpty)
685  {
686  *result_r = "";
687  return ++ret;
688  }
689 
690  // after the leading sepchars
691  enum class Quote { None, Slash, Single, Double, DoubleSlash };
692  std::vector<char> buf;
693  Quote quoting = Quote::None;
694  for ( beg = cur; *beg; beg = cur, ++result_r, ++ret )
695  {
696  // read next value until unquoted sepchar
697  buf.clear();
698  quoting = Quote::None;
699  do {
700  switch ( quoting )
701  {
702  case Quote::None:
703  switch ( *cur )
704  {
705  case '\\': quoting = Quote::Slash; break;
706  case '\'': quoting = Quote::Single; break;
707  case '"': quoting = Quote::Double; break;
708  default: buf.push_back( *cur ); break;
709  }
710  break;
711 
712  case Quote::Slash:
713  buf.push_back( *cur );
714  quoting = Quote::None;
715  break;
716 
717  case Quote::Single:
718  switch ( *cur )
719  {
720  case '\'': quoting = Quote::None; break;
721  default: buf.push_back( *cur ); break;
722  }
723  break;
724 
725  case Quote::Double:
726  switch ( *cur )
727  {
728  case '\"': quoting = Quote::None; break;
729  case '\\': quoting = Quote::DoubleSlash; break;
730  default: buf.push_back( *cur ); break;
731  }
732  break;
733 
734  case Quote::DoubleSlash:
735  switch ( *cur )
736  {
737  case '\"': /*fallthrough*/
738  case '\\': buf.push_back( *cur ); break;
739  default:
740  buf.push_back( '\\' );
741  buf.push_back( *cur );
742  break;
743  }
744  quoting = Quote::Double;
745  break;
746  }
747  ++cur;
748  } while ( *cur && ( quoting != Quote::None || !::strchr( sepchars_r, *cur ) ) );
749  *result_r = std::string( buf.begin(), buf.end() );
750 
751 
752  // skip sepchars
753  if ( *cur && ::strchr( sepchars_r, *cur ) )
754  ++cur;
755  while ( *cur && ::strchr( sepchars_r, *cur ) )
756  {
757  ++cur;
758  if (withEmpty)
759  {
760  *result_r = "";
761  ++ret;
762  }
763  }
764  // the last was a separator => one more field
765  if ( !*cur && withEmpty && ::strchr( sepchars_r, *(cur-1) ) )
766  {
767  *result_r = "";
768  ++ret;
769  }
770  }
771  return ret;
772  }
773 
795  template<class TOutputIterator>
796  unsigned splitFields( const C_Str & line_r, TOutputIterator result_r, const C_Str & sepchars_r = ":" )
797  {
798  const char * beg = line_r;
799  const char * cur = beg;
800  unsigned ret = 0;
801  for ( beg = cur; *beg; beg = cur, ++result_r )
802  {
803  // skip non sepchars
804  while( *cur && !::strchr( sepchars_r, *cur ) )
805  {
806  if ( *cur == '\\' && *(cur+1) )
807  ++cur;
808  ++cur;
809  }
810  // build string
811  *result_r = std::string( beg, cur-beg );
812  ++ret;
813  // skip sepchar
814  if ( *cur )
815  {
816  ++cur;
817  if ( ! *cur ) // ending with sepchar
818  {
819  *result_r = std::string(); // add final empty field
820  ++ret;
821  break;
822  }
823  }
824  }
825  return ret;
826  }
827 
834  template<class TOutputIterator>
835  unsigned splitFieldsEscaped( const C_Str & line_r, TOutputIterator result_r, const C_Str & sepchars_r = ":" )
836  {
837  return splitEscaped( line_r, result_r, sepchars_r, true /* withEmpty */ );
838  }
839 
841 
843 
846  template <class TIterator>
847  std::string join( TIterator begin, TIterator end, const C_Str & sep_r = " " )
848  {
849  std::string res;
850  for ( TIterator iter = begin; iter != end; ++ iter )
851  {
852  if ( iter != begin )
853  res += sep_r;
854  res += asString(*iter);
855  }
856  return res;
857  }
858 
860  template <class TContainer>
861  std::string join( const TContainer & cont_r, const C_Str & sep_r = " " )
862  { return join( cont_r.begin(), cont_r.end(), sep_r ); }
863 
868  template <class TIterator>
869  std::string joinEscaped( TIterator begin, TIterator end, const char sep_r = ' ' )
870  {
871  std::vector<char> buf;
872  for ( TIterator iter = begin; iter != end; ++ iter )
873  {
874  if ( iter != begin )
875  buf.push_back( sep_r );
876 
877  if ( iter->empty() )
878  {
879  // empty string goes ""
880  buf.push_back( '"' );
881  buf.push_back( '"' );
882  }
883  else
884  {
885  std::string toadd( asString(*iter) );
886  for ( const char ch : toadd )
887  {
888  switch ( ch )
889  {
890  case '"':
891  case '\'':
892  case '\\':
893  buf.push_back( '\\' );
894  buf.push_back( ch );
895  break;
896  default:
897  if ( ch == sep_r )
898  buf.push_back( '\\' );
899  buf.push_back( ch );
900  }
901  }
902  }
903  }
904  return std::string( buf.begin(), buf.end() );
905  }
907 
908 
910 
916  inline std::ostream & printIndented( std::ostream & str, const std::string & text_r, const std::string & indent_r = " ", unsigned maxWitdh_r = 0 )
917  {
918  if ( maxWitdh_r )
919  {
920  if ( indent_r.size() >= maxWitdh_r )
921  maxWitdh_r = 0; // nonsense: indent larger than line witdh
922  else
923  maxWitdh_r -= indent_r.size();
924  }
925 
926  for ( const char * e = text_r.c_str(), * s = e; *e; s = ++e )
927  {
928  for ( ; *e && *e != '\n'; ++e ) ;/*searching*/
929  unsigned width = e-s;
930  if ( maxWitdh_r && width > maxWitdh_r )
931  {
932  // must break line
933  width = maxWitdh_r;
934  for ( e = s+width; e > s && *e != ' '; --e ) ;/*searching*/
935  if ( e > s )
936  width = e-s; // on a ' ', replaced by '\n'
937  else
938  e = s+width-1; // cut line;
939  }
940  str << indent_r;
941  str.write( s, width );
942  str << "\n";
943  if ( !*e ) // on '\0'
944  break;
945  }
946  return str;
947  }
949  inline std::ostream & printIndented( std::ostream & str, const std::string & text_r, unsigned indent_r, char indentch_r = ' ', unsigned maxWitdh_r = 0 )
950  { return printIndented( str, text_r, std::string( indent_r, indentch_r ), maxWitdh_r ); }
952  inline std::ostream & printIndented( std::ostream & str, const std::string & text_r, unsigned indent_r, unsigned maxWitdh_r, char indentch_r = ' ' )
953  { return printIndented( str, text_r, std::string( indent_r, indentch_r ), maxWitdh_r ); }
954 
958  inline std::ostream & autoPrefix( std::ostream & str, const std::string & text_r, const function<std::string(const char*, const char*)>& fnc_r )
959  {
960  for ( const char * e = text_r.c_str(); *e; ++e )
961  {
962  const char * s = e;
963  for ( ; *e && *e != '\n'; ++e ) /*searching*/;
964  str << fnc_r( s, e );
965  str.write( s, e-s );
966  str << "\n";
967  if ( !*e ) // on '\0'
968  break;
969  }
970  return str;
971  }
973  inline std::ostream & autoPrefix0( std::ostream & str, const std::string & text_r, function<std::string()> fnc_r )
974  {
975  auto wrap = [&fnc_r]( const char*, const char* )-> std::string {
976  return fnc_r();
977  };
978  return autoPrefix( str, text_r, wrap );
979  }
981 
990  std::string escape( const C_Str & str_r, const char c = ' ' ) ZYPP_API;
991 
993  inline void appendEscaped( std::string & str_r, const C_Str & next_r, const char sep_r = ' ' )
994  {
995  if ( ! str_r.empty() )
996  str_r += sep_r;
997  if ( next_r.empty() )
998  str_r += "\"\"";
999  else
1000  str_r += escape( next_r, sep_r );
1001  }
1002 
1004  std::string bEscape( std::string str_r, const C_Str & special_r ) ZYPP_API;
1005 
1007  std::string rxEscapeStr( std::string str_r ) ZYPP_API;
1008 
1010  std::string rxEscapeGlob( std::string str_r ) ZYPP_API;
1011 
1013 
1015 
1025  std::string hexencode( const C_Str & str_r );
1027  std::string hexdecode( const C_Str & str_r );
1029 
1036  std::string toLower( const std::string & s ) ZYPP_API;
1037  std::string toLower( std::string && s ) ZYPP_API;
1039  inline std::string toLower( const char * s )
1040  { return( s ? toLower( std::string(s) ) : std::string() ); }
1041 
1045  std::string toUpper( const std::string & s ) ZYPP_API;
1046  std::string toUpper( std::string && s ) ZYPP_API;
1048  inline std::string toUpper( const char * s )
1049  { return( s ? toUpper( std::string(s) ) : std::string() ); }
1051 
1052 
1055  inline int compareCI( const C_Str & lhs, const C_Str & rhs )
1056  { return ::strcasecmp( lhs, rhs ); }
1058 
1062  inline bool contains( const C_Str & str_r, const C_Str & val_r )
1063  { return ::strstr( str_r, val_r ); }
1065  inline bool containsCI( const C_Str & str_r, const C_Str & val_r )
1066  { return ::strcasestr( str_r, val_r ); }
1068 
1069  std::string stripFirstWord( std::string & line, const bool ltrim_first = true ) ZYPP_API;
1070 
1071  std::string stripLastWord( std::string & line, const bool rtrim_first = true ) ZYPP_API;
1072 
1076  std::string getline( std::istream & str, bool trim = false ) ZYPP_API;
1077 
1081  std::string getline( std::istream & str, const Trim trim_r ) ZYPP_API;
1082 
1090  std::string receiveUpTo( std::istream & str, const char delim_r, bool returnDelim_r = false );
1091 
1093 
1098  inline bool hasPrefix( const C_Str & str_r, const C_Str & prefix_r )
1099  { return( ::strncmp( str_r, prefix_r, prefix_r.size() ) == 0 ); }
1101  inline bool hasPrefixCI( const C_Str & str_r, const C_Str & prefix_r )
1102  { return( ::strncasecmp( str_r, prefix_r, prefix_r.size() ) == 0 ); }
1103 
1105  inline std::string stripPrefix( const C_Str & str_r, const C_Str & prefix_r )
1106  { return( hasPrefix( str_r, prefix_r ) ? str_r + prefix_r.size() : str_r.c_str() ); }
1108  inline std::string stripPrefixCI( const C_Str & str_r, const C_Str & prefix_r )
1109  { return( hasPrefixCI( str_r, prefix_r ) ? str_r + prefix_r.size() : str_r.c_str() ); }
1110 
1112  inline bool hasSuffix( const C_Str & str_r, const C_Str & suffix_r )
1113  { return( str_r.size() >= suffix_r.size() && ::strncmp( str_r + str_r.size() - suffix_r.size() , suffix_r, suffix_r.size() ) == 0 ); }
1115  inline bool hasSuffixCI( const C_Str & str_r, const C_Str & suffix_r )
1116  { return( str_r.size() >= suffix_r.size() && ::strncasecmp( str_r + str_r.size() - suffix_r.size() , suffix_r, suffix_r.size() ) == 0 ); }
1117 
1119  inline std::string stripSuffix( const C_Str & str_r, const C_Str & suffix_r )
1120  {
1121  if ( hasSuffix( str_r, suffix_r ) )
1122  return std::string( str_r, str_r.size() - suffix_r.size() );
1123  return str_r.c_str();
1124  }
1126  inline std::string stripSuffixCI( const C_Str & str_r, const C_Str & suffix_r )
1127  {
1128  if ( hasSuffixCI( str_r, suffix_r ) )
1129  return std::string( str_r, str_r.size() - suffix_r.size() );
1130  return str_r.c_str();
1131  }
1132 
1134  inline std::string::size_type commonPrefix( const C_Str & lhs, const C_Str & rhs )
1135  {
1136  const char * lp = lhs.c_str();
1137  const char * rp = rhs.c_str();
1138  std::string::size_type ret = 0;
1139  while ( *lp == *rp && *lp != '\0' )
1140  { ++lp, ++rp, ++ret; }
1141  return ret;
1142  }
1144  inline std::string::size_type commonPrefixCI( const C_Str & lhs, const C_Str & rhs )
1145  {
1146  const char * lp = lhs.c_str();
1147  const char * rp = rhs.c_str();
1148  std::string::size_type ret = 0;
1149  while ( tolower(*lp) == tolower(*rp) && *lp != '\0' )
1150  { ++lp, ++rp, ++ret; }
1151  return ret;
1152  }
1153 
1154 
1156  inline bool startsWith( const C_Str & str_r, const C_Str & prefix_r )
1157  { return hasPrefix( str_r, prefix_r ); }
1159  inline bool startsWithCI( const C_Str & str_r, const C_Str & prefix_r )
1160  { return hasPrefixCI( str_r, prefix_r ); }
1161 
1163  inline bool endsWith( const C_Str & str_r, const C_Str & prefix_r )
1164  { return hasSuffix( str_r, prefix_r ); }
1166  inline bool endsWithCI( const C_Str & str_r, const C_Str & prefix_r )
1167  { return hasSuffixCI( str_r, prefix_r ); }
1169  } // namespace str
1171 
1172  // drag into zypp:: namespace
1173  using str::asString;
1174 
1175 } // namespace zypp
1177 #endif // ZYPP_BASE_STRING_H
std::string toLower(const std::string &s)
Return lowercase version of s.
Definition: String.cc:180
bool strToFalse(const C_Str &str)
Return false if str is 0, false, no, off, never.
Definition: String.cc:84
boost::logic::tribool TriBool
3-state boolean logic (true, false and indeterminate).
Definition: String.h:31
std::string getline(std::istream &str, const Trim trim_r)
Return stream content up to (but not returning) the next newline.
Definition: String.cc:481
bool contains(const C_Str &str_r, const C_Str &val_r)
Locate substring case sensitive.
Definition: String.h:1062
std::string str() const
Definition: String.h:223
std::string asString() const
Definition: String.h:222
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:666
std::string octstring(char n, int w=4)
Definition: String.h:419
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:327
C_Str(const boost::string_ref &str_r)
Definition: String.h:101
Definition: String.h:30
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:507
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:1105
unsigned short b
bool hasPrefixCI(const C_Str &str_r, const C_Str &prefix_r)
Definition: String.h:1101
std::string join(TIterator begin, TIterator end, const C_Str &sep_r=" ")
Join strings using separator sep_r (defaults to BLANK).
Definition: String.h:847
boost::format _fmter
Definition: String.h:270
bool hasSuffixCI(const C_Str &str_r, const C_Str &suffix_r)
Definition: String.h:1115
bool startsWithCI(const C_Str &str_r, const C_Str &prefix_r)
Definition: String.h:1159
std::string stripSuffixCI(const C_Str &str_r, const C_Str &suffix_r)
Definition: String.h:1126
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:1134
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:1119
std::ostream & autoPrefix0(std::ostream &str, const std::string &text_r, function< std::string()> fnc_r)
Definition: String.h:973
String related utilities and Regular expression matching.
std::string rxEscapeStr(std::string str_r)
Escape plain STRING str_r for use in a regex (not anchored by "^" or "$").
Definition: String.cc:418
C_Str(const std::string &str_r)
Definition: String.h:100
const std::string & asString(const std::string &t)
Global asString() that works with std::string too.
Definition: String.h:140
Definition: Arch.h:363
Convenient building of std::string with boost::format.
Definition: String.h:253
Format & operator%(Tp &&arg)
Definition: String.h:259
const char * c_str() const
Definition: String.h:117
std::string form(const char *format,...) __attribute__((format(printf
Printf style construction of std::string.
Definition: String.cc:39
Trim
To define how to trim.
Definition: String.h:567
std::string asUserString(VendorSupportOption opt)
converts the support option to a name intended to be printed to the user.
const boost::format & fmter() const
Definition: String.h:266
std::string asString() const
Definition: String.h:263
const std::ostream & stream() const
Definition: String.h:225
std::string ltrim(const std::string &s)
Definition: String.h:577
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:869
bool endsWithCI(const C_Str &str_r, const C_Str &prefix_r)
Definition: String.h:1166
TriBool strToTriBool(const C_Str &str)
Parse str into a bool if it&#39;s a legal true or false string; else indeterminate.
Definition: String.cc:96
size_type size() const
Definition: String.h:109
std::string strerror(int errno_r)
Return string describing the error_r code.
Definition: String.cc:56
std::string asString() const
Definition: String.h:196
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:916
unsigned split(const C_Str &line_r, TOutputIterator result_r, const C_Str &sepchars_r=" \, const Trim trim_r=NO_TRIM)
Split line_r into words.
Definition: String.h:602
std::string stripFirstWord(std::string &line, const bool ltrim_first)
Definition: String.cc:266
typename enable_if< B, T >::type enable_if_t
Definition: TypeTraits.h:45
Convenient building of std::string via std::ostringstream Basically a std::ostringstream autoconverti...
Definition: String.h:212
std::string trim(const std::string &s, const Trim trim_r)
Definition: String.cc:226
boost::format & fmter()
Definition: String.h:267
std::string _buf[TLen]
Definition: Capability.cc:49
std::string escape(const C_Str &str_r, const char sep_r)
Escape desired character c using a backslash.
Definition: String.cc:374
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 Format &obj)
Definition: String.h:274
bool startsWith(const C_Str &str_r, const C_Str &prefix_r)
alias for hasPrefix
Definition: String.h:1156
const char *const _val
Definition: String.h:120
std::string hexCodepointToUtf8String(std::string_view hexChar)
Definition: String.cc:535
std::string bEscape(std::string str_r, const C_Str &special_r)
Return str_r with &#39;\&#39;-escaped chars occurring in special_r (and &#39;\&#39;).
Definition: String.cc:397
TInt strtonum(const C_Str &str)
Parsing numbers from string.
Definition: String.h:459
std::string stripLastWord(std::string &line, const bool rtrim_first)
Definition: String.cc:299
std::string::size_type size_type
Definition: String.h:94
std::string toUpper(const std::string &s)
Return uppercase version of s.
Definition: String.cc:203
bool containsCI(const C_Str &str_r, const C_Str &val_r)
Locate substring case insensitive.
Definition: String.h:1065
std::string codepointToUtf8String(uint32_t unichar)
Definition: String.cc:525
std::string gsubFun(const std::string &str_r, const std::string &from_r, function< std::string()> to_r)
Definition: String.cc:350
bool endsWith(const C_Str &str_r, const C_Str &prefix_r)
alias for hasSuffix
Definition: String.h:1163
std::string numstring(char n, int w=0)
Definition: String.h:290
size_type _sze
Definition: String.h:121
int compareCI(const C_Str &lhs, const C_Str &rhs)
Definition: String.h:1055
std::string rtrim(const std::string &s)
Definition: String.h:582
Str & operator<<(Tp &&val)
Definition: String.h:215
std::ostream & operator<<(std::ostream &str, const Str &obj)
Definition: String.h:235
std::string ZYPP_API
Definition: String.h:171
unsigned splitFields(const C_Str &line_r, TOutputIterator result_r, const C_Str &sepchars_r=":")
Split line_r into fields.
Definition: String.h:796
bool hasSuffix(const C_Str &str_r, const C_Str &suffix_r)
Return whether str_r has suffix suffix_r.
Definition: String.h:1112
struct zypp::media::MediaBlock __attribute__
std::string str() const
Definition: String.h:264
std::string rxEscapeGlob(std::string str_r)
Escape GLOB str_r for use in a regex (not anchored by "^" or "$").
Definition: String.cc:423
C_Str(const char *c_str_r)
Definition: String.h:99
bool isNull() const
Definition: String.h:107
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:491
bool strToBool(const C_Str &str, bool default_r)
Parse str into a bool depending on the default value.
Definition: String.h:500
bool validateUtf8(std::string_view str)
Definition: String.cc:520
std::string hexencode(const C_Str &str_r)
Encode all characters other than [a-zA-Z0-9] as XX.
Definition: String.cc:127
Str & operator<<(std::ostream &(*iomanip)(std::ostream &))
Definition: String.h:218
std::string binstring(TInt val_r)
String representation of number as bit-string with leading &#39;0&#39;s.
Definition: String.h:435
std::string & replaceAllFun(std::string &str_r, const std::string &from_r, const function< std::string()> &to_r)
Definition: String.cc:356
bool empty() const
Definition: String.h:108
std::ostream & operator<<(std::ostream &str, const C_Str &obj)
Definition: String.h:125
std::string stripPrefixCI(const C_Str &str_r, const C_Str &prefix_r)
Definition: String.h:1108
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:333
std::ostream & autoPrefix(std::ostream &str, const std::string &text_r, const 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:958
C_Str(char *c_str_r)
Definition: String.h:98
Easy-to use interface to the ZYPP dependency resolver.
Definition: Application.cc:19
std::ostream & stream()
Definition: String.h:226
SolvableIdType size_type
Definition: PoolMember.h:126
Assert free called for allocated char *.
Definition: String.h:191
bool hasPrefix(const C_Str &str_r, const C_Str &prefix_r)
Return whether str_r has prefix prefix_r.
Definition: String.h:1098
void clear()
Definition: String.h:228
std::string hexstring(char n, int w=4)
Definition: String.h:325
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:993
std::ostringstream _str
Definition: String.h:231
std::string hexdecode(const C_Str &str_r)
Decode hexencoded XX sequences.
Definition: String.cc:148
std::string::size_type commonPrefixCI(const C_Str &lhs, const C_Str &rhs)
Definition: String.h:1144
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:835
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:550
bool strToTrue(const C_Str &str)
Parsing boolean from string.
Definition: String.cc:66
Format(const std::string &format_r)
Definition: String.h:256