5d3455cfcb83b91f58630207e34ec24cd6a19e72
[libi2ncommon] / src / stringfunc.hxx
1 /*
2 The software in this package is distributed under the GNU General
3 Public License version 2 (with a special exception described below).
4
5 A copy of GNU General Public License (GPL) is included in this distribution,
6 in the file COPYING.GPL.
7
8 As a special exception, if other files instantiate templates or use macros
9 or inline functions from this file, or you compile this file and link it
10 with other works to produce a work based on this file, this file
11 does not by itself cause the resulting work to be covered
12 by the GNU General Public License.
13
14 However the source code for this file must still be made available
15 in accordance with section (3) of the GNU General Public License.
16
17 This exception does not invalidate any other reasons why a work based
18 on this file might be covered by the GNU General Public License.
19 */
20 /** @file
21  * @brief collection of string tools (/ functions).
22  *
23  * contains a collection of miscellaneous functions for dealing with strings.
24  *
25  * some functions (like trim, lower case, upper case ...) are available in two versions:
26  * - a modifying one (suffix "Mod") which modifies the given string argument in place.
27  * - a non modifying one which take a constant string reference and returns a new string.
28  * .
29  *
30  *
31  * (c) Copyright 2007-2008 by Intra2net AG
32  */
33
34 #ifndef __STRINGFUNC_HXX
35 #define __STRINGFUNC_HXX
36
37 #include <list>
38 #include <vector>
39 #include <string>
40 #include <sstream>
41 #include <stdexcept>
42 #include <sys/types.h>
43
44 namespace I2n
45 {
46
47 /*
48 ** some useful constants:
49 */
50
51 extern const std::string Whitespaces;
52 extern const std::string LineEndings;
53
54
55 /*
56 ** predicates:
57 */
58
59
60 bool has_prefix(const std::string& str, const std::string& prefix);
61
62 bool has_suffix(const std::string& str, const std::string& suffix);
63
64
65 /*
66 ** tool functions(modifying):
67 */
68
69 std::string trim_mod(std::string& str, const std::string& charlist = Whitespaces);
70
71 std::string chomp_mod(std::string& str, const std::string& what= LineEndings );
72
73 std::string to_lower_mod(std::string& str);
74
75 std::string to_upper_mod(std::string& str);
76
77
78 /*
79 ** tool functions (not modifying):
80 */
81
82 std::string trim(const std::string& str, const std::string& charlist = Whitespaces);
83
84 std::string chomp(const std::string& str, const std::string& what= LineEndings );
85
86 std::string to_lower(const std::string& str);
87
88 std::string to_upper(const std::string& str);
89
90
91 std::string remove_suffix(const std::string& str, const std::string& suffix);
92
93 std::string remove_prefix(const std::string& str, const std::string& prefix);
94
95
96
97 /*
98 ** split and join:
99 */
100
101
102 bool pair_split(
103    const std::string& str,
104    std::string& key,
105    std::string& value,
106    char delimiter = '=');
107
108
109 void split_string(
110    const std::string& str,
111    std::list< std::string >& result,
112    const std::string& delimiter= "\n",
113    bool omit_empty= false,
114    const std::string& trim_list= std::string()
115 );
116
117 std::list< std::string > split_string(
118    const std::string& str,
119    const std::string& delimiter = "\n",
120    bool omit_empty= false,
121    const std::string& trim_list= std::string()
122 );
123
124
125 std::string join_string(
126    const std::list< std::string >& parts,
127    const std::string& delimiter = "\n"
128 );
129
130 std::string join_string(
131    const std::vector< std::string >& parts,
132    const std::string& delimiter = "\n"
133 );
134
135
136 /*
137 ** conversions:
138 */
139
140
141 std::string convert_binary_to_hex(const std::string&str, bool upper_case_digits= false);
142
143 std::string convert_hex_to_binary(const std::string& str) throw(std::runtime_error);
144
145
146 /*
147 ** "type conversions":
148 */
149
150
151 /**
152  * convert a datatype @a T to a string via string stream.
153  *
154  * This will not report trouble in conversion; for example:
155  *     string_to<int>("christian")
156  * will return 0 and not throw an error.
157  * Use boost::lexical_cast<T>(string) to get error-checked results.
158  *
159  * @param s the string which should be converted to @a T.
160  * @return the value of type T.
161  */
162 template<
163 class T
164 >
165 T string_to(const std::string& s)
166 {
167    std::istringstream istr(s);
168    T result;
169    istr >> result;
170    return result;
171 } // eo string_to(const std::string&)
172
173
174 /**
175  * convert a datatype @a T to a string via string stream.
176  *
177  * @param s the string which should be converted to @a T.
178  * @param result the resulting value of type @a T.
179  * @return @a true iff the internal string stream was EOF after the conversion.
180  *
181  * @attention: does not return if the conversion was successful. So check for empty strings before.
182  */
183 template<
184 class T
185 >
186 bool string_to(const std::string& s, T& result)
187 {
188    std::istringstream istr(s);
189    istr >> result;
190    return istr.eof();
191 } // eo string_to(const std::string&)
192
193
194 /**
195  * convert string in hexadecimal notation to a datatype @a T
196  * supports strings with and without "0x" notation, e.g. 0xff and FF are both valid
197  * 
198  * @param s the hex string which should be converted to @a T.
199  * @return the value of type T.
200  */
201 template<
202 class T
203 >
204 T hex_string_to(const std::string& s)
205 {
206    std::istringstream istr(s);
207    T result;
208    istr >> std::hex >> result;
209    return result;
210 } // eo string_to(const std::string&)
211
212
213 /**
214  * convert string in hexadecimal notation to a datatype @a T
215  * supports strings with and without "0x" notation, e.g. 0xff and FF are both valid
216  *
217  * @param s the hex string which should be converted to @a T.
218  * @param result the resulting value of type @a T.
219  * @return @a true iff the internal string stream was EOF after the conversion.
220  *
221  * @attention: does not return if the conversion was successful. So check for empty strings before.
222  */
223 template<
224 class T
225 >
226 bool hex_string_to(const std::string& s, T& result)
227 {
228    std::istringstream istr(s);
229    istr >> std::hex >> result;
230    return istr.eof();
231 } // eo string_to(const std::string&)
232
233
234 /**
235  * convert a string to another datatype @a T via string stream.
236  *
237  * @param v the value (of type @a T) which should be converted to a string.
238  * @return the resulting string.
239  */
240 template<
241 class T
242 >
243 std::string to_string(const T& v)
244 {
245    std::ostringstream ostr;
246    ostr << v;
247    return ostr.str();
248 } // eo to_string(const T&)
249
250
251 } // eo namespace I2n
252
253
254 #if 0
255 std::string to_lower(const std::string &src);
256 std::string to_upper(const std::string &src);
257 #else
258 // compatibility: import lower/upper funcs from I2n:
259 using I2n::to_lower;
260 using I2n::to_upper;
261 #endif
262
263
264 enum UnitBase {
265     UnitBase1000, // SI decimal, composed by multiples of 1000 (KB, MB, etc.)
266     UnitBase1024 // IEC binary, composed by multiples of 1024 (KiB, MiB, etc. )
267 };
268
269 enum UnitFormat {
270     ShortUnitFormat, // B, KB, MB, ...
271     LongUnitFormat // Byte, KByte, MByte, ...
272 };
273
274 std::string nice_unit_format(
275         const int64_t input,
276         const UnitFormat format = ShortUnitFormat,
277         const UnitBase base = UnitBase1024
278 );
279
280 std::string nice_unit_format(
281         const double input,
282         const UnitFormat format = ShortUnitFormat,
283         const UnitBase base = UnitBase1024
284 );
285
286 bool replace_all(std::string &base, const std::string *ist, const std::string *soll);
287 bool replace_all(std::string &base, const char *ist, const char *soll);
288 bool replace_all(std::string &base, const char *ist, const std::string *soll);
289 bool replace_all(std::string &base, const std::string &ist, const char *soll);
290 bool replace_all(std::string &base, const std::string &ist, const std::string &soll);
291
292 std::string iso_to_utf8(const std::string& isostring);
293 std::string utf8_to_iso(const std::string& utf8string);
294 std::string utf7imap_to_utf8(const std::string &utf7imapstring);
295 std::string utf8_to_utf7imap(const std::string &utf8string);
296
297 std::string strip_html_tags(const std::string &input);
298 std::string smart_html_entities(const std::string &input);
299 std::string html_entities(std::string str);
300 std::string html_entities_to_console(std::string str);
301
302 typedef std::pair<std::string::size_type, std::string::size_type> CommentZone;
303 void find_html_comments(const std::string &str, std::vector<CommentZone> &result);
304 void remove_html_comments(std::string &str);
305 void remove_html_comments(std::string &str, const std::vector<CommentZone> &comments);
306
307 std::string sanitize_for_logging(const std::string &str, const char replace_with='?');
308
309 std::string escape(const std::string &s);
310
311 std::string descape(const std::string &s, int startpos, int &endpos);
312 inline std::string descape(const std::string &s)
313 {
314    int endpos;
315    return descape(s,0,endpos);
316 }
317
318 std::string escape_shellarg(const std::string &input);
319
320 #endif