Bitcoin Core  22.99.0
P2P Digital Currency
strencodings.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2021 The Bitcoin Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
6 #include <util/strencodings.h>
7 #include <util/string.h>
8 
9 #include <tinyformat.h>
10 
11 #include <algorithm>
12 #include <cstdlib>
13 #include <cstring>
14 #include <limits>
15 #include <optional>
16 
17 static const std::string CHARS_ALPHA_NUM = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
18 
19 static const std::string SAFE_CHARS[] =
20 {
21  CHARS_ALPHA_NUM + " .,;-_/:?@()", // SAFE_CHARS_DEFAULT
22  CHARS_ALPHA_NUM + " .,;-_?@", // SAFE_CHARS_UA_COMMENT
23  CHARS_ALPHA_NUM + ".-_", // SAFE_CHARS_FILENAME
24  CHARS_ALPHA_NUM + "!*'();:@&=+$,/?#[]-_.~%", // SAFE_CHARS_URI
25 };
26 
27 std::string SanitizeString(const std::string& str, int rule)
28 {
29  std::string strResult;
30  for (std::string::size_type i = 0; i < str.size(); i++)
31  {
32  if (SAFE_CHARS[rule].find(str[i]) != std::string::npos)
33  strResult.push_back(str[i]);
34  }
35  return strResult;
36 }
37 
38 const signed char p_util_hexdigit[256] =
39 { -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
40  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
41  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
42  0,1,2,3,4,5,6,7,8,9,-1,-1,-1,-1,-1,-1,
43  -1,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1,
44  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
45  -1,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1,
46  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
47  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
48  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
49  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
50  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
51  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
52  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
53  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
54  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, };
55 
56 signed char HexDigit(char c)
57 {
58  return p_util_hexdigit[(unsigned char)c];
59 }
60 
61 bool IsHex(const std::string& str)
62 {
63  for(std::string::const_iterator it(str.begin()); it != str.end(); ++it)
64  {
65  if (HexDigit(*it) < 0)
66  return false;
67  }
68  return (str.size() > 0) && (str.size()%2 == 0);
69 }
70 
71 bool IsHexNumber(const std::string& str)
72 {
73  size_t starting_location = 0;
74  if (str.size() > 2 && *str.begin() == '0' && *(str.begin()+1) == 'x') {
75  starting_location = 2;
76  }
77  for (const char c : str.substr(starting_location)) {
78  if (HexDigit(c) < 0) return false;
79  }
80  // Return false for empty string or "0x".
81  return (str.size() > starting_location);
82 }
83 
84 std::vector<unsigned char> ParseHex(const char* psz)
85 {
86  // convert hex dump to vector
87  std::vector<unsigned char> vch;
88  while (true)
89  {
90  while (IsSpace(*psz))
91  psz++;
92  signed char c = HexDigit(*psz++);
93  if (c == (signed char)-1)
94  break;
95  auto n{uint8_t(c << 4)};
96  c = HexDigit(*psz++);
97  if (c == (signed char)-1)
98  break;
99  n |= c;
100  vch.push_back(n);
101  }
102  return vch;
103 }
104 
105 std::vector<unsigned char> ParseHex(const std::string& str)
106 {
107  return ParseHex(str.c_str());
108 }
109 
110 void SplitHostPort(std::string in, uint16_t& portOut, std::string& hostOut)
111 {
112  size_t colon = in.find_last_of(':');
113  // if a : is found, and it either follows a [...], or no other : is in the string, treat it as port separator
114  bool fHaveColon = colon != in.npos;
115  bool fBracketed = fHaveColon && (in[0] == '[' && in[colon - 1] == ']'); // if there is a colon, and in[0]=='[', colon is not 0, so in[colon-1] is safe
116  bool fMultiColon{fHaveColon && colon != 0 && (in.find_last_of(':', colon - 1) != in.npos)};
117  if (fHaveColon && (colon == 0 || fBracketed || !fMultiColon)) {
118  uint16_t n;
119  if (ParseUInt16(in.substr(colon + 1), &n)) {
120  in = in.substr(0, colon);
121  portOut = n;
122  }
123  }
124  if (in.size() > 0 && in[0] == '[' && in[in.size() - 1] == ']') {
125  hostOut = in.substr(1, in.size() - 2);
126  } else {
127  hostOut = in;
128  }
129 }
130 
132 {
133  static const char *pbase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
134 
135  std::string str;
136  str.reserve(((input.size() + 2) / 3) * 4);
137  ConvertBits<8, 6, true>([&](int v) { str += pbase64[v]; }, input.begin(), input.end());
138  while (str.size() % 4) str += '=';
139  return str;
140 }
141 
142 std::vector<unsigned char> DecodeBase64(const char* p, bool* pf_invalid)
143 {
144  static const int8_t decode64_table[256]{
145  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
146  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
147  -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1,
148  -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
149  15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28,
150  29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
151  49, 50, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
152  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
153  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
154  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
155  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
156  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
157  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
158  };
159 
160  const char* e = p;
161  std::vector<uint8_t> val;
162  val.reserve(strlen(p));
163  while (*p != 0) {
164  int x = decode64_table[(unsigned char)*p];
165  if (x == -1) break;
166  val.push_back(uint8_t(x));
167  ++p;
168  }
169 
170  std::vector<unsigned char> ret;
171  ret.reserve((val.size() * 3) / 4);
172  bool valid = ConvertBits<6, 8, false>([&](unsigned char c) { ret.push_back(c); }, val.begin(), val.end());
173 
174  const char* q = p;
175  while (valid && *p != 0) {
176  if (*p != '=') {
177  valid = false;
178  break;
179  }
180  ++p;
181  }
182  valid = valid && (p - e) % 4 == 0 && p - q < 4;
183  if (pf_invalid) *pf_invalid = !valid;
184 
185  return ret;
186 }
187 
188 std::string DecodeBase64(const std::string& str, bool* pf_invalid)
189 {
190  if (!ValidAsCString(str)) {
191  if (pf_invalid) {
192  *pf_invalid = true;
193  }
194  return {};
195  }
196  std::vector<unsigned char> vchRet = DecodeBase64(str.c_str(), pf_invalid);
197  return std::string((const char*)vchRet.data(), vchRet.size());
198 }
199 
200 std::string EncodeBase32(Span<const unsigned char> input, bool pad)
201 {
202  static const char *pbase32 = "abcdefghijklmnopqrstuvwxyz234567";
203 
204  std::string str;
205  str.reserve(((input.size() + 4) / 5) * 8);
206  ConvertBits<8, 5, true>([&](int v) { str += pbase32[v]; }, input.begin(), input.end());
207  if (pad) {
208  while (str.size() % 8) {
209  str += '=';
210  }
211  }
212  return str;
213 }
214 
215 std::string EncodeBase32(const std::string& str, bool pad)
216 {
217  return EncodeBase32(MakeUCharSpan(str), pad);
218 }
219 
220 std::vector<unsigned char> DecodeBase32(const char* p, bool* pf_invalid)
221 {
222  static const int8_t decode32_table[256]{
223  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
224  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
225  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, -1, -1, -1, -1,
226  -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
227  15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 0, 1, 2,
228  3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
229  23, 24, 25, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
230  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
231  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
232  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
233  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
234  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
235  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
236  };
237 
238  const char* e = p;
239  std::vector<uint8_t> val;
240  val.reserve(strlen(p));
241  while (*p != 0) {
242  int x = decode32_table[(unsigned char)*p];
243  if (x == -1) break;
244  val.push_back(uint8_t(x));
245  ++p;
246  }
247 
248  std::vector<unsigned char> ret;
249  ret.reserve((val.size() * 5) / 8);
250  bool valid = ConvertBits<5, 8, false>([&](unsigned char c) { ret.push_back(c); }, val.begin(), val.end());
251 
252  const char* q = p;
253  while (valid && *p != 0) {
254  if (*p != '=') {
255  valid = false;
256  break;
257  }
258  ++p;
259  }
260  valid = valid && (p - e) % 8 == 0 && p - q < 8;
261  if (pf_invalid) *pf_invalid = !valid;
262 
263  return ret;
264 }
265 
266 std::string DecodeBase32(const std::string& str, bool* pf_invalid)
267 {
268  if (!ValidAsCString(str)) {
269  if (pf_invalid) {
270  *pf_invalid = true;
271  }
272  return {};
273  }
274  std::vector<unsigned char> vchRet = DecodeBase32(str.c_str(), pf_invalid);
275  return std::string((const char*)vchRet.data(), vchRet.size());
276 }
277 
278 namespace {
279 template <typename T>
280 bool ParseIntegral(const std::string& str, T* out)
281 {
282  static_assert(std::is_integral<T>::value);
283  // Replicate the exact behavior of strtol/strtoll/strtoul/strtoull when
284  // handling leading +/- for backwards compatibility.
285  if (str.length() >= 2 && str[0] == '+' && str[1] == '-') {
286  return false;
287  }
288  const std::optional<T> opt_int = ToIntegral<T>((!str.empty() && str[0] == '+') ? str.substr(1) : str);
289  if (!opt_int) {
290  return false;
291  }
292  if (out != nullptr) {
293  *out = *opt_int;
294  }
295  return true;
296 }
297 }; // namespace
298 
299 bool ParseInt32(const std::string& str, int32_t* out)
300 {
301  return ParseIntegral<int32_t>(str, out);
302 }
303 
304 bool ParseInt64(const std::string& str, int64_t* out)
305 {
306  return ParseIntegral<int64_t>(str, out);
307 }
308 
309 bool ParseUInt8(const std::string& str, uint8_t* out)
310 {
311  return ParseIntegral<uint8_t>(str, out);
312 }
313 
314 bool ParseUInt16(const std::string& str, uint16_t* out)
315 {
316  return ParseIntegral<uint16_t>(str, out);
317 }
318 
319 bool ParseUInt32(const std::string& str, uint32_t* out)
320 {
321  return ParseIntegral<uint32_t>(str, out);
322 }
323 
324 bool ParseUInt64(const std::string& str, uint64_t* out)
325 {
326  return ParseIntegral<uint64_t>(str, out);
327 }
328 
329 std::string FormatParagraph(const std::string& in, size_t width, size_t indent)
330 {
331  assert(width >= indent);
332  std::stringstream out;
333  size_t ptr = 0;
334  size_t indented = 0;
335  while (ptr < in.size())
336  {
337  size_t lineend = in.find_first_of('\n', ptr);
338  if (lineend == std::string::npos) {
339  lineend = in.size();
340  }
341  const size_t linelen = lineend - ptr;
342  const size_t rem_width = width - indented;
343  if (linelen <= rem_width) {
344  out << in.substr(ptr, linelen + 1);
345  ptr = lineend + 1;
346  indented = 0;
347  } else {
348  size_t finalspace = in.find_last_of(" \n", ptr + rem_width);
349  if (finalspace == std::string::npos || finalspace < ptr) {
350  // No place to break; just include the entire word and move on
351  finalspace = in.find_first_of("\n ", ptr);
352  if (finalspace == std::string::npos) {
353  // End of the string, just add it and break
354  out << in.substr(ptr);
355  break;
356  }
357  }
358  out << in.substr(ptr, finalspace - ptr) << "\n";
359  if (in[finalspace] == '\n') {
360  indented = 0;
361  } else if (indent) {
362  out << std::string(indent, ' ');
363  indented = indent;
364  }
365  ptr = finalspace + 1;
366  }
367  }
368  return out.str();
369 }
370 
379 static const int64_t UPPER_BOUND = 1000000000000000000LL - 1LL;
380 
382 static inline bool ProcessMantissaDigit(char ch, int64_t &mantissa, int &mantissa_tzeros)
383 {
384  if(ch == '0')
385  ++mantissa_tzeros;
386  else {
387  for (int i=0; i<=mantissa_tzeros; ++i) {
388  if (mantissa > (UPPER_BOUND / 10LL))
389  return false; /* overflow */
390  mantissa *= 10;
391  }
392  mantissa += ch - '0';
393  mantissa_tzeros = 0;
394  }
395  return true;
396 }
397 
398 bool ParseFixedPoint(const std::string &val, int decimals, int64_t *amount_out)
399 {
400  int64_t mantissa = 0;
401  int64_t exponent = 0;
402  int mantissa_tzeros = 0;
403  bool mantissa_sign = false;
404  bool exponent_sign = false;
405  int ptr = 0;
406  int end = val.size();
407  int point_ofs = 0;
408 
409  if (ptr < end && val[ptr] == '-') {
410  mantissa_sign = true;
411  ++ptr;
412  }
413  if (ptr < end)
414  {
415  if (val[ptr] == '0') {
416  /* pass single 0 */
417  ++ptr;
418  } else if (val[ptr] >= '1' && val[ptr] <= '9') {
419  while (ptr < end && IsDigit(val[ptr])) {
420  if (!ProcessMantissaDigit(val[ptr], mantissa, mantissa_tzeros))
421  return false; /* overflow */
422  ++ptr;
423  }
424  } else return false; /* missing expected digit */
425  } else return false; /* empty string or loose '-' */
426  if (ptr < end && val[ptr] == '.')
427  {
428  ++ptr;
429  if (ptr < end && IsDigit(val[ptr]))
430  {
431  while (ptr < end && IsDigit(val[ptr])) {
432  if (!ProcessMantissaDigit(val[ptr], mantissa, mantissa_tzeros))
433  return false; /* overflow */
434  ++ptr;
435  ++point_ofs;
436  }
437  } else return false; /* missing expected digit */
438  }
439  if (ptr < end && (val[ptr] == 'e' || val[ptr] == 'E'))
440  {
441  ++ptr;
442  if (ptr < end && val[ptr] == '+')
443  ++ptr;
444  else if (ptr < end && val[ptr] == '-') {
445  exponent_sign = true;
446  ++ptr;
447  }
448  if (ptr < end && IsDigit(val[ptr])) {
449  while (ptr < end && IsDigit(val[ptr])) {
450  if (exponent > (UPPER_BOUND / 10LL))
451  return false; /* overflow */
452  exponent = exponent * 10 + val[ptr] - '0';
453  ++ptr;
454  }
455  } else return false; /* missing expected digit */
456  }
457  if (ptr != end)
458  return false; /* trailing garbage */
459 
460  /* finalize exponent */
461  if (exponent_sign)
462  exponent = -exponent;
463  exponent = exponent - point_ofs + mantissa_tzeros;
464 
465  /* finalize mantissa */
466  if (mantissa_sign)
467  mantissa = -mantissa;
468 
469  /* convert to one 64-bit fixed-point value */
470  exponent += decimals;
471  if (exponent < 0)
472  return false; /* cannot represent values smaller than 10^-decimals */
473  if (exponent >= 18)
474  return false; /* cannot represent values larger than or equal to 10^(18-decimals) */
475 
476  for (int i=0; i < exponent; ++i) {
477  if (mantissa > (UPPER_BOUND / 10LL) || mantissa < -(UPPER_BOUND / 10LL))
478  return false; /* overflow */
479  mantissa *= 10;
480  }
481  if (mantissa > UPPER_BOUND || mantissa < -UPPER_BOUND)
482  return false; /* overflow */
483 
484  if (amount_out)
485  *amount_out = mantissa;
486 
487  return true;
488 }
489 
490 std::string ToLower(const std::string& str)
491 {
492  std::string r;
493  for (auto ch : str) r += ToLower(ch);
494  return r;
495 }
496 
497 std::string ToUpper(const std::string& str)
498 {
499  std::string r;
500  for (auto ch : str) r += ToUpper(ch);
501  return r;
502 }
503 
504 std::string Capitalize(std::string str)
505 {
506  if (str.empty()) return str;
507  str[0] = ToUpper(str.front());
508  return str;
509 }
510 
511 std::string HexStr(const Span<const uint8_t> s)
512 {
513  std::string rv(s.size() * 2, '\0');
514  static constexpr char hexmap[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
515  '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
516  auto it = rv.begin();
517  for (uint8_t v : s) {
518  *it++ = hexmap[v >> 4];
519  *it++ = hexmap[v & 15];
520  }
521  assert(it == rv.end());
522  return rv;
523 }
524 
525 std::optional<uint64_t> ParseByteUnits(const std::string& str, ByteUnit default_multiplier)
526 {
527  if (str.empty()) {
528  return std::nullopt;
529  }
530  auto multiplier = default_multiplier;
531  char unit = str.back();
532  switch (unit) {
533  case 'k':
534  multiplier = ByteUnit::k;
535  break;
536  case 'K':
537  multiplier = ByteUnit::K;
538  break;
539  case 'm':
540  multiplier = ByteUnit::m;
541  break;
542  case 'M':
543  multiplier = ByteUnit::M;
544  break;
545  case 'g':
546  multiplier = ByteUnit::g;
547  break;
548  case 'G':
549  multiplier = ByteUnit::G;
550  break;
551  case 't':
552  multiplier = ByteUnit::t;
553  break;
554  case 'T':
555  multiplier = ByteUnit::T;
556  break;
557  default:
558  unit = 0;
559  break;
560  }
561 
562  uint64_t unit_amount = static_cast<uint64_t>(multiplier);
563  auto parsed_num = ToIntegral<uint64_t>(unit ? str.substr(0, str.size() - 1) : str);
564  if (!parsed_num || parsed_num > std::numeric_limits<uint64_t>::max() / unit_amount) { // check overflow
565  return std::nullopt;
566  }
567  return *parsed_num * unit_amount;
568 }
ParseInt64
bool ParseInt64(const std::string &str, int64_t *out)
Convert string to signed 64-bit integer with strict parse error feedback.
Definition: strencodings.cpp:304
MakeUCharSpan
constexpr auto MakeUCharSpan(V &&v) -> decltype(UCharSpanCast(Span
Like the Span constructor, but for (const) unsigned char member types only.
Definition: span.h:285
ParseHex
std::vector< unsigned char > ParseHex(const char *psz)
Definition: strencodings.cpp:84
assert
assert(!tx.IsCoinBase())
ByteUnit::M
@ M
ParseFixedPoint
bool ParseFixedPoint(const std::string &val, int decimals, int64_t *amount_out)
Parse number as fixed point according to JSON number syntax.
Definition: strencodings.cpp:398
IsHexNumber
bool IsHexNumber(const std::string &str)
Return true if the string is a hex number, optionally prefixed with "0x".
Definition: strencodings.cpp:71
string.h
IsHex
bool IsHex(const std::string &str)
Definition: strencodings.cpp:61
ByteUnit
ByteUnit
Used by ParseByteUnits() Lowercase base 1000 Uppercase base 1024.
Definition: strencodings.h:38
EncodeBase64
std::string EncodeBase64(Span< const unsigned char > input)
Definition: strencodings.cpp:131
ValidAsCString
bool ValidAsCString(const std::string &str) noexcept
Check if a string does not contain any embedded NUL (\0) characters.
Definition: string.h:78
ParseUInt16
bool ParseUInt16(const std::string &str, uint16_t *out)
Convert decimal string to unsigned 16-bit integer with strict parse error feedback.
Definition: strencodings.cpp:314
IsSpace
constexpr bool IsSpace(char c) noexcept
Tests if the given character is a whitespace character.
Definition: strencodings.h:152
tinyformat.h
Span::size
constexpr std::size_t size() const noexcept
Definition: span.h:186
Span< const unsigned char >
ByteUnit::G
@ G
strencodings.h
p_util_hexdigit
const signed char p_util_hexdigit[256]
Definition: strencodings.cpp:38
SplitHostPort
void SplitHostPort(std::string in, uint16_t &portOut, std::string &hostOut)
Definition: strencodings.cpp:110
UPPER_BOUND
static const int64_t UPPER_BOUND
Upper bound for mantissa.
Definition: strencodings.cpp:379
HexDigit
signed char HexDigit(char c)
Definition: strencodings.cpp:56
DecodeBase64
std::vector< unsigned char > DecodeBase64(const char *p, bool *pf_invalid)
Definition: strencodings.cpp:142
Span::begin
constexpr C * begin() const noexcept
Definition: span.h:174
Capitalize
std::string Capitalize(std::string str)
Capitalizes the first character of the given string.
Definition: strencodings.cpp:504
ToUpper
std::string ToUpper(const std::string &str)
Returns the uppercase equivalent of the given string.
Definition: strencodings.cpp:497
CHARS_ALPHA_NUM
static const std::string CHARS_ALPHA_NUM
Definition: strencodings.cpp:17
EncodeBase32
std::string EncodeBase32(Span< const unsigned char > input, bool pad)
Base32 encode.
Definition: strencodings.cpp:200
IsDigit
constexpr bool IsDigit(char c)
Tests if the given character is a decimal digit.
Definition: strencodings.h:136
DecodeBase32
std::vector< unsigned char > DecodeBase32(const char *p, bool *pf_invalid)
Definition: strencodings.cpp:220
ParseUInt64
bool ParseUInt64(const std::string &str, uint64_t *out)
Convert decimal string to unsigned 64-bit integer with strict parse error feedback.
Definition: strencodings.cpp:324
SAFE_CHARS
static const std::string SAFE_CHARS[]
Definition: strencodings.cpp:19
ParseInt32
bool ParseInt32(const std::string &str, int32_t *out)
Convert string to signed 32-bit integer with strict parse error feedback.
Definition: strencodings.cpp:299
SanitizeString
std::string SanitizeString(const std::string &str, int rule)
Remove unsafe chars.
Definition: strencodings.cpp:27
ByteUnit::K
@ K
ByteUnit::T
@ T
ParseByteUnits
std::optional< uint64_t > ParseByteUnits(const std::string &str, ByteUnit default_multiplier)
Parse a string with suffix unit [k|K|m|M|g|G|t|T].
Definition: strencodings.cpp:525
ByteUnit::g
@ g
HexStr
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
Definition: strencodings.cpp:511
ByteUnit::m
@ m
ParseUInt8
bool ParseUInt8(const std::string &str, uint8_t *out)
Convert decimal string to unsigned 8-bit integer with strict parse error feedback.
Definition: strencodings.cpp:309
ProcessMantissaDigit
static bool ProcessMantissaDigit(char ch, int64_t &mantissa, int &mantissa_tzeros)
Helper function for ParseFixedPoint.
Definition: strencodings.cpp:382
ByteUnit::k
@ k
Span::end
constexpr C * end() const noexcept
Definition: span.h:175
ParseUInt32
bool ParseUInt32(const std::string &str, uint32_t *out)
Convert decimal string to unsigned 32-bit integer with strict parse error feedback.
Definition: strencodings.cpp:319
FormatParagraph
std::string FormatParagraph(const std::string &in, size_t width, size_t indent)
Format a paragraph of text to a fixed width, adding spaces for indentation to any added line.
Definition: strencodings.cpp:329
ByteUnit::t
@ t
ToLower
std::string ToLower(const std::string &str)
Returns the lowercase equivalent of the given string.
Definition: strencodings.cpp:490