Copyright 2012 -> 2013
[folly.git] / folly / String.h
1 /*
2  * Copyright 2013 Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #ifndef FOLLY_BASE_STRING_H_
18 #define FOLLY_BASE_STRING_H_
19
20 #include <exception>
21 #include <string>
22 #include <boost/type_traits.hpp>
23
24 #ifdef __GNUC__
25 # include <ext/hash_set>
26 # include <ext/hash_map>
27 #endif
28
29 #include "folly/Conv.h"
30 #include "folly/FBString.h"
31 #include "folly/FBVector.h"
32 #include "folly/Range.h"
33 #include "folly/ScopeGuard.h"
34
35 // Compatibility function, to make sure toStdString(s) can be called
36 // to convert a std::string or fbstring variable s into type std::string
37 // with very little overhead if s was already std::string
38 namespace folly {
39
40 inline
41 std::string toStdString(const folly::fbstring& s) {
42   return std::string(s.data(), s.size());
43 }
44
45 inline
46 const std::string& toStdString(const std::string& s) {
47   return s;
48 }
49
50 // If called with a temporary, the compiler will select this overload instead
51 // of the above, so we don't return a (lvalue) reference to a temporary.
52 inline
53 std::string&& toStdString(std::string&& s) {
54   return std::move(s);
55 }
56
57 /**
58  * C-Escape a string, making it suitable for representation as a C string
59  * literal.  Appends the result to the output string.
60  *
61  * Backslashes all occurrences of backslash and double-quote:
62  *   "  ->  \"
63  *   \  ->  \\
64  *
65  * Replaces all non-printable ASCII characters with backslash-octal
66  * representation:
67  *   <ASCII 254> -> \376
68  *
69  * Note that we use backslash-octal instead of backslash-hex because the octal
70  * representation is guaranteed to consume no more than 3 characters; "\3760"
71  * represents two characters, one with value 254, and one with value 48 ('0'),
72  * whereas "\xfe0" represents only one character (with value 4064, which leads
73  * to implementation-defined behavior).
74  */
75 template <class String>
76 void cEscape(StringPiece str, String& out);
77
78 /**
79  * Similar to cEscape above, but returns the escaped string.
80  */
81 template <class String>
82 String cEscape(StringPiece str) {
83   String out;
84   cEscape(str, out);
85   return out;
86 }
87
88 /**
89  * C-Unescape a string; the opposite of cEscape above.  Appends the result
90  * to the output string.
91  *
92  * Recognizes the standard C escape sequences:
93  *
94  * \' \" \? \\ \a \b \f \n \r \t \v
95  * \[0-7]+
96  * \x[0-9a-fA-F]+
97  *
98  * In strict mode (default), throws std::invalid_argument if it encounters
99  * an unrecognized escape sequence.  In non-strict mode, it leaves
100  * the escape sequence unchanged.
101  */
102 template <class String>
103 void cUnescape(StringPiece str, String& out, bool strict = true);
104
105 /**
106  * Similar to cUnescape above, but returns the escaped string.
107  */
108 template <class String>
109 String cUnescape(StringPiece str, bool strict = true) {
110   String out;
111   cUnescape(str, out, strict);
112   return out;
113 }
114
115 /**
116  * stringPrintf is much like printf but deposits its result into a
117  * string. Two signatures are supported: the first simply returns the
118  * resulting string, and the second appends the produced characters to
119  * the specified string and returns a reference to it.
120  */
121 std::string stringPrintf(const char* format, ...)
122   __attribute__ ((format (printf, 1, 2)));
123
124 /** Similar to stringPrintf, with different signiture.
125   */
126 void stringPrintf(std::string* out, const char* fmt, ...)
127   __attribute__ ((format (printf, 2, 3)));
128
129 std::string& stringAppendf(std::string* output, const char* format, ...)
130   __attribute__ ((format (printf, 2, 3)));
131
132 /**
133  * Backslashify a string, that is, replace non-printable characters
134  * with C-style (but NOT C compliant) "\xHH" encoding.  If hex_style
135  * is false, then shorthand notations like "\0" will be used instead
136  * of "\x00" for the most common backslash cases.
137  *
138  * There are two forms, one returning the input string, and one
139  * creating output in the specified output string.
140  *
141  * This is mainly intended for printing to a terminal, so it is not
142  * particularly optimized.
143  *
144  * Do *not* use this in situations where you expect to be able to feed
145  * the string to a C or C++ compiler, as there are nuances with how C
146  * parses such strings that lead to failures.  This is for display
147  * purposed only.  If you want a string you can embed for use in C or
148  * C++, use cEscape instead.  This function is for display purposes
149  * only.
150  */
151 template <class String1, class String2>
152 void backslashify(const String1& input, String2& output, bool hex_style=false);
153
154 template <class String>
155 String backslashify(const String& input, bool hex_style=false) {
156   String output;
157   backslashify(input, output, hex_style);
158   return output;
159 }
160
161 /**
162  * Take a string and "humanify" it -- that is, make it look better.
163  * Since "better" is subjective, caveat emptor.  The basic approach is
164  * to count the number of unprintable characters.  If there are none,
165  * then the output is the input.  If there are relatively few, or if
166  * there is a long "enough" prefix of printable characters, use
167  * backslashify.  If it is mostly binary, then simply hex encode.
168  *
169  * This is an attempt to make a computer smart, and so likely is wrong
170  * most of the time.
171  */
172 template <class String1, class String2>
173 void humanify(const String1& input, String2& output);
174
175 template <class String>
176 String humanify(const String& input) {
177   String output;
178   humanify(input, output);
179   return output;
180 }
181
182 /**
183  * Same functionality as Python's binascii.hexlify.  Returns true
184  * on successful conversion.
185  *
186  * If append_output is true, append data to the output rather than
187  * replace it.
188  */
189 template<class InputString, class OutputString>
190 bool hexlify(const InputString& input, OutputString& output,
191              bool append=false);
192
193 /**
194  * Same functionality as Python's binascii.unhexlify.  Returns true
195  * on successful conversion.
196  */
197 template<class InputString, class OutputString>
198 bool unhexlify(const InputString& input, OutputString& output);
199
200 /*
201  * A pretty-printer for numbers that appends suffixes of units of the
202  * given type.  It prints 4 sig-figs of value with the most
203  * appropriate unit.
204  *
205  * If `addSpace' is true, we put a space between the units suffix and
206  * the value.
207  *
208  * Current types are:
209  *   PRETTY_TIME         - s, ms, us, ns, etc.
210  *   PRETTY_BYTES_METRIC - kB, MB, GB, etc (goes up by 10^3 = 1000 each time)
211  *   PRETTY_BYTES        - kB, MB, GB, etc (goes up by 2^10 = 1024 each time)
212  *   PRETTY_BYTES_IEC    - KiB, MiB, GiB, etc
213  *   PRETTY_UNITS_METRIC - k, M, G, etc (goes up by 10^3 = 1000 each time)
214  *   PRETTY_UNITS_BINARY - k, M, G, etc (goes up by 2^10 = 1024 each time)
215  *   PRETTY_UNITS_BINARY_IEC - Ki, Mi, Gi, etc
216  *
217  * @author Mark Rabkin <mrabkin@fb.com>
218  */
219 enum PrettyType {
220   PRETTY_TIME,
221
222   PRETTY_BYTES_METRIC,
223   PRETTY_BYTES_BINARY,
224   PRETTY_BYTES = PRETTY_BYTES_BINARY,
225   PRETTY_BYTES_BINARY_IEC,
226   PRETTY_BYTES_IEC = PRETTY_BYTES_BINARY_IEC,
227
228   PRETTY_UNITS_METRIC,
229   PRETTY_UNITS_BINARY,
230   PRETTY_UNITS_BINARY_IEC,
231
232   PRETTY_NUM_TYPES
233 };
234
235 std::string prettyPrint(double val, PrettyType, bool addSpace = true);
236
237 /**
238  * Write a hex dump of size bytes starting at ptr to out.
239  *
240  * The hex dump is formatted as follows:
241  *
242  * for the string "abcdefghijklmnopqrstuvwxyz\x02"
243 00000000  61 62 63 64 65 66 67 68  69 6a 6b 6c 6d 6e 6f 70  |abcdefghijklmnop|
244 00000010  71 72 73 74 75 76 77 78  79 7a 02                 |qrstuvwxyz.     |
245  *
246  * that is, we write 16 bytes per line, both as hex bytes and as printable
247  * characters.  Non-printable characters are replaced with '.'
248  * Lines are written to out one by one (one StringPiece at a time) without
249  * delimiters.
250  */
251 template <class OutIt>
252 void hexDump(const void* ptr, size_t size, OutIt out);
253
254 /**
255  * Return the hex dump of size bytes starting at ptr as a string.
256  */
257 std::string hexDump(const void* ptr, size_t size);
258
259 /**
260  * Return a fbstring containing the description of the given errno value.
261  * Takes care not to overwrite the actual system errno, so calling
262  * errnoStr(errno) is valid.
263  */
264 fbstring errnoStr(int err);
265
266 /**
267  * Return the demangled (prettyfied) version of a C++ type.
268  *
269  * This function tries to produce a human-readable type, but the type name will
270  * be returned unchanged in case of error or if demangling isn't supported on
271  * your system.
272  *
273  * Use for debugging -- do not rely on demangle() returning anything useful.
274  *
275  * This function may allocate memory (and therefore throw).
276  */
277 fbstring demangle(const char* name);
278 inline fbstring demangle(const std::type_info& type) {
279   return demangle(type.name());
280 }
281
282 /**
283  * Debug string for an exception: include type and what().
284  */
285 inline fbstring exceptionStr(const std::exception& e) {
286   return folly::to<fbstring>(demangle(typeid(e)), ": ", e.what());
287 }
288
289 inline fbstring exceptionStr(std::exception_ptr ep) {
290   try {
291     std::rethrow_exception(ep);
292   } catch (const std::exception& e) {
293     return exceptionStr(e);
294   } catch (...) {
295     return "<unknown exception>";
296   }
297 }
298
299 /*
300  * Split a string into a list of tokens by delimiter.
301  *
302  * The split interface here supports different output types, selected
303  * at compile time: StringPiece, fbstring, or std::string.  If you are
304  * using a vector to hold the output, it detects the type based on
305  * what your vector contains.  If the output vector is not empty, split
306  * will append to the end of the vector.
307  *
308  * You can also use splitTo() to write the output to an arbitrary
309  * OutputIterator (e.g. std::inserter() on a std::set<>), in which
310  * case you have to tell the function the type.  (Rationale:
311  * OutputIterators don't have a value_type, so we can't detect the
312  * type in splitTo without being told.)
313  *
314  * Examples:
315  *
316  *   std::vector<folly::StringPiece> v;
317  *   folly::split(":", "asd:bsd", v);
318  *
319  *   std::set<StringPiece> s;
320  *   folly::splitTo<StringPiece>(":", "asd:bsd:asd:csd",
321  *    std::inserter(s, s.begin()));
322  *
323  * Split also takes a flag (ignoreEmpty) that indicates whether adjacent
324  * delimiters should be treated as one single separator (ignoring empty tokens)
325  * or not (generating empty tokens).
326  */
327
328 template<class Delim, class String, class OutputType>
329 void split(const Delim& delimiter,
330            const String& input,
331            std::vector<OutputType>& out,
332            bool ignoreEmpty = false);
333
334 template<class Delim, class String, class OutputType>
335 void split(const Delim& delimiter,
336            const String& input,
337            folly::fbvector<OutputType>& out,
338            bool ignoreEmpty = false);
339
340 template<class OutputValueType, class Delim, class String,
341          class OutputIterator>
342 void splitTo(const Delim& delimiter,
343              const String& input,
344              OutputIterator out,
345              bool ignoreEmpty = false);
346
347 /*
348  * Join list of tokens.
349  *
350  * Stores a string representation of tokens in the same order with
351  * deliminer between each element.
352  */
353
354 template <class Delim, class Iterator, class String>
355 void join(const Delim& delimiter,
356           Iterator begin,
357           Iterator end,
358           String& output);
359
360 template <class Delim, class Container, class String>
361 void join(const Delim& delimiter,
362           const Container& container,
363           String& output) {
364   join(delimiter, container.begin(), container.end(), output);
365 }
366
367 template <class Delim, class Container>
368 std::string join(const Delim& delimiter,
369                  const Container& container) {
370   std::string output;
371   join(delimiter, container.begin(), container.end(), output);
372   return output;
373 }
374
375 } // namespace folly
376
377 // Hash functions for string and fbstring usable with e.g. hash_map
378 #ifdef __GNUC__
379 namespace __gnu_cxx {
380
381 template <class C>
382 struct hash<folly::basic_fbstring<C> > : private hash<const C*> {
383   size_t operator()(const folly::basic_fbstring<C> & s) const {
384     return hash<const C*>::operator()(s.c_str());
385   }
386 };
387
388 template <class C>
389 struct hash<std::basic_string<C> > : private hash<const C*> {
390   size_t operator()(const std::basic_string<C> & s) const {
391     return hash<const C*>::operator()(s.c_str());
392   }
393 };
394
395 } // namespace __gnu_cxx
396 #endif
397
398 // Hook into boost's type traits
399 namespace boost {
400 template <class T>
401 struct has_nothrow_constructor<folly::basic_fbstring<T> > : true_type {
402   enum { value = true };
403 };
404 } // namespace boost
405
406 #include "folly/String-inl.h"
407
408 #endif