/* The software in this package is distributed under the GNU General Public License version 2 (with a special exception described below). A copy of GNU General Public License (GPL) is included in this distribution, in the file COPYING.GPL. As a special exception, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other works to produce a work based on this file, this file does not by itself cause the resulting work to be covered by the GNU General Public License. However the source code for this file must still be made available in accordance with section (3) of the GNU General Public License. This exception does not invalidate any other reasons why a work based on this file might be covered by the GNU General Public License. */ /** @file * @brief collection of string tools (/ functions). * * contains a collection of miscellaneous functions for dealing with strings. * * some functions (like trim, lower case, upper case ...) are available in two versions: * - a modifying one (suffix "Mod") which modifies the given string argument in place. * - a non modifying one which take a constant string reference and returns a new string. * . * * * (c) Copyright 2007-2008 by Intra2net AG */ #ifndef __STRINGFUNC_HXX #define __STRINGFUNC_HXX #include #include #include #include #include #include #include #include #include namespace I2n { /* ** some useful constants: */ extern const std::string Whitespaces; extern const std::string LineEndings; /* ** predicates: */ bool has_prefix(const std::string& str, const std::string& prefix); bool has_suffix(const std::string& str, const std::string& suffix); /* ** tool functions(modifying): */ std::string trim_mod(std::string& str, const std::string& charlist = Whitespaces); std::string chomp_mod(std::string& str, const std::string& what= LineEndings ); std::string to_lower_mod(std::string& str); std::string to_upper_mod(std::string& str); /* ** tool functions (not modifying): */ std::string trim(const std::string& str, const std::string& charlist = Whitespaces); std::string chomp(const std::string& str, const std::string& what= LineEndings ); std::string to_lower(const std::string& str); std::string to_upper(const std::string& str); std::string remove_suffix(const std::string& str, const std::string& suffix); std::string remove_prefix(const std::string& str, const std::string& prefix); /* ** split and join: */ bool pair_split( const std::string& str, std::string& key, std::string& value, char delimiter = '='); void split_string( const std::string& str, std::list< std::string >& result, const std::string& delimiter= "\n", bool omit_empty= false, const std::string& trim_list= std::string() ); void split_string( const std::string& str, std::vector< std::string >& result, const std::string& delimiter= "\n", bool omit_empty= false, const std::string& trim_list= std::string() ); std::list< std::string > split_string( const std::string& str, const std::string& delimiter = "\n", bool omit_empty= false, const std::string& trim_list= std::string() ); struct concatenator { std::string delim; concatenator (const std::string &delim) : delim (delim) { } inline std::string operator() (const std::string &acc, const std::string &elt) const { return acc + delim + elt; } }; template std::string join_string ( Iter first, Iter last, const std::string &delimiter = "\n" ) { if (first == last) { return ""; } const std::string &init = *first++; if (first == last) { return init; } return std::accumulate (first, last, init, concatenator (delimiter)); } /** * @brief joins a container of strings into a single string. * * This funtion is (basically) the reverse operation of @a split_string. * * @param parts the container of strings. * @param delimiter the delimiter to insert between the strings. * @return the joined string. */ template inline std::string join_string( const Cont& parts, const std::string& delimiter = "\n" ) { return join_string (parts.begin (), parts.end (), delimiter); } std::string join_string( const char *const parts [], const std::string& delimiter = "\n" ); /* ** conversions: */ std::string convert_binary_to_hex(const std::string&str, bool upper_case_digits= false); std::string convert_hex_to_binary(const std::string& str) throw(std::runtime_error); /* ** "type conversions": */ /** * convert a datatype @a T to a string via string stream. * * This will not report trouble in conversion; for example: * string_to("christian") * will return 0 and not throw an error. * Use boost::lexical_cast(string) to get error-checked results. * * @param s the string which should be converted to @a T. * @return the value of type T. */ template< class T > T string_to(const std::string& s) { std::istringstream istr(s); T result; istr >> result; return result; } // eo string_to(const std::string&) /** * convert a datatype @a T to a string via string stream. * * @param s the string which should be converted to @a T. * @param result the resulting value of type @a T. * @return @a true iff the internal string stream was EOF after the conversion. * * @attention: does not return if the conversion was successful. So check for empty strings before. */ template< class T > bool string_to(const std::string& s, T& result) { std::istringstream istr(s); istr >> result; return istr.eof(); } // eo string_to(const std::string&) /** * convert string in hexadecimal notation to a datatype @a T * supports strings with and without "0x" notation, e.g. 0xff and FF are both valid * * @param s the hex string which should be converted to @a T. * @return the value of type T. */ template< class T > T hex_string_to(const std::string& s) { std::istringstream istr(s); T result; istr >> std::hex >> result; return result; } // eo string_to(const std::string&) /** * convert string in hexadecimal notation to a datatype @a T * supports strings with and without "0x" notation, e.g. 0xff and FF are both valid * * @param s the hex string which should be converted to @a T. * @param result the resulting value of type @a T. * @return @a true iff the internal string stream was EOF after the conversion. * * @attention: does not return if the conversion was successful. So check for empty strings before. */ template< class T > bool hex_string_to(const std::string& s, T& result) { std::istringstream istr(s); istr >> std::hex >> result; return istr.eof(); } // eo string_to(const std::string&) /** * convert a string to another datatype @a T via string stream. * * @param v the value (of type @a T) which should be converted to a string. * @return the resulting string. */ template< class T > std::string to_string(const T& v) { std::ostringstream ostr; ostr << v; return ostr.str(); } // eo to_string(const T&) /** * Create a string with types shortened in texts describing C++ types * * for example: std::list > * --> std::list * * and std::basic_string, std::allocator > * --> std::string */ std::string shorten_stl_types(const std::string &input); std::string base64_encode(const std::string &input, bool one_line=true); std::string base64_decode(const std::string &input, bool one_line=true); } // eo namespace I2n #if 0 std::string to_lower(const std::string &src); std::string to_upper(const std::string &src); #else // compatibility: import lower/upper funcs from I2n: using I2n::to_lower; using I2n::to_upper; #endif enum UnitBase { UnitBase1000, // SI decimal, composed by multiples of 1000 (KB, MB, etc.) UnitBase1024 // IEC binary, composed by multiples of 1024 (KiB, MiB, etc. ) }; enum UnitFormat { ShortUnitFormat, // B, KB, MB, ... LongUnitFormat // Byte, KByte, MByte, ... }; std::string nice_unit_format( const int64_t input, const UnitFormat format = ShortUnitFormat, const UnitBase base = UnitBase1024 ); std::string nice_unit_format( const double input, const UnitFormat format = ShortUnitFormat, const UnitBase base = UnitBase1024 ); bool replace_all(std::string &base, const std::string *ist, const std::string *soll); bool replace_all(std::string &base, const char *ist, const char *soll); bool replace_all(std::string &base, const char *ist, const std::string *soll); bool replace_all(std::string &base, const std::string &ist, const char *soll); bool replace_all(std::string &base, const std::string &ist, const std::string &soll); std::string iso_to_utf8(const std::string& isostring); std::string utf8_to_iso(const std::string& utf8string); std::string utf7imap_to_utf8(const std::string &utf7imapstring); std::string utf8_to_utf7imap(const std::string &utf8string); std::string strip_html_tags(const std::string &input); std::string smart_html_entities(const std::string &input); std::string html_entities(std::string str); std::string html_entities_to_console(std::string str); inline std::string html_entities_iso (const std::string &str) { return html_entities (iso_to_utf8 (str)); } typedef std::pair CommentZone; std::vector find_html_comments(const std::string &str); void remove_html_comments(std::string &str); void remove_html_comments(std::string &str, const std::vector &comments); std::string sanitize_for_logging(const std::string &str, const char replace_with='?'); std::string escape(const std::string &s); std::string descape(const std::string &s, int startpos, int &endpos); inline std::string descape(const std::string &s) { int endpos; return descape(s,0,endpos); } std::string escape_shellarg(const std::string &input); #endif