allow selecting stdout and stderr with inpipestream
[libi2ncommon] / src / stringfunc.hxx
CommitLineData
0e23f538
TJ
1/*
2The software in this package is distributed under the GNU General
3Public License version 2 (with a special exception described below).
4
5A copy of GNU General Public License (GPL) is included in this distribution,
6in the file COPYING.GPL.
7
8As a special exception, if other files instantiate templates or use macros
9or inline functions from this file, or you compile this file and link it
10with other works to produce a work based on this file, this file
11does not by itself cause the resulting work to be covered
12by the GNU General Public License.
13
14However the source code for this file must still be made available
15in accordance with section (3) of the GNU General Public License.
16
17This exception does not invalidate any other reasons why a work based
18on this file might be covered by the GNU General Public License.
19*/
6a93d84a
TJ
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
6a93d84a 32 */
e93545dd
GE
33
34#ifndef __STRINGFUNC_HXX
35#define __STRINGFUNC_HXX
36
5ad80381 37#include <stdio.h>
6a93d84a 38#include <list>
5ad80381 39#include <numeric>
0aaf13b5 40#include <set>
376ec4fa 41#include <vector>
e93545dd 42#include <string>
6a93d84a
TJ
43#include <sstream>
44#include <stdexcept>
b04b4f7e 45#include <sys/types.h>
6a93d84a 46
6ab3bc95
RP
47namespace I2n
48{
6a93d84a
TJ
49
50/*
51** some useful constants:
52*/
53
6ab3bc95
RP
54extern const std::string Whitespaces;
55extern const std::string LineEndings;
6a93d84a
TJ
56
57
58/*
59** predicates:
60*/
61
62
6ab3bc95 63bool has_prefix(const std::string& str, const std::string& prefix);
6a93d84a 64
6ab3bc95 65bool has_suffix(const std::string& str, const std::string& suffix);
6a93d84a
TJ
66
67
68/*
6ab3bc95 69** tool functions(modifying):
6a93d84a
TJ
70*/
71
6ab3bc95 72std::string trim_mod(std::string& str, const std::string& charlist = Whitespaces);
6a93d84a 73
6ab3bc95 74std::string chomp_mod(std::string& str, const std::string& what= LineEndings );
6a93d84a 75
6ab3bc95 76std::string to_lower_mod(std::string& str);
6a93d84a 77
6ab3bc95 78std::string to_upper_mod(std::string& str);
6a93d84a
TJ
79
80
81/*
82** tool functions (not modifying):
83*/
84
6ab3bc95 85std::string trim(const std::string& str, const std::string& charlist = Whitespaces);
6a93d84a 86
6ab3bc95 87std::string chomp(const std::string& str, const std::string& what= LineEndings );
6a93d84a 88
6ab3bc95 89std::string to_lower(const std::string& str);
6a93d84a 90
6ab3bc95 91std::string to_upper(const std::string& str);
6a93d84a
TJ
92
93
6ab3bc95 94std::string remove_suffix(const std::string& str, const std::string& suffix);
6a93d84a 95
6ab3bc95 96std::string remove_prefix(const std::string& str, const std::string& prefix);
6a93d84a
TJ
97
98
99
100/*
101** split and join:
102*/
103
104
6ab3bc95
RP
105bool pair_split(
106 const std::string& str,
107 std::string& key,
108 std::string& value,
109 char delimiter = '=');
6a93d84a
TJ
110
111
6ab3bc95
RP
112void split_string(
113 const std::string& str,
114 std::list< std::string >& result,
115 const std::string& delimiter= "\n",
116 bool omit_empty= false,
117 const std::string& trim_list= std::string()
6a93d84a
TJ
118);
119
338da253
CH
120void split_string(
121 const std::string& str,
122 std::vector< std::string >& result,
123 const std::string& delimiter= "\n",
124 bool omit_empty= false,
125 const std::string& trim_list= std::string()
126);
127
6ab3bc95
RP
128std::list< std::string > split_string(
129 const std::string& str,
130 const std::string& delimiter = "\n",
131 bool omit_empty= false,
132 const std::string& trim_list= std::string()
6a93d84a
TJ
133);
134
5ad80381
PG
135struct concatenator {
136 std::string delim;
6a93d84a 137
5ad80381 138 concatenator (const std::string &delim) : delim (delim) { }
6a93d84a 139
5ad80381
PG
140 inline std::string operator() (const std::string &acc, const std::string &elt) const
141 { return acc + delim + elt; }
142};
376ec4fa 143
5ad80381
PG
144template<typename Iter>
145std::string
146join_string (
147 Iter first,
148 Iter last,
149 const std::string &delimiter = "\n"
150)
151{
152 if (first == last) { return ""; }
153
154 const std::string &init = *first++;
155 if (first == last) { return init; }
156
157 return std::accumulate (first, last, init, concatenator (delimiter));
158}
159
160/**
161 * @brief joins a container of strings into a single string.
162 *
163 * This funtion is (basically) the reverse operation of @a split_string.
164 *
165 * @param parts the container of strings.
166 * @param delimiter the delimiter to insert between the strings.
167 * @return the joined string.
168 */
169template<typename Cont>
170inline std::string join_string(
171 const Cont& parts,
0aaf13b5 172 const std::string& delimiter = "\n"
5ad80381
PG
173)
174{ return join_string (parts.begin (), parts.end (), delimiter); }
0aaf13b5
PG
175
176std::string join_string(
4f7a7b9f
PG
177 const char *const parts [],
178 const std::string& delimiter = "\n"
179);
180
6a93d84a 181/*
f3b61bd6
PG
182 * provide instantiation wrappers for ABI compatibility
183 */
184std::string join_string (const std::list<std::string> &l,
185 const std::string &d = "\n");
186
187std::string join_string (const std::vector<std::string> &l,
188 const std::string &d = "\n");
189
190/*
6a93d84a
TJ
191** conversions:
192*/
193
194
6ab3bc95 195std::string convert_binary_to_hex(const std::string&str, bool upper_case_digits= false);
6a93d84a 196
6ab3bc95 197std::string convert_hex_to_binary(const std::string& str) throw(std::runtime_error);
6a93d84a
TJ
198
199
6a93d84a
TJ
200/*
201** "type conversions":
202*/
203
204
205/**
206 * convert a datatype @a T to a string via string stream.
207 *
1fe2e899
CH
208 * This will not report trouble in conversion; for example:
209 * string_to<int>("christian")
210 * will return 0 and not throw an error.
211 * Use boost::lexical_cast<T>(string) to get error-checked results.
212 *
6a93d84a
TJ
213 * @param s the string which should be converted to @a T.
214 * @return the value of type T.
215 */
216template<
6ab3bc95 217class T
6a93d84a 218>
6ab3bc95 219T string_to(const std::string& s)
6a93d84a 220{
6ab3bc95
RP
221 std::istringstream istr(s);
222 T result;
223 istr >> result;
224 return result;
225} // eo string_to(const std::string&)
6a93d84a
TJ
226
227
228/**
229 * convert a datatype @a T to a string via string stream.
230 *
231 * @param s the string which should be converted to @a T.
232 * @param result the resulting value of type @a T.
233 * @return @a true iff the internal string stream was EOF after the conversion.
08f2d184
GE
234 *
235 * @attention: does not return if the conversion was successful. So check for empty strings before.
6a93d84a
TJ
236 */
237template<
6ab3bc95 238class T
6a93d84a 239>
6ab3bc95 240bool string_to(const std::string& s, T& result)
6a93d84a 241{
6ab3bc95
RP
242 std::istringstream istr(s);
243 istr >> result;
244 return istr.eof();
245} // eo string_to(const std::string&)
6a93d84a
TJ
246
247
248/**
3bcc713f
GE
249 * convert string in hexadecimal notation to a datatype @a T
250 * supports strings with and without "0x" notation, e.g. 0xff and FF are both valid
251 *
252 * @param s the hex string which should be converted to @a T.
253 * @return the value of type T.
254 */
255template<
256class T
257>
258T hex_string_to(const std::string& s)
259{
260 std::istringstream istr(s);
261 T result;
262 istr >> std::hex >> result;
263 return result;
264} // eo string_to(const std::string&)
265
266
267/**
268 * convert string in hexadecimal notation to a datatype @a T
269 * supports strings with and without "0x" notation, e.g. 0xff and FF are both valid
270 *
271 * @param s the hex string which should be converted to @a T.
272 * @param result the resulting value of type @a T.
273 * @return @a true iff the internal string stream was EOF after the conversion.
274 *
275 * @attention: does not return if the conversion was successful. So check for empty strings before.
276 */
277template<
278class T
279>
280bool hex_string_to(const std::string& s, T& result)
281{
282 std::istringstream istr(s);
283 istr >> std::hex >> result;
284 return istr.eof();
285} // eo string_to(const std::string&)
286
287
288/**
6a93d84a
TJ
289 * convert a string to another datatype @a T via string stream.
290 *
291 * @param v the value (of type @a T) which should be converted to a string.
292 * @return the resulting string.
293 */
294template<
6ab3bc95 295class T
6a93d84a 296>
6ab3bc95 297std::string to_string(const T& v)
6a93d84a 298{
6ab3bc95
RP
299 std::ostringstream ostr;
300 ostr << v;
301 return ostr.str();
302} // eo to_string(const T&)
303
304
1a0267e5
CH
305/**
306 * Create a string with types shortened in texts describing C++ types
307 *
308 * for example: std::list<some_long_type, std::allocator<some_long_type> >
309 * --> std::list<some_long_type, _alloc_>
310 *
311 * and std::basic_string<char, std::char_traits<char>, std::allocator<char> >
312 * --> std::string
313 */
314std::string shorten_stl_types(const std::string &input);
315
1ebab1e3
TJ
316std::string base64_encode(const std::string &input, bool one_line=true);
317std::string base64_decode(const std::string &input, bool one_line=true);
1a0267e5 318
6ab3bc95
RP
319} // eo namespace I2n
320
6a93d84a 321
e5b21dbb 322#if 0
6ab3bc95
RP
323std::string to_lower(const std::string &src);
324std::string to_upper(const std::string &src);
e5b21dbb
RP
325#else
326// compatibility: import lower/upper funcs from I2n:
327using I2n::to_lower;
328using I2n::to_upper;
329#endif
e93545dd 330
81267544 331
8f296924
GMF
332enum UnitBase {
333 UnitBase1000, // SI decimal, composed by multiples of 1000 (KB, MB, etc.)
334 UnitBase1024 // IEC binary, composed by multiples of 1024 (KiB, MiB, etc. )
81267544
GMF
335};
336
8f296924
GMF
337enum UnitFormat {
338 ShortUnitFormat, // B, KB, MB, ...
339 LongUnitFormat // Byte, KByte, MByte, ...
d1ea9075
GMF
340};
341
81267544
GMF
342std::string nice_unit_format(
343 const int64_t input,
ee037ee3
GMF
344 const UnitFormat format = ShortUnitFormat,
345 const UnitBase base = UnitBase1024
81267544 346);
e93545dd 347
5cd64148
CH
348std::string nice_unit_format(
349 const double input,
350 const UnitFormat format = ShortUnitFormat,
351 const UnitBase base = UnitBase1024
352);
353
e93545dd
GE
354bool replace_all(std::string &base, const std::string *ist, const std::string *soll);
355bool replace_all(std::string &base, const char *ist, const char *soll);
356bool replace_all(std::string &base, const char *ist, const std::string *soll);
357bool replace_all(std::string &base, const std::string &ist, const char *soll);
358bool replace_all(std::string &base, const std::string &ist, const std::string &soll);
359
360std::string iso_to_utf8(const std::string& isostring);
361std::string utf8_to_iso(const std::string& utf8string);
13cc4db1 362std::string utf7imap_to_utf8(const std::string &utf7imapstring);
6a2b6dd1 363std::string utf8_to_utf7imap(const std::string &utf8string);
118e216e
TJ
364
365std::string strip_html_tags(const std::string &input);
366std::string smart_html_entities(const std::string &input);
367std::string html_entities(std::string str);
554f813d 368std::string html_entities_to_console(std::string str);
118e216e 369
3f5c5ccd 370typedef std::pair<std::string::size_type, std::string::size_type> CommentZone;
46dd1321 371std::vector<CommentZone> find_html_comments(const std::string &str);
3f5c5ccd
CH
372void remove_html_comments(std::string &str);
373void remove_html_comments(std::string &str, const std::vector<CommentZone> &comments);
374
b953bf36
GE
375std::string sanitize_for_logging(const std::string &str, const char replace_with='?');
376
47c07fba
GE
377std::string escape(const std::string &s);
378
379std::string descape(const std::string &s, int startpos, int &endpos);
e6da286a 380inline std::string descape(const std::string &s)
47c07fba 381{
6ab3bc95
RP
382 int endpos;
383 return descape(s,0,endpos);
47c07fba
GE
384}
385
386std::string escape_shellarg(const std::string &input);
387
e93545dd 388#endif