12#ifndef ZYPP_BASE_STRING_H
13#define ZYPP_BASE_STRING_H
22#include <boost/format.hpp>
23#include <boost/utility/string_ref.hpp>
42 {
return val_r.asUserString(); }
102#ifdef __cpp_lib_string_view
103 C_Str(
const std::string_view & str_r ) :
_val( str_r.data() ),
_sze( str_r.
size() ) {}
111 if (
_sze == std::string::npos )
116 operator const char *()
const {
return c_str(); }
140 inline const std::string &
asString(
const std::string & t )
144 {
return std::move(t); }
147 {
return t ==
nullptr ? std::string() : t; }
150 {
return t ==
nullptr ? std::string() : t; }
154 {
return t.asString(); }
158 {
return p->asString(); }
162 {
return p->asString(); }
166 {
return t ?
"true" :
"false"; }
170 std::string
form(
const char * format, ... )
197 {
return _buf ? std::string(
_buf) : std::string(); }
221 operator std::string()
const {
return _str.str(); }
223 std::string
str()
const {
return _str.str(); }
236 {
return str << obj.
str(); }
260 {
_fmter % std::forward<Tp>(arg);
return *
this; }
262 operator std::string()
const {
return _fmter.str(); }
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 ); }
310 template<>
inline std::string
asString(
const unsigned long long & t ) {
return numstring( t ); }
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 ); }
337#ifdef __cpp_lib_string_view
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))
346 template <
typename BArr = std::
string>
347 BArr hexstringToByteArray ( std::string_view
str ) {
349 for ( std::string::size_type i = 0; i <
str.length(); i+=2 )
351 int v = hexCharToByte(
str[i]);
355 v = hexCharToByte(str[i+1]);
358 bytes.back() = (bytes.back() << 4) | v;
369 template<
typename T=u
int32_t>
373 constexpr auto l =
sizeof(T) * 2;
374 if ( hexChar.length() == 0 || hexChar.length() % 2 || hexChar.length() > l )
379 for (
const auto c : hexChar ) {
380 const char b = hexCharToByte(c);
383 cp = (cp << shift) |
b;
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 ); }
434 template <
typename TInt>
437 constexpr unsigned bits =
sizeof(TInt)*8;
438 std::string ret( bits,
' ' );
440 for (
unsigned pos = bits; pos > 0; )
441 { --pos; ret[pos] = ((val_r &
bit)?
'1':
'0');
bit =
bit<<1; }
455 template<
typename TInt>
481 template<
typename TInt>
522 std::string
gsub(
const std::string & str_r,
const std::string & from_r,
const std::string & to_r )
ZYPP_API;
526 std::string
gsubFun(
const std::string & str_r,
const std::string & from_r, function<std::string()> to_r )
ZYPP_API;
532 std::string &
replaceAll( std::string & str_r,
const std::string & from_r,
const std::string & to_r )
ZYPP_API;
536 std::string &
replaceAllFun( std::string & str_r,
const std::string & from_r,
const function<std::string()>& to_r )
ZYPP_API;
550 inline std::string
gapify( std::string inp_r, std::string::size_type gap_r = 1,
char gapchar =
' ' )
552 if ( gap_r && inp_r.size() > gap_r )
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 );
577 inline std::string
ltrim(
const std::string & s )
579 inline std::string
ltrim( std::string && s )
582 inline std::string
rtrim(
const std::string & s )
584 inline std::string
rtrim( std::string && s )
601 template<
class TOutputIterator>
604 const char * beg = line_r;
605 const char * cur = beg;
607 while ( *cur && ::strchr( sepchars_r, *cur ) )
610 for ( beg = cur; *beg; beg = cur, ++result_r, ++ret )
613 while( *cur && !::strchr( sepchars_r, *cur ) )
616 *result_r =
trim( std::string( beg, cur-beg ), trim_r );
618 while ( *cur && ::strchr( sepchars_r, *cur ) )
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 ); }
665 template<
class TOutputIterator>
666 unsigned splitEscaped(
const C_Str & line_r, TOutputIterator result_r,
const C_Str & sepchars_r =
" \t",
bool withEmpty =
false)
668 const char * beg = line_r;
669 const char * cur = beg;
673 while ( *cur && ::strchr( sepchars_r, *cur ) )
684 if (!*cur && withEmpty)
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 )
698 quoting = Quote::None;
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;
713 buf.push_back( *cur );
714 quoting = Quote::None;
720 case '\'': quoting = Quote::None;
break;
721 default: buf.push_back( *cur );
break;
728 case '\"': quoting = Quote::None;
break;
729 case '\\': quoting = Quote::DoubleSlash;
break;
730 default: buf.push_back( *cur );
break;
734 case Quote::DoubleSlash:
738 case '\\': buf.push_back( *cur );
break;
740 buf.push_back(
'\\' );
741 buf.push_back( *cur );
744 quoting = Quote::Double;
748 }
while ( *cur && ( quoting != Quote::None || !::strchr( sepchars_r, *cur ) ) );
749 *result_r = std::string( buf.begin(), buf.end() );
753 if ( *cur && ::strchr( sepchars_r, *cur ) )
755 while ( *cur && ::strchr( sepchars_r, *cur ) )
765 if ( !*cur && withEmpty && ::strchr( sepchars_r, *(cur-1) ) )
795 template<
class TOutputIterator>
796 unsigned splitFields(
const C_Str & line_r, TOutputIterator result_r,
const C_Str & sepchars_r =
":" )
798 const char * beg = line_r;
799 const char * cur = beg;
801 for ( beg = cur; *beg; beg = cur, ++result_r )
804 while( *cur && !::strchr( sepchars_r, *cur ) )
806 if ( *cur ==
'\\' && *(cur+1) )
811 *result_r = std::string( beg, cur-beg );
819 *result_r = std::string();
834 template<
class TOutputIterator>
837 return splitEscaped( line_r, result_r, sepchars_r,
true );
846 template <
class TIterator>
847 std::string
join( TIterator begin, TIterator end,
const C_Str & sep_r =
" " )
850 for ( TIterator iter = begin; iter != end; ++ iter )
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 ); }
868 template <
class TIterator>
869 std::string
joinEscaped( TIterator begin, TIterator end,
const char sep_r =
' ' )
871 std::vector<char> buf;
872 for ( TIterator iter = begin; iter != end; ++ iter )
875 buf.push_back( sep_r );
880 buf.push_back(
'"' );
881 buf.push_back(
'"' );
885 std::string toadd(
asString(*iter) );
886 for (
const char ch : toadd )
893 buf.push_back(
'\\' );
898 buf.push_back(
'\\' );
904 return std::string( buf.begin(), buf.end() );
916 inline std::ostream &
printIndented( std::ostream &
str,
const std::string & text_r,
const std::string & indent_r =
" ",
unsigned maxWitdh_r = 0 )
920 if ( indent_r.size() >= maxWitdh_r )
923 maxWitdh_r -= indent_r.size();
926 for (
const char * e = text_r.c_str(), * s = e; *e; s = ++e )
928 for ( ; *e && *e !=
'\n'; ++e ) ;
929 unsigned width = e-s;
930 if ( maxWitdh_r && width > maxWitdh_r )
934 for ( e = s+width; e > s && *e !=
' '; --e ) ;
941 str.write( s, width );
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 ); }
958 inline std::ostream &
autoPrefix( std::ostream &
str,
const std::string & text_r,
const function<std::string(
const char*,
const char*)>& fnc_r )
960 for (
const char * e = text_r.c_str(); *e; ++e )
963 for ( ; *e && *e !=
'\n'; ++e ) ;
964 str << fnc_r( s, e );
973 inline std::ostream &
autoPrefix0( std::ostream &
str,
const std::string & text_r, function<std::string()> fnc_r )
975 auto wrap = [&fnc_r](
const char*,
const char* )-> std::string {
995 if ( ! str_r.
empty() )
997 if ( next_r.empty() )
1000 str_r +=
escape( next_r, sep_r );
1039 inline std::string
toLower(
const char * s )
1040 {
return( s ?
toLower( std::string(s) ) : std::string() ); }
1048 inline std::string
toUpper(
const char * s )
1049 {
return( s ?
toUpper( std::string(s) ) : std::string() ); }
1056 { return ::strcasecmp( lhs, rhs ); }
1063 { return ::strstr( str_r, val_r ); }
1066 { return ::strcasestr( str_r, val_r ); }
1099 {
return( ::strncmp( str_r, prefix_r, prefix_r.size() ) == 0 ); }
1102 {
return( ::strncasecmp( str_r, prefix_r, prefix_r.
size() ) == 0 ); }
1106 {
return(
hasPrefix( str_r, prefix_r ) ? str_r + prefix_r.
size() : str_r.
c_str() ); }
1113 {
return( str_r.
size() >= suffix_r.
size() && ::strncmp( str_r + str_r.
size() - suffix_r.
size() , suffix_r, suffix_r.
size() ) == 0 ); }
1116 {
return( str_r.
size() >= suffix_r.
size() && ::strncasecmp( str_r + str_r.
size() - suffix_r.
size() , suffix_r, suffix_r.
size() ) == 0 ); }
1122 return std::string( str_r, str_r.
size() - suffix_r.
size() );
1123 return str_r.
c_str();
1129 return std::string( str_r, str_r.
size() - suffix_r.
size() );
1130 return str_r.
c_str();
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; }
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; }
1157 {
return hasPrefix( str_r, prefix_r ); }
1164 {
return hasSuffix( str_r, prefix_r ); }
Convenience char* constructible from std::string and char*, it maps (char*)0 to an empty string.
std::ostream & operator<<(std::ostream &str, const C_Str &obj)
Stream output.
C_Str(const std::string &str_r)
C_Str(const boost::string_ref &str_r)
const char * c_str() const
C_Str(const char *c_str_r)
std::string::size_type size_type
boost::logic::tribool TriBool
3-state boolean logic (true, false and indeterminate).
typename enable_if< B, T >::type enable_if_t
String related utilities and Regular expression matching.
std::string octstring(char n, int w=4)
std::string stripLastWord(std::string &line, const bool rtrim_first)
std::string hexdecode(const C_Str &str_r)
Decode hexencoded XX sequences.
std::string::size_type commonPrefix(const C_Str &lhs, const C_Str &rhs)
Return size of the common prefix of lhs and rhs.
Trim
To define how to trim.
std::string hexencode(const C_Str &str_r)
Encode all characters other than [a-zA-Z0-9] as XX.
std::string joinEscaped(TIterator begin, TIterator end, const char sep_r=' ')
Join strings using separator sep_r, quoting or escaping the values.
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).
std::string stripPrefixCI(const C_Str &str_r, const C_Str &prefix_r)
bool hasSuffix(const C_Str &str_r, const C_Str &suffix_r)
Return whether str_r has suffix suffix_r.
std::string hexCodepointToUtf8String(std::string_view hexChar)
std::ostream & autoPrefix0(std::ostream &str, const std::string &text_r, function< std::string()> fnc_r)
unsigned splitFields(const C_Str &line_r, TOutputIterator result_r, const C_Str &sepchars_r=":")
Split line_r into fields.
std::string numstring(char n, int w=0)
std::string gsubFun(const std::string &str_r, const std::string &from_r, function< std::string()> to_r)
bool strToTrue(const C_Str &str)
Parsing boolean from string.
std::string binstring(TInt val_r)
String representation of number as bit-string with leading '0's.
TriBool strToTriBool(const C_Str &str)
Parse str into a bool if it's a legal true or false string; else indeterminate.
std::string::size_type commonPrefixCI(const C_Str &lhs, const C_Str &rhs)
std::string codepointToUtf8String(uint32_t unichar)
std::string rxEscapeGlob(std::string str_r)
Escape GLOB str_r for use in a regex (not anchored by "^" or "$").
const std::string & asString(const std::string &t)
Global asString() that works with std::string too.
std::string stripFirstWord(std::string &line, const bool ltrim_first)
std::string stripSuffixCI(const C_Str &str_r, const C_Str &suffix_r)
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*,...
std::string escape(const C_Str &str_r, const char sep_r)
Escape desired character c using a backslash.
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.
bool hasPrefix(const C_Str &str_r, const C_Str &prefix_r)
Return whether str_r has prefix prefix_r.
std::string toLower(const std::string &s)
Return lowercase version of s.
unsigned splitFieldsEscaped(const C_Str &line_r, TOutputIterator result_r, const C_Str &sepchars_r=":")
Split line_r into fields handling also escaped separators.
bool startsWith(const C_Str &str_r, const C_Str &prefix_r)
alias for hasPrefix
bool endsWith(const C_Str &str_r, const C_Str &prefix_r)
alias for hasSuffix
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.
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,...
std::string rtrim(const std::string &s)
std::string join(TIterator begin, TIterator end, const C_Str &sep_r=" ")
Join strings using separator sep_r (defaults to BLANK).
std::string strerror(int errno_r)
Return string describing the error_r code.
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.
std::string toUpper(const std::string &s)
Return uppercase version of s.
std::string ltrim(const std::string &s)
std::string form(const char *format,...) __attribute__((format(printf
Printf style construction of std::string.
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.
bool strToBool(const C_Str &str, bool default_r)
Parse str into a bool depending on the default value.
std::string bEscape(std::string str_r, const C_Str &special_r)
Return str_r with '\'-escaped chars occurring in special_r (and '\').
bool hasPrefixCI(const C_Str &str_r, const C_Str &prefix_r)
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.
std::string & replaceAllFun(std::string &str_r, const std::string &from_r, const function< std::string()> &to_r)
std::string rxEscapeStr(std::string str_r)
Escape plain STRING str_r for use in a regex (not anchored by "^" or "$").
std::string getline(std::istream &str, const Trim trim_r)
Return stream content up to (but not returning) the next newline.
bool validateUtf8(std::string_view str)
std::string hexstring(char n, int w=4)
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.
TInt strtonum(const C_Str &str)
Parsing numbers from string.
bool containsCI(const C_Str &str_r, const C_Str &val_r)
Locate substring case insensitive.
bool contains(const C_Str &str_r, const C_Str &val_r)
Locate substring case sensitive.
bool strToFalse(const C_Str &str)
Return false if str is 0, false, no, off, never.
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.
bool endsWithCI(const C_Str &str_r, const C_Str &prefix_r)
bool hasSuffixCI(const C_Str &str_r, const C_Str &suffix_r)
std::string trim(const std::string &s, const Trim trim_r)
bool strToBoolNodefault(const C_Str &str, bool &return_r)
Parse str into a bool if it's a legal true or false string.
int compareCI(const C_Str &lhs, const C_Str &rhs)
std::string gapify(std::string inp_r, std::string::size_type gap_r=1, char gapchar=' ')
Enhance readability: insert gaps at regular distance.
bool startsWithCI(const C_Str &str_r, const C_Str &prefix_r)
Easy-to use interface to the ZYPP dependency resolver.
std::string asUserString(VendorSupportOption opt)
converts the support option to a name intended to be printed to the user.
const Arch Arch_armv7hnl Arch_armv7nhl ZYPP_API
std::string asString() const
Convenient building of std::string via std::ostringstream Basically a std::ostringstream autoconverti...
std::ostream & operator<<(std::ostream &str, const Str &obj)
Stream output.
Str & operator<<(Tp &&val)
std::string asString() const
const std::ostream & stream() const
Str & operator<<(std::ostream &(*iomanip)(std::ostream &))