libzypp 17.25.7
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
29namespace boost { namespace logic { class tribool; } }
30namespace zypp { typedef boost::logic::tribool TriBool; }
32
34namespace zypp
35{
39 template <class Tp>
40 std::string asUserString( const Tp & val_r )
41 { return val_r.asUserString(); }
42
43}// namespace zypp
45
47namespace 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); }
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;
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 inline std::string && asString( std::string && t )
140 { return std::move(t); }
141
142 inline std::string asString( const char * t )
143 { return t == nullptr ? std::string() : t; }
144
145 inline std::string asString( char * t )
146 { return t == nullptr ? std::string() : t; }
147
148 template<class Tp>
149 inline std::string asString( const Tp &t )
150 { return t.asString(); }
151
152 template<class Tp>
153 inline std::string asString( const intrusive_ptr<Tp> &p )
154 { return p->asString(); }
155
156 template<class Tp>
157 inline std::string asString( const weak_ptr<Tp> &p )
158 { return p->asString(); }
159
160 template<>
161 inline std::string asString( const bool &t )
162 { return t ? "true" : "false"; }
163
165
166 std::string form( const char * format, ... )
167 __attribute__ ((format (printf, 1, 2)));
168
170
174 std::string strerror( int errno_r );
175
177
187 struct SafeBuf
188 {
189 char * _buf;
190 SafeBuf() : _buf( 0 ) {}
191 ~SafeBuf() { if ( _buf ) free( _buf ); }
192 std::string asString() const
193 { return _buf ? std::string(_buf) : std::string(); }
194 };
195
208 struct Str
209 {
210 template<class Tp>
211 Str & operator<<( Tp && val )
212 { _str << std::forward<Tp>(val); return *this; }
213
214 Str & operator<<( std::ostream& (*iomanip)( std::ostream& ) )
215 { _str << iomanip; return *this; }
216
217 operator std::string() const { return _str.str(); }
218 std::string asString() const { return _str.str(); }
219 std::string str() const { return _str.str(); }
220
221 const std::ostream & stream() const { return _str; }
222 std::ostream & stream() { return _str; }
223
224 void clear() { _str.str( std::string() ); }
225
226 private:
227 std::ostringstream _str;
228 };
229
231 inline std::ostream & operator<<( std::ostream & str, const Str & obj )
232 { return str << obj.str(); }
233
249 struct Format
250 {
251 Format() { _fmter.exceptions( boost::io::no_error_bits ); }
252 Format( const std::string & format_r ) : Format() { _fmter.parse( format_r ); }
253
254 template<class Tp>
255 Format & operator%( Tp && arg )
256 { _fmter % std::forward<Tp>(arg); return *this; }
257
258 operator std::string() const { return _fmter.str(); }
259 std::string asString() const { return _fmter.str(); }
260 std::string str() const { return _fmter.str(); }
261
262 const boost::format & fmter() const { return _fmter; }
263 boost::format & fmter() { return _fmter; }
264
265 protected:
266 boost::format _fmter;
267 };
268
270 inline std::ostream & operator<<( std::ostream & str, const Format & obj )
271 { return str << obj.fmter(); }
272
286 inline std::string numstring( char n, int w = 0 ) { return form( "%*hhd", w, n ); }
287 inline std::string numstring( unsigned char n, int w = 0 ) { return form( "%*hhu", w, n ); }
288 inline std::string numstring( short n, int w = 0 ) { return form( "%*hd", w, n ); }
289 inline std::string numstring( unsigned short n, int w = 0 ) { return form( "%*hu", w, n ); }
290 inline std::string numstring( int n, int w = 0 ) { return form( "%*d", w, n ); }
291 inline std::string numstring( unsigned n, int w = 0 ) { return form( "%*u", w, n ); }
292 inline std::string numstring( long n, int w = 0 ) { return form( "%*ld", w, n ); }
293 inline std::string numstring( unsigned long n, int w = 0 ) { return form( "%*lu", w, n ); }
294 inline std::string numstring( long long n, int w = 0 ) { return form( "%*lld", w, n ); }
295 inline std::string numstring( unsigned long long n, int w = 0 ) { return form( "%*llu", w, n ); }
296
297 template<> inline std::string asString( const char & t ) { return numstring( t ); }
298 template<> inline std::string asString( const unsigned char & t ) { return numstring( t ); }
299 template<> inline std::string asString( const short & t ) { return numstring( t ); }
300 template<> inline std::string asString( const unsigned short & t ) { return numstring( t ); }
301 template<> inline std::string asString( const int & t ) { return numstring( t ); }
302 template<> inline std::string asString( const unsigned & t ) { return numstring( t ); }
303 template<> inline std::string asString( const long & t ) { return numstring( t ); }
304 template<> inline std::string asString( const unsigned long & t ) { return numstring( t ); }
305 template<> inline std::string asString( const long long & t ) { return numstring( t ); }
306 template<> inline std::string asString( const unsigned long long & t ) { return numstring( t ); }
308
310
321 inline std::string hexstring( char n, int w = 4 ) { return form( "%#0*hhx", w, n ); }
322 inline std::string hexstring( unsigned char n, int w = 4 ) { return form( "%#0*hhx", w, n ); }
323 inline std::string hexstring( short n, int w = 10 ){ return form( "%#0*hx", w, n ); }
324 inline std::string hexstring( unsigned short n, int w = 10 ){ return form( "%#0*hx", w, n ); }
325 inline std::string hexstring( int n, int w = 10 ){ return form( "%#0*x", w, n ); }
326 inline std::string hexstring( unsigned n, int w = 10 ){ return form( "%#0*x", w, n ); }
327 inline std::string hexstring( long n, int w = 10 ){ return form( "%#0*lx", w, n ); }
328 inline std::string hexstring( unsigned long n, int w = 10 ){ return form( "%#0*lx", w, n ); }
329 inline std::string hexstring( long long n, int w = 0 ) { return form( "%#0*llx", w, n ); }
330 inline std::string hexstring( unsigned long long n, int w = 0 ) { return form( "%#0*llx", w, n ); }
332
334
345 inline std::string octstring( char n, int w = 4 ) { return form( "%#0*hho", w, n ); }
346 inline std::string octstring( unsigned char n, int w = 4 ) { return form( "%#0*hho", w, n ); }
347 inline std::string octstring( short n, int w = 5 ) { return form( "%#0*ho", w, n ); }
348 inline std::string octstring( unsigned short n, int w = 5 ) { return form( "%#0*ho", w, n ); }
349 inline std::string octstring( int n, int w = 5 ) { return form( "%#0*o", w, n ); }
350 inline std::string octstring( unsigned n, int w = 5 ) { return form( "%#0*o", w, n ); }
351 inline std::string octstring( long n, int w = 5 ) { return form( "%#0*lo", w, n ); }
352 inline std::string octstring( unsigned long n, int w = 5 ) { return form( "%#0*lo", w, n ); }
353 inline std::string octstring( long long n, int w = 0 ) { return form( "%#0*llo", w, n ); }
354 inline std::string octstring( unsigned long long n, int w = 0 ) { return form( "%#0*llo", w, n ); }
356
357
359
360 template <typename TInt>
361 std::string binstring( TInt val_r )
362 {
363 constexpr unsigned bits = sizeof(TInt)*8;
364 std::string ret( bits, ' ' );
365 TInt bit = 1;
366 for ( unsigned pos = bits; pos > 0; )
367 { --pos; ret[pos] = ((val_r & bit)?'1':'0'); bit = bit<<1; }
368 return ret;
369 }
370
372
381 template<typename TInt>
382 TInt strtonum( const C_Str & str );
383
384 template<>
385 inline short strtonum( const C_Str & str ) { return ::strtol ( str, NULL, 0 ); }
386 template<>
387 inline int strtonum( const C_Str & str ) { return ::strtol ( str, NULL, 0 ); }
388 template<>
389 inline long strtonum( const C_Str & str ) { return ::strtol ( str, NULL, 0 ); }
390 template<>
391 inline long long strtonum( const C_Str & str ) { return ::strtoll ( str, NULL, 0 ); }
392
393 template<>
394 inline unsigned short strtonum( const C_Str & str ) { return ::strtoul ( str, NULL, 0 ); }
395 template<>
396 inline unsigned strtonum( const C_Str & str ) { return ::strtoul ( str, NULL, 0 ); }
397 template<>
398 inline unsigned long strtonum( const C_Str & str ) { return ::strtoul ( str, NULL, 0 ); }
399 template<>
400 inline unsigned long long strtonum( const C_Str & str ) { return ::strtoull( str, NULL, 0 ); }
401
407 template<typename TInt>
408 inline TInt strtonum( const C_Str & str, TInt & i )
409 { return i = strtonum<TInt>( str ); }
411
413
417 bool strToTrue( const C_Str & str );
418
420 bool strToFalse( const C_Str & str );
421
426 inline bool strToBool( const C_Str & str, bool default_r )
427 { return( default_r ? strToFalse( str ) : strToTrue( str ) ); }
428
433 inline bool strToBoolNodefault( const C_Str & str, bool & return_r )
434 {
435 if ( strToTrue( str ) ) return (return_r = true);
436 if ( !strToFalse( str ) ) return (return_r = false);
437 return return_r;
438 }
439
441 TriBool strToTriBool( const C_Str & str );
442
444
448 std::string gsub( const std::string & str_r, const std::string & from_r, const std::string & to_r );
449
452 std::string gsubFun( const std::string & str_r, const std::string & from_r, function<std::string()> to_r );
453
458 std::string & replaceAll( std::string & str_r, const std::string & from_r, const std::string & to_r );
459
462 std::string & replaceAllFun( std::string & str_r, const std::string & from_r, function<std::string()> to_r );
463
476 inline std::string gapify( std::string inp_r, std::string::size_type gap_r = 1, char gapchar = ' ' )
477 {
478 if ( gap_r && inp_r.size() > gap_r )
479 {
480 inp_r.reserve( inp_r.size() + (inp_r.size()-1)/gap_r );
481 for ( std::string::size_type pos = gap_r; pos < inp_r.size(); pos += gap_r+1 )
482 inp_r.insert( pos, 1, gapchar );
483 }
484 return inp_r;
485 }
486
488
493 enum Trim {
494 NO_TRIM = 0x00,
495 L_TRIM = 0x01,
496 R_TRIM = 0x02,
497 TRIM = (L_TRIM|R_TRIM)
498 };
499
500 std::string trim( const std::string & s, const Trim trim_r = TRIM );
501 std::string trim( std::string && s, const Trim trim_r = TRIM );
502
503 inline std::string ltrim( const std::string & s )
504 { return trim( s, L_TRIM ); }
505 inline std::string ltrim( std::string && s )
506 { return trim( std::move(s), L_TRIM ); }
507
508 inline std::string rtrim( const std::string & s )
509 { return trim( s, R_TRIM ); }
510 inline std::string rtrim( std::string && s )
511 { return trim( std::move(s), R_TRIM ); }
513
515
526 template<class TOutputIterator>
527 unsigned split( const C_Str & line_r, TOutputIterator result_r, const C_Str & sepchars_r = " \t", const Trim trim_r = NO_TRIM )
528 {
529 const char * beg = line_r;
530 const char * cur = beg;
531 // skip leading sepchars
532 while ( *cur && ::strchr( sepchars_r, *cur ) )
533 ++cur;
534 unsigned ret = 0;
535 for ( beg = cur; *beg; beg = cur, ++result_r, ++ret )
536 {
537 // skip non sepchars
538 while( *cur && !::strchr( sepchars_r, *cur ) )
539 ++cur;
540 // build string
541 *result_r = trim( std::string( beg, cur-beg ), trim_r );
542 // skip sepchars
543 while ( *cur && ::strchr( sepchars_r, *cur ) )
544 ++cur;
545 }
546 return ret;
547 }
548
549 template<class TOutputIterator>
550 unsigned split( const C_Str & line_r, TOutputIterator result_r, const Trim trim_r )
551 { return split( line_r, result_r, " \t", trim_r ); }
552
553
590 template<class TOutputIterator>
591 unsigned splitEscaped( const C_Str & line_r, TOutputIterator result_r, const C_Str & sepchars_r = " \t", bool withEmpty = false)
592 {
593 const char * beg = line_r;
594 const char * cur = beg;
595 unsigned ret = 0;
596
597 // skip leading sepchars
598 while ( *cur && ::strchr( sepchars_r, *cur ) )
599 {
600 ++cur;
601 if (withEmpty)
602 {
603 *result_r = "";
604 ++ret;
605 }
606 }
607
608 // there were only sepchars in the string
609 if (!*cur && withEmpty)
610 {
611 *result_r = "";
612 return ++ret;
613 }
614
615 // after the leading sepchars
616 enum class Quote { None, Slash, Single, Double, DoubleSlash };
617 std::vector<char> buf;
618 Quote quoting = Quote::None;
619 for ( beg = cur; *beg; beg = cur, ++result_r, ++ret )
620 {
621 // read next value until unquoted sepchar
622 buf.clear();
623 quoting = Quote::None;
624 do {
625 switch ( quoting )
626 {
627 case Quote::None:
628 switch ( *cur )
629 {
630 case '\\': quoting = Quote::Slash; break;
631 case '\'': quoting = Quote::Single; break;
632 case '"': quoting = Quote::Double; break;
633 default: buf.push_back( *cur ); break;
634 }
635 break;
636
637 case Quote::Slash:
638 buf.push_back( *cur );
639 quoting = Quote::None;
640 break;
641
642 case Quote::Single:
643 switch ( *cur )
644 {
645 case '\'': quoting = Quote::None; break;
646 default: buf.push_back( *cur ); break;
647 }
648 break;
649
650 case Quote::Double:
651 switch ( *cur )
652 {
653 case '\"': quoting = Quote::None; break;
654 case '\\': quoting = Quote::DoubleSlash; break;
655 default: buf.push_back( *cur ); break;
656 }
657 break;
658
659 case Quote::DoubleSlash:
660 switch ( *cur )
661 {
662 case '\"': /*fallthrough*/
663 case '\\': buf.push_back( *cur ); break;
664 default:
665 buf.push_back( '\\' );
666 buf.push_back( *cur );
667 break;
668 }
669 quoting = Quote::Double;
670 break;
671 }
672 ++cur;
673 } while ( *cur && ( quoting != Quote::None || !::strchr( sepchars_r, *cur ) ) );
674 *result_r = std::string( buf.begin(), buf.end() );
675
676
677 // skip sepchars
678 if ( *cur && ::strchr( sepchars_r, *cur ) )
679 ++cur;
680 while ( *cur && ::strchr( sepchars_r, *cur ) )
681 {
682 ++cur;
683 if (withEmpty)
684 {
685 *result_r = "";
686 ++ret;
687 }
688 }
689 // the last was a separator => one more field
690 if ( !*cur && withEmpty && ::strchr( sepchars_r, *(cur-1) ) )
691 {
692 *result_r = "";
693 ++ret;
694 }
695 }
696 return ret;
697 }
698
720 template<class TOutputIterator>
721 unsigned splitFields( const C_Str & line_r, TOutputIterator result_r, const C_Str & sepchars_r = ":" )
722 {
723 const char * beg = line_r;
724 const char * cur = beg;
725 unsigned ret = 0;
726 for ( beg = cur; *beg; beg = cur, ++result_r )
727 {
728 // skip non sepchars
729 while( *cur && !::strchr( sepchars_r, *cur ) )
730 {
731 if ( *cur == '\\' && *(cur+1) )
732 ++cur;
733 ++cur;
734 }
735 // build string
736 *result_r = std::string( beg, cur-beg );
737 ++ret;
738 // skip sepchar
739 if ( *cur )
740 {
741 ++cur;
742 if ( ! *cur ) // ending with sepchar
743 {
744 *result_r = std::string(); // add final empty field
745 ++ret;
746 break;
747 }
748 }
749 }
750 return ret;
751 }
752
759 template<class TOutputIterator>
760 unsigned splitFieldsEscaped( const C_Str & line_r, TOutputIterator result_r, const C_Str & sepchars_r = ":" )
761 {
762 return splitEscaped( line_r, result_r, sepchars_r, true /* withEmpty */ );
763 }
764
766
768
771 template <class TIterator>
772 std::string join( TIterator begin, TIterator end, const C_Str & sep_r = " " )
773 {
774 std::string res;
775 for ( TIterator iter = begin; iter != end; ++ iter )
776 {
777 if ( iter != begin )
778 res += sep_r;
779 res += asString(*iter);
780 }
781 return res;
782 }
783
785 template <class TContainer>
786 std::string join( const TContainer & cont_r, const C_Str & sep_r = " " )
787 { return join( cont_r.begin(), cont_r.end(), sep_r ); }
788
793 template <class TIterator>
794 std::string joinEscaped( TIterator begin, TIterator end, const char sep_r = ' ' )
795 {
796 std::vector<char> buf;
797 for ( TIterator iter = begin; iter != end; ++ iter )
798 {
799 if ( iter != begin )
800 buf.push_back( sep_r );
801
802 if ( iter->empty() )
803 {
804 // empty string goes ""
805 buf.push_back( '"' );
806 buf.push_back( '"' );
807 }
808 else
809 {
810 std::string toadd( asString(*iter) );
811 for_( ch, toadd.begin(), toadd.end() )
812 {
813 switch ( *ch )
814 {
815 case '"':
816 case '\'':
817 case '\\':
818 buf.push_back( '\\' );
819 buf.push_back( *ch );
820 break;
821 default:
822 if ( *ch == sep_r )
823 buf.push_back( '\\' );
824 buf.push_back( *ch );
825 }
826 }
827 }
828 }
829 return std::string( buf.begin(), buf.end() );
830 }
832
833
835
841 inline std::ostream & printIndented( std::ostream & str, const std::string & text_r, const std::string & indent_r = " ", unsigned maxWitdh_r = 0 )
842 {
843 if ( maxWitdh_r )
844 {
845 if ( indent_r.size() >= maxWitdh_r )
846 maxWitdh_r = 0; // nonsense: indent larger than line witdh
847 else
848 maxWitdh_r -= indent_r.size();
849 }
850 unsigned width = 0;
851 for ( const char * e = text_r.c_str(), * s = e; *e; s = ++e )
852 {
853 for ( ; *e && *e != '\n'; ++e ) ;/*searching*/
854 width = e-s;
855 if ( maxWitdh_r && width > maxWitdh_r )
856 {
857 // must break line
858 width = maxWitdh_r;
859 for ( e = s+width; e > s && *e != ' '; --e ) ;/*searching*/
860 if ( e > s )
861 width = e-s; // on a ' ', replaced by '\n'
862 else
863 e = s+width-1; // cut line;
864 }
865 str << indent_r;
866 str.write( s, width );
867 str << "\n";
868 if ( !*e ) // on '\0'
869 break;
870 }
871 return str;
872 }
874 inline std::ostream & printIndented( std::ostream & str, const std::string & text_r, unsigned indent_r, char indentch_r = ' ', unsigned maxWitdh_r = 0 )
875 { return printIndented( str, text_r, std::string( indent_r, indentch_r ), maxWitdh_r ); }
877 inline std::ostream & printIndented( std::ostream & str, const std::string & text_r, unsigned indent_r, unsigned maxWitdh_r, char indentch_r = ' ' )
878 { return printIndented( str, text_r, std::string( indent_r, indentch_r ), maxWitdh_r ); }
879
883 inline std::ostream & autoPrefix( std::ostream & str, const std::string & text_r, function<std::string(const char*, const char*)> fnc_r )
884 {
885 for ( const char * e = text_r.c_str(); *e; ++e )
886 {
887 const char * s = e;
888 for ( ; *e && *e != '\n'; ++e ) /*searching*/;
889 str << fnc_r( s, e );
890 str.write( s, e-s );
891 str << "\n";
892 if ( !*e ) // on '\0'
893 break;
894 }
895 return str;
896 }
898 inline std::ostream & autoPrefix0( std::ostream & str, const std::string & text_r, function<std::string()> fnc_r )
899 {
900 auto wrap = [&fnc_r]( const char*, const char* )-> std::string {
901 return fnc_r();
902 };
903 return autoPrefix( str, text_r, wrap );
904 }
906
915 std::string escape( const C_Str & str_r, const char c = ' ' );
916
918 inline void appendEscaped( std::string & str_r, const C_Str & next_r, const char sep_r = ' ' )
919 {
920 if ( ! str_r.empty() )
921 str_r += sep_r;
922 if ( next_r.empty() )
923 str_r += "\"\"";
924 else
925 str_r += escape( next_r, sep_r );
926 }
927
929 std::string bEscape( std::string str_r, const C_Str & special_r );
930
932 std::string rxEscapeStr( std::string str_r );
933
935 std::string rxEscapeGlob( std::string str_r );
936
938
940
942
950 std::string hexencode( const C_Str & str_r );
952 std::string hexdecode( const C_Str & str_r );
954
955
961 std::string toLower( const std::string & s );
962 std::string toLower( std::string && s );
964 inline std::string toLower( const char * s )
965 { return( s ? toLower( std::string(s) ) : std::string() ); }
966
970 std::string toUpper( const std::string & s );
971 std::string toUpper( std::string && s );
973 inline std::string toUpper( const char * s )
974 { return( s ? toUpper( std::string(s) ) : std::string() ); }
976
977
980 inline int compareCI( const C_Str & lhs, const C_Str & rhs )
981 { return ::strcasecmp( lhs, rhs ); }
983
987 inline bool contains( const C_Str & str_r, const C_Str & val_r )
988 { return ::strstr( str_r, val_r ); }
990 inline bool containsCI( const C_Str & str_r, const C_Str & val_r )
991 { return ::strcasestr( str_r, val_r ); }
993
994 std::string stripFirstWord( std::string & line, const bool ltrim_first = true );
995
996 std::string stripLastWord( std::string & line, const bool rtrim_first = true );
997
1001 std::string getline( std::istream & str, bool trim = false );
1002
1006 std::string getline( std::istream & str, const Trim trim_r );
1007
1015 std::string receiveUpTo( std::istream & str, const char delim_r, bool returnDelim_r = false );
1016
1018
1023 inline bool hasPrefix( const C_Str & str_r, const C_Str & prefix_r )
1024 { return( ::strncmp( str_r, prefix_r, prefix_r.size() ) == 0 ); }
1026 inline bool hasPrefixCI( const C_Str & str_r, const C_Str & prefix_r )
1027 { return( ::strncasecmp( str_r, prefix_r, prefix_r.size() ) == 0 ); }
1028
1030 inline std::string stripPrefix( const C_Str & str_r, const C_Str & prefix_r )
1031 { return( hasPrefix( str_r, prefix_r ) ? str_r + prefix_r.size() : str_r.c_str() ); }
1033 inline std::string stripPrefixCI( const C_Str & str_r, const C_Str & prefix_r )
1034 { return( hasPrefixCI( str_r, prefix_r ) ? str_r + prefix_r.size() : str_r.c_str() ); }
1035
1037 inline bool hasSuffix( const C_Str & str_r, const C_Str & suffix_r )
1038 { return( str_r.size() >= suffix_r.size() && ::strncmp( str_r + str_r.size() - suffix_r.size() , suffix_r, suffix_r.size() ) == 0 ); }
1040 inline bool hasSuffixCI( const C_Str & str_r, const C_Str & suffix_r )
1041 { return( str_r.size() >= suffix_r.size() && ::strncasecmp( str_r + str_r.size() - suffix_r.size() , suffix_r, suffix_r.size() ) == 0 ); }
1042
1044 inline std::string stripSuffix( const C_Str & str_r, const C_Str & suffix_r )
1045 {
1046 if ( hasSuffix( str_r, suffix_r ) )
1047 return std::string( str_r, str_r.size() - suffix_r.size() );
1048 return str_r.c_str();
1049 }
1051 inline std::string stripSuffixCI( const C_Str & str_r, const C_Str & suffix_r )
1052 {
1053 if ( hasSuffixCI( str_r, suffix_r ) )
1054 return std::string( str_r, str_r.size() - suffix_r.size() );
1055 return str_r.c_str();
1056 }
1057
1059 inline std::string::size_type commonPrefix( const C_Str & lhs, const C_Str & rhs )
1060 {
1061 const char * lp = lhs.c_str();
1062 const char * rp = rhs.c_str();
1063 std::string::size_type ret = 0;
1064 while ( *lp == *rp && *lp != '\0' )
1065 { ++lp, ++rp, ++ret; }
1066 return ret;
1067 }
1069 inline std::string::size_type commonPrefixCI( const C_Str & lhs, const C_Str & rhs )
1070 {
1071 const char * lp = lhs.c_str();
1072 const char * rp = rhs.c_str();
1073 std::string::size_type ret = 0;
1074 while ( tolower(*lp) == tolower(*rp) && *lp != '\0' )
1075 { ++lp, ++rp, ++ret; }
1076 return ret;
1077 }
1078
1079
1081 inline bool startsWith( const C_Str & str_r, const C_Str & prefix_r )
1082 { return hasPrefix( str_r, prefix_r ); }
1084 inline bool startsWithCI( const C_Str & str_r, const C_Str & prefix_r )
1085 { return hasPrefixCI( str_r, prefix_r ); }
1086
1088 inline bool endsWith( const C_Str & str_r, const C_Str & prefix_r )
1089 { return hasSuffix( str_r, prefix_r ); }
1091 inline bool endsWithCI( const C_Str & str_r, const C_Str & prefix_r )
1092 { return hasSuffixCI( str_r, prefix_r ); }
1094 } // namespace str
1096
1097 // drag into zypp:: namespace
1098 using str::asString;
1099
1100} // namespace zypp
1102#endif // ZYPP_BASE_STRING_H
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
Definition: Easy.h:28
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:121
size_type size() const
Definition: String.h:105
bool empty() const
Definition: String.h:104
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 * c_str() const
Definition: String.h:113
const char *const _val
Definition: String.h:116
C_Str(const char *c_str_r)
Definition: String.h:98
bool isNull() const
Definition: String.h:103
std::string::size_type size_type
Definition: String.h:93
size_type _sze
Definition: String.h:117
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:345
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:1059
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:493
@ NO_TRIM
Definition: String.h:494
@ R_TRIM
Definition: String.h:496
@ TRIM
Definition: String.h:497
@ L_TRIM
Definition: String.h:495
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:794
std::string stripPrefixCI(const C_Str &str_r, const C_Str &prefix_r)
Definition: String.h:1033
bool hasSuffix(const C_Str &str_r, const C_Str &suffix_r)
Return whether str_r has suffix suffix_r.
Definition: String.h:1037
std::ostream & autoPrefix0(std::ostream &str, const std::string &text_r, function< std::string()> fnc_r)
Definition: String.h:898
unsigned splitFields(const C_Str &line_r, TOutputIterator result_r, const C_Str &sepchars_r=":")
Split line_r into fields.
Definition: String.h:721
std::string numstring(char n, int w=0)
Definition: String.h:286
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:361
bool strToFalse(const C_Str &str)
Return false if str is 0, false, no, off, never.
Definition: String.cc:81
std::string::size_type commonPrefixCI(const C_Str &lhs, const C_Str &rhs)
Definition: String.h:1069
const std::string & asString(const std::string &t)
Global asString() that works with std::string too.
Definition: String.h:136
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:1051
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:918
bool hasPrefix(const C_Str &str_r, const C_Str &prefix_r)
Return whether str_r has prefix prefix_r.
Definition: String.h:1023
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:760
bool startsWith(const C_Str &str_r, const C_Str &prefix_r)
alias for hasPrefix
Definition: String.h:1081
bool endsWith(const C_Str &str_r, const C_Str &prefix_r)
alias for hasSuffix
Definition: String.h:1088
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:1044
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:508
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:772
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:503
std::string form(const char *format,...) __attribute__((format(printf
Printf style construction of std::string.
Definition: String.cc:36
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:841
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:426
bool hasPrefixCI(const C_Str &str_r, const C_Str &prefix_r)
Definition: String.h:1026
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:1030
std::string hexstring(char n, int w=4)
Definition: String.h:321
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:527
TInt strtonum(const C_Str &str)
Parsing numbers from string.
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:990
bool contains(const C_Str &str_r, const C_Str &val_r)
Locate substring case sensitive.
Definition: String.h:987
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:883
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:591
bool endsWithCI(const C_Str &str_r, const C_Str &prefix_r)
Definition: String.h:1091
bool hasSuffixCI(const C_Str &str_r, const C_Str &suffix_r)
Definition: String.h:1040
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:433
int compareCI(const C_Str &lhs, const C_Str &rhs)
Definition: String.h:980
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:476
bool startsWithCI(const C_Str &str_r, const C_Str &prefix_r)
Definition: String.h:1084
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:2
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
Convenient building of std::string with boost::format.
Definition: String.h:250
std::string asString() const
Definition: String.h:259
std::ostream & operator<<(std::ostream &str, const Format &obj)
Stream output.
Definition: String.h:270
Format(const std::string &format_r)
Definition: String.h:252
std::string str() const
Definition: String.h:260
boost::format & fmter()
Definition: String.h:263
Format & operator%(Tp &&arg)
Definition: String.h:255
boost::format _fmter
Definition: String.h:266
const boost::format & fmter() const
Definition: String.h:262
Assert free called for allocated char *.
Definition: String.h:188
std::string asString() const
Definition: String.h:192
Convenient building of std::string via std::ostringstream Basically a std::ostringstream autoconverti...
Definition: String.h:209
std::ostream & operator<<(std::ostream &str, const Str &obj)
Stream output.
Definition: String.h:231
Str & operator<<(Tp &&val)
Definition: String.h:211
std::ostream & stream()
Definition: String.h:222
std::string asString() const
Definition: String.h:218
void clear()
Definition: String.h:224
std::string str() const
Definition: String.h:219
const std::ostream & stream() const
Definition: String.h:221
std::ostringstream _str
Definition: String.h:227
Str & operator<<(std::ostream &(*iomanip)(std::ostream &))
Definition: String.h:214