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 && (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  std::stringstream out;
332  size_t ptr = 0;
333  size_t indented = 0;
334  while (ptr < in.size())
335  {
336  size_t lineend = in.find_first_of('\n', ptr);
337  if (lineend == std::string::npos) {
338  lineend = in.size();
339  }
340  const size_t linelen = lineend - ptr;
341  const size_t rem_width = width - indented;
342  if (linelen <= rem_width) {
343  out << in.substr(ptr, linelen + 1);
344  ptr = lineend + 1;
345  indented = 0;
346  } else {
347  size_t finalspace = in.find_last_of(" \n", ptr + rem_width);
348  if (finalspace == std::string::npos || finalspace < ptr) {
349  // No place to break; just include the entire word and move on
350  finalspace = in.find_first_of("\n ", ptr);
351  if (finalspace == std::string::npos) {
352  // End of the string, just add it and break
353  out << in.substr(ptr);
354  break;
355  }
356  }
357  out << in.substr(ptr, finalspace - ptr) << "\n";
358  if (in[finalspace] == '\n') {
359  indented = 0;
360  } else if (indent) {
361  out << std::string(indent, ' ');
362  indented = indent;
363  }
364  ptr = finalspace + 1;
365  }
366  }
367  return out.str();
368 }
369 
378 static const int64_t UPPER_BOUND = 1000000000000000000LL - 1LL;
379 
381 static inline bool ProcessMantissaDigit(char ch, int64_t &mantissa, int &mantissa_tzeros)
382 {
383  if(ch == '0')
384  ++mantissa_tzeros;
385  else {
386  for (int i=0; i<=mantissa_tzeros; ++i) {
387  if (mantissa > (UPPER_BOUND / 10LL))
388  return false; /* overflow */
389  mantissa *= 10;
390  }
391  mantissa += ch - '0';
392  mantissa_tzeros = 0;
393  }
394  return true;
395 }
396 
397 bool ParseFixedPoint(const std::string &val, int decimals, int64_t *amount_out)
398 {
399  int64_t mantissa = 0;
400  int64_t exponent = 0;
401  int mantissa_tzeros = 0;
402  bool mantissa_sign = false;
403  bool exponent_sign = false;
404  int ptr = 0;
405  int end = val.size();
406  int point_ofs = 0;
407 
408  if (ptr < end && val[ptr] == '-') {
409  mantissa_sign = true;
410  ++ptr;
411  }
412  if (ptr < end)
413  {
414  if (val[ptr] == '0') {
415  /* pass single 0 */
416  ++ptr;
417  } else if (val[ptr] >= '1' && val[ptr] <= '9') {
418  while (ptr < end && IsDigit(val[ptr])) {
419  if (!ProcessMantissaDigit(val[ptr], mantissa, mantissa_tzeros))
420  return false; /* overflow */
421  ++ptr;
422  }
423  } else return false; /* missing expected digit */
424  } else return false; /* empty string or loose '-' */
425  if (ptr < end && val[ptr] == '.')
426  {
427  ++ptr;
428  if (ptr < end && IsDigit(val[ptr]))
429  {
430  while (ptr < end && IsDigit(val[ptr])) {
431  if (!ProcessMantissaDigit(val[ptr], mantissa, mantissa_tzeros))
432  return false; /* overflow */
433  ++ptr;
434  ++point_ofs;
435  }
436  } else return false; /* missing expected digit */
437  }
438  if (ptr < end && (val[ptr] == 'e' || val[ptr] == 'E'))
439  {
440  ++ptr;
441  if (ptr < end && val[ptr] == '+')
442  ++ptr;
443  else if (ptr < end && val[ptr] == '-') {
444  exponent_sign = true;
445  ++ptr;
446  }
447  if (ptr < end && IsDigit(val[ptr])) {
448  while (ptr < end && IsDigit(val[ptr])) {
449  if (exponent > (UPPER_BOUND / 10LL))
450  return false; /* overflow */
451  exponent = exponent * 10 + val[ptr] - '0';
452  ++ptr;
453  }
454  } else return false; /* missing expected digit */
455  }
456  if (ptr != end)
457  return false; /* trailing garbage */
458 
459  /* finalize exponent */
460  if (exponent_sign)
461  exponent = -exponent;
462  exponent = exponent - point_ofs + mantissa_tzeros;
463 
464  /* finalize mantissa */
465  if (mantissa_sign)
466  mantissa = -mantissa;
467 
468  /* convert to one 64-bit fixed-point value */
469  exponent += decimals;
470  if (exponent < 0)
471  return false; /* cannot represent values smaller than 10^-decimals */
472  if (exponent >= 18)
473  return false; /* cannot represent values larger than or equal to 10^(18-decimals) */
474 
475  for (int i=0; i < exponent; ++i) {
476  if (mantissa > (UPPER_BOUND / 10LL) || mantissa < -(UPPER_BOUND / 10LL))
477  return false; /* overflow */
478  mantissa *= 10;
479  }
480  if (mantissa > UPPER_BOUND || mantissa < -UPPER_BOUND)
481  return false; /* overflow */
482 
483  if (amount_out)
484  *amount_out = mantissa;
485 
486  return true;
487 }
488 
489 std::string ToLower(const std::string& str)
490 {
491  std::string r;
492  for (auto ch : str) r += ToLower(ch);
493  return r;
494 }
495 
496 std::string ToUpper(const std::string& str)
497 {
498  std::string r;
499  for (auto ch : str) r += ToUpper(ch);
500  return r;
501 }
502 
503 std::string Capitalize(std::string str)
504 {
505  if (str.empty()) return str;
506  str[0] = ToUpper(str.front());
507  return str;
508 }
509 
510 std::string HexStr(const Span<const uint8_t> s)
511 {
512  std::string rv(s.size() * 2, '\0');
513  static constexpr char hexmap[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
514  '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
515  auto it = rv.begin();
516  for (uint8_t v : s) {
517  *it++ = hexmap[v >> 4];
518  *it++ = hexmap[v & 15];
519  }
520  assert(it == rv.end());
521  return rv;
522 }
523 
524 std::optional<uint64_t> ParseByteUnits(const std::string& str, ByteUnit default_multiplier)
525 {
526  if (str.empty()) {
527  return std::nullopt;
528  }
529  auto multiplier = default_multiplier;
530  char unit = str.back();
531  switch (unit) {
532  case 'k':
533  multiplier = ByteUnit::k;
534  break;
535  case 'K':
536  multiplier = ByteUnit::K;
537  break;
538  case 'm':
539  multiplier = ByteUnit::m;
540  break;
541  case 'M':
542  multiplier = ByteUnit::M;
543  break;
544  case 'g':
545  multiplier = ByteUnit::g;
546  break;
547  case 'G':
548  multiplier = ByteUnit::G;
549  break;
550  case 't':
551  multiplier = ByteUnit::t;
552  break;
553  case 'T':
554  multiplier = ByteUnit::T;
555  break;
556  default:
557  unit = 0;
558  break;
559  }
560 
561  uint64_t unit_amount = static_cast<uint64_t>(multiplier);
562  auto parsed_num = ToIntegral<uint64_t>(unit ? str.substr(0, str.size() - 1) : str);
563  if (!parsed_num || parsed_num > std::numeric_limits<uint64_t>::max() / unit_amount) { // check overflow
564  return std::nullopt;
565  }
566  return *parsed_num * unit_amount;
567 }
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:280
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:397
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:378
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:503
ToUpper
std::string ToUpper(const std::string &str)
Returns the uppercase equivalent of the given string.
Definition: strencodings.cpp:496
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:524
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:510
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:381
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:489