Replace inet_aton() with inet_pton() to parse IPs correctly (#8825)
[libi2ncommon] / src / stringfunc.hxx
... / ...
CommitLineData
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*/
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 <stdio.h>
38#include <list>
39#include <numeric>
40#include <set>
41#include <vector>
42#include <string>
43#include <sstream>
44#include <stdexcept>
45#include <sys/types.h>
46
47namespace I2n
48{
49
50/*
51** some useful constants:
52*/
53
54extern const std::string Whitespaces;
55extern const std::string LineEndings;
56
57
58/*
59** predicates:
60*/
61
62
63bool has_prefix(const std::string& str, const std::string& prefix);
64
65bool has_suffix(const std::string& str, const std::string& suffix);
66
67
68/*
69** tool functions(modifying):
70*/
71
72std::string trim_mod(std::string& str, const std::string& charlist = Whitespaces);
73
74std::string chomp_mod(std::string& str, const std::string& what= LineEndings );
75
76std::string to_lower_mod(std::string& str);
77
78std::string to_upper_mod(std::string& str);
79
80
81/*
82** tool functions (not modifying):
83*/
84
85std::string trim(const std::string& str, const std::string& charlist = Whitespaces);
86
87std::string chomp(const std::string& str, const std::string& what= LineEndings );
88
89std::string to_lower(const std::string& str);
90
91std::string to_upper(const std::string& str);
92
93
94std::string remove_suffix(const std::string& str, const std::string& suffix);
95
96std::string remove_prefix(const std::string& str, const std::string& prefix);
97
98
99
100/*
101** split and join:
102*/
103
104
105bool pair_split(
106 const std::string& str,
107 std::string& key,
108 std::string& value,
109 char delimiter = '=');
110
111
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()
118);
119
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
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()
133);
134
135struct concatenator {
136 std::string delim;
137
138 concatenator (const std::string &delim) : delim (delim) { }
139
140 inline std::string operator() (const std::string &acc, const std::string &elt) const
141 { return acc + delim + elt; }
142};
143
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,
172 const std::string& delimiter = "\n"
173)
174{ return join_string (parts.begin (), parts.end (), delimiter); }
175
176std::string join_string(
177 const char *const parts [],
178 const std::string& delimiter = "\n"
179);
180
181/*
182** conversions:
183*/
184
185
186std::string convert_binary_to_hex(const std::string&str, bool upper_case_digits= false);
187
188std::string convert_hex_to_binary(const std::string& str);
189
190
191/*
192** "type conversions":
193*/
194
195
196/**
197 * convert a datatype @a T to a string via string stream.
198 *
199 * This will not report trouble in conversion; for example:
200 * string_to<int>("christian")
201 * will return 0 and not throw an error.
202 * Use boost::lexical_cast<T>(string) to get error-checked results.
203 *
204 * @param s the string which should be converted to @a T.
205 * @return the value of type T.
206 */
207template<
208class T
209>
210T string_to(const std::string& s)
211{
212 std::istringstream istr(s);
213 T result;
214 istr >> result;
215 return result;
216} // eo string_to(const std::string&)
217
218
219/**
220 * convert a datatype @a T to a string via string stream.
221 *
222 * @param s the string which should be converted to @a T.
223 * @param result the resulting value of type @a T.
224 * @return @a true iff the internal string stream was EOF after the conversion.
225 *
226 * @attention: does not return if the conversion was successful. So check for empty strings before.
227 */
228template<
229class T
230>
231bool string_to(const std::string& s, T& result)
232{
233 std::istringstream istr(s);
234 istr >> result;
235 return istr.eof();
236} // eo string_to(const std::string&)
237
238
239/**
240 * convert string in hexadecimal notation to a datatype @a T
241 * supports strings with and without "0x" notation, e.g. 0xff and FF are both valid
242 *
243 * @param s the hex string which should be converted to @a T.
244 * @return the value of type T.
245 */
246template<
247class T
248>
249T hex_string_to(const std::string& s)
250{
251 std::istringstream istr(s);
252 T result;
253 istr >> std::hex >> result;
254 return result;
255} // eo string_to(const std::string&)
256
257
258/**
259 * convert string in hexadecimal notation to a datatype @a T
260 * supports strings with and without "0x" notation, e.g. 0xff and FF are both valid
261 *
262 * @param s the hex string which should be converted to @a T.
263 * @param result the resulting value of type @a T.
264 * @return @a true iff the internal string stream was EOF after the conversion.
265 *
266 * @attention: does not return if the conversion was successful. So check for empty strings before.
267 */
268template<
269class T
270>
271bool hex_string_to(const std::string& s, T& result)
272{
273 std::istringstream istr(s);
274 istr >> std::hex >> result;
275 return istr.eof();
276} // eo string_to(const std::string&)
277
278
279/**
280 * convert a string to another datatype @a T via string stream.
281 *
282 * @param v the value (of type @a T) which should be converted to a string.
283 * @return the resulting string.
284 */
285template<
286class T
287>
288std::string to_string(const T& v)
289{
290 std::ostringstream ostr;
291 ostr << v;
292 return ostr.str();
293} // eo to_string(const T&)
294
295
296/**
297 * Create a string with types shortened in texts describing C++ types
298 *
299 * for example: std::list<some_long_type, std::allocator<some_long_type> >
300 * --> std::list<some_long_type, _alloc_>
301 *
302 * and std::basic_string<char, std::char_traits<char>, std::allocator<char> >
303 * --> std::string
304 */
305std::string shorten_stl_types(const std::string &input);
306
307std::string base64_encode(const std::string &input, bool one_line=true);
308std::string base64_decode(const std::string &input, bool one_line=true);
309
310} // eo namespace I2n
311
312
313#if 0
314std::string to_lower(const std::string &src);
315std::string to_upper(const std::string &src);
316#else
317// compatibility: import lower/upper funcs from I2n:
318using I2n::to_lower;
319using I2n::to_upper;
320#endif
321
322
323enum UnitBase {
324 UnitBase1000, // SI decimal, composed by multiples of 1000 (KB, MB, etc.)
325 UnitBase1024 // IEC binary, composed by multiples of 1024 (KiB, MiB, etc. )
326};
327
328enum UnitFormat {
329 ShortUnitFormat, // B, KB, MB, ...
330 LongUnitFormat // Byte, KByte, MByte, ...
331};
332
333std::string nice_unit_format(
334 const int64_t input,
335 const UnitFormat format = ShortUnitFormat,
336 const UnitBase base = UnitBase1024
337);
338
339std::string nice_unit_format(
340 const double input,
341 const UnitFormat format = ShortUnitFormat,
342 const UnitBase base = UnitBase1024
343);
344
345bool replace_all(std::string &base, const std::string *ist, const std::string *soll);
346bool replace_all(std::string &base, const char *ist, const char *soll);
347bool replace_all(std::string &base, const char *ist, const std::string *soll);
348bool replace_all(std::string &base, const std::string &ist, const char *soll);
349bool replace_all(std::string &base, const std::string &ist, const std::string &soll);
350
351std::string iso_to_utf8(const std::string& isostring);
352std::string utf8_to_iso(const std::string& utf8string);
353std::string utf7imap_to_utf8(const std::string &utf7imapstring);
354std::string utf8_to_utf7imap(const std::string &utf8string);
355
356std::string strip_html_tags(const std::string &input);
357std::string smart_html_entities(const std::string &input);
358std::string html_entities(std::string str);
359std::string html_entities_to_console(std::string str);
360
361inline std::string html_entities_iso (const std::string &str)
362{
363 return html_entities (iso_to_utf8 (str));
364}
365
366typedef std::pair<std::string::size_type, std::string::size_type> CommentZone;
367std::vector<CommentZone> find_html_comments(const std::string &str);
368void remove_html_comments(std::string &str);
369void remove_html_comments(std::string &str, const std::vector<CommentZone> &comments);
370
371std::string sanitize_for_logging(const std::string &str, const char replace_with='?');
372
373std::string escape(const std::string &s);
374
375std::string descape(const std::string &s, int startpos, int &endpos);
376inline std::string descape(const std::string &s)
377{
378 int endpos;
379 return descape(s,0,endpos);
380}
381
382std::string escape_shellarg(const std::string &input);
383
384#endif