add char** overloads for join_string
[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 void split_string(
118    const std::string& str,
119    std::vector< std::string >& result,
120    const std::string& delimiter= "\n",
121    bool omit_empty= false,
122    const std::string& trim_list= std::string()
123 );
124
125 std::list< std::string > split_string(
126    const std::string& str,
127    const std::string& delimiter = "\n",
128    bool omit_empty= false,
129    const std::string& trim_list= std::string()
130 );
131
132
133 std::string join_string(
134    const std::list< std::string >& parts,
135    const std::string& delimiter = "\n"
136 );
137
138 std::string join_string(
139    const std::vector< std::string >& parts,
140    const std::string& delimiter = "\n"
141 );
142
143 std::string join_string(
144    const char *const parts [],
145    const std::string& delimiter = "\n"
146 );
147
148
149 /*
150 ** conversions:
151 */
152
153
154 std::string convert_binary_to_hex(const std::string&str, bool upper_case_digits= false);
155
156 std::string convert_hex_to_binary(const std::string& str) throw(std::runtime_error);
157
158
159 /*
160 ** "type conversions":
161 */
162
163
164 /**
165  * convert a datatype @a T to a string via string stream.
166  *
167  * This will not report trouble in conversion; for example:
168  *     string_to<int>("christian")
169  * will return 0 and not throw an error.
170  * Use boost::lexical_cast<T>(string) to get error-checked results.
171  *
172  * @param s the string which should be converted to @a T.
173  * @return the value of type T.
174  */
175 template<
176 class T
177 >
178 T string_to(const std::string& s)
179 {
180    std::istringstream istr(s);
181    T result;
182    istr >> result;
183    return result;
184 } // eo string_to(const std::string&)
185
186
187 /**
188  * convert a datatype @a T to a string via string stream.
189  *
190  * @param s the string which should be converted to @a T.
191  * @param result the resulting value of type @a T.
192  * @return @a true iff the internal string stream was EOF after the conversion.
193  *
194  * @attention: does not return if the conversion was successful. So check for empty strings before.
195  */
196 template<
197 class T
198 >
199 bool string_to(const std::string& s, T& result)
200 {
201    std::istringstream istr(s);
202    istr >> result;
203    return istr.eof();
204 } // eo string_to(const std::string&)
205
206
207 /**
208  * convert string in hexadecimal notation to a datatype @a T
209  * supports strings with and without "0x" notation, e.g. 0xff and FF are both valid
210  * 
211  * @param s the hex string which should be converted to @a T.
212  * @return the value of type T.
213  */
214 template<
215 class T
216 >
217 T hex_string_to(const std::string& s)
218 {
219    std::istringstream istr(s);
220    T result;
221    istr >> std::hex >> result;
222    return result;
223 } // eo string_to(const std::string&)
224
225
226 /**
227  * convert string in hexadecimal notation to a datatype @a T
228  * supports strings with and without "0x" notation, e.g. 0xff and FF are both valid
229  *
230  * @param s the hex string which should be converted to @a T.
231  * @param result the resulting value of type @a T.
232  * @return @a true iff the internal string stream was EOF after the conversion.
233  *
234  * @attention: does not return if the conversion was successful. So check for empty strings before.
235  */
236 template<
237 class T
238 >
239 bool hex_string_to(const std::string& s, T& result)
240 {
241    std::istringstream istr(s);
242    istr >> std::hex >> result;
243    return istr.eof();
244 } // eo string_to(const std::string&)
245
246
247 /**
248  * convert a string to another datatype @a T via string stream.
249  *
250  * @param v the value (of type @a T) which should be converted to a string.
251  * @return the resulting string.
252  */
253 template<
254 class T
255 >
256 std::string to_string(const T& v)
257 {
258    std::ostringstream ostr;
259    ostr << v;
260    return ostr.str();
261 } // eo to_string(const T&)
262
263
264 /**
265  * Create a string with types shortened in texts describing C++ types
266  *
267  * for example: std::list<some_long_type, std::allocator<some_long_type> >
268  * -->  std::list<some_long_type, _alloc_>
269  *
270  * and std::basic_string<char, std::char_traits<char>, std::allocator<char> >
271  * --> std::string
272  */
273 std::string shorten_stl_types(const std::string &input);
274
275 std::string base64_encode(const std::string &input, bool one_line=true);
276 std::string base64_decode(const std::string &input, bool one_line=true);
277
278 } // eo namespace I2n
279
280
281 #if 0
282 std::string to_lower(const std::string &src);
283 std::string to_upper(const std::string &src);
284 #else
285 // compatibility: import lower/upper funcs from I2n:
286 using I2n::to_lower;
287 using I2n::to_upper;
288 #endif
289
290
291 enum UnitBase {
292     UnitBase1000, // SI decimal, composed by multiples of 1000 (KB, MB, etc.)
293     UnitBase1024 // IEC binary, composed by multiples of 1024 (KiB, MiB, etc. )
294 };
295
296 enum UnitFormat {
297     ShortUnitFormat, // B, KB, MB, ...
298     LongUnitFormat // Byte, KByte, MByte, ...
299 };
300
301 std::string nice_unit_format(
302         const int64_t input,
303         const UnitFormat format = ShortUnitFormat,
304         const UnitBase base = UnitBase1024
305 );
306
307 std::string nice_unit_format(
308         const double input,
309         const UnitFormat format = ShortUnitFormat,
310         const UnitBase base = UnitBase1024
311 );
312
313 bool replace_all(std::string &base, const std::string *ist, const std::string *soll);
314 bool replace_all(std::string &base, const char *ist, const char *soll);
315 bool replace_all(std::string &base, const char *ist, const std::string *soll);
316 bool replace_all(std::string &base, const std::string &ist, const char *soll);
317 bool replace_all(std::string &base, const std::string &ist, const std::string &soll);
318
319 std::string iso_to_utf8(const std::string& isostring);
320 std::string utf8_to_iso(const std::string& utf8string);
321 std::string utf7imap_to_utf8(const std::string &utf7imapstring);
322 std::string utf8_to_utf7imap(const std::string &utf8string);
323
324 std::string strip_html_tags(const std::string &input);
325 std::string smart_html_entities(const std::string &input);
326 std::string html_entities(std::string str);
327 std::string html_entities_to_console(std::string str);
328
329 typedef std::pair<std::string::size_type, std::string::size_type> CommentZone;
330 std::vector<CommentZone> find_html_comments(const std::string &str);
331 void remove_html_comments(std::string &str);
332 void remove_html_comments(std::string &str, const std::vector<CommentZone> &comments);
333
334 std::string sanitize_for_logging(const std::string &str, const char replace_with='?');
335
336 std::string escape(const std::string &s);
337
338 std::string descape(const std::string &s, int startpos, int &endpos);
339 inline std::string descape(const std::string &s)
340 {
341    int endpos;
342    return descape(s,0,endpos);
343 }
344
345 std::string escape_shellarg(const std::string &input);
346
347 #endif