CernVM-FS  2.13.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
string.cc
Go to the documentation of this file.
1 
7 #ifndef __STDC_FORMAT_MACROS
8 // NOLINTNEXTLINE
9 #define __STDC_FORMAT_MACROS
10 #endif
11 
12 #include "string.h"
13 
14 
15 #include <errno.h>
16 #include <fcntl.h>
17 #include <inttypes.h>
18 #include <stdint.h>
19 #include <unistd.h>
20 
21 #include <cstdio>
22 #include <cstdlib>
23 #include <cstring>
24 #include <ctime>
25 #include <string>
26 
27 using namespace std; // NOLINT
28 
29 #ifdef CVMFS_NAMESPACE_GUARD
30 namespace CVMFS_NAMESPACE_GUARD {
31 #endif
32 
33 const char b64_table[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',
34  'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
35  'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
36  'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
37  's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2',
38  '3', '4', '5', '6', '7', '8', '9', '+', '/'};
39 
43 const int8_t db64_table[] = {
44  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
45  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
46  -1, -1, -1, -1, -1, 62, -1, 62, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60,
47  61, -1, -1, -1, 0, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
48  11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1,
49  63, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
50  43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
51 
52  -1, -1, -1, -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, -1, -1, -1,
54  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
55  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
56  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
57  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
58  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
59 };
60 
61 namespace {
62 
68  bool operator()(const std::string::value_type a,
69  const std::string::value_type b) const {
70  return std::tolower(a) == std::tolower(b);
71  }
72 };
73 
74 } // anonymous namespace
75 
76 string StringifyBool(const bool value) { return value ? "yes" : "no"; }
77 
78 string StringifyInt(const int64_t value) {
79  char buffer[48];
80  snprintf(buffer, sizeof(buffer), "%" PRId64, value);
81  return string(buffer);
82 }
83 
84 std::string StringifyUint(const uint64_t value) {
85  char buffer[48];
86  snprintf(buffer, sizeof(buffer), "%" PRIu64, value);
87  return string(buffer);
88 }
89 
90 string StringifyByteAsHex(const unsigned char value) {
91  char buffer[3];
92  snprintf(buffer, sizeof(buffer), "%02x", value);
93  return string(buffer);
94 }
95 
96 string StringifyDouble(const double value) {
97  char buffer[64];
98  snprintf(buffer, sizeof(buffer), "%.03f", value);
99  return string(buffer);
100 }
101 
105 string StringifyTime(const time_t seconds, const bool utc) {
106  struct tm timestamp;
107  if (utc) {
108  localtime_r(&seconds, &timestamp);
109  } else {
110  gmtime_r(&seconds, &timestamp);
111  }
112 
113  const char *months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
114  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
115  char buffer[21];
116  snprintf(buffer, sizeof(buffer), "%d %s %d %02d:%02d:%02d", timestamp.tm_mday,
117  months[timestamp.tm_mon], timestamp.tm_year + 1900,
118  timestamp.tm_hour, timestamp.tm_min, timestamp.tm_sec);
119 
120  return string(buffer);
121 }
122 
126 string StringifyLocalTime(const time_t seconds) {
127  struct tm timestamp;
128  localtime_r(&seconds, &timestamp);
129 
130  const char *months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
131  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
132  char buffer[26];
133  (void)/* cast to void ignores return and placates clang-tidy */
134  snprintf(buffer, sizeof(buffer), "%d %s %d %02d:%02d:%02d %s", timestamp.tm_mday,
135  months[timestamp.tm_mon], timestamp.tm_year + 1900,
136  timestamp.tm_hour, timestamp.tm_min, timestamp.tm_sec, timestamp.tm_zone);
137 
138  return string(buffer);
139 }
140 
141 
145 std::string RfcTimestamp() {
146  const char *months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
147  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
148  const char *day_of_week[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
149 
150  struct tm timestamp;
151  time_t now = time(NULL);
152  gmtime_r(&now, &timestamp);
153 
154  char buffer[30];
155  snprintf(buffer, sizeof(buffer), "%s, %02d %s %d %02d:%02d:%02d %s",
156  day_of_week[timestamp.tm_wday], timestamp.tm_mday,
157  months[timestamp.tm_mon], timestamp.tm_year + 1900,
158  timestamp.tm_hour, timestamp.tm_min, timestamp.tm_sec,
159  timestamp.tm_zone);
160  return string(buffer);
161 }
162 
163 
167 std::string IsoTimestamp() {
168  struct tm timestamp;
169  time_t now = time(NULL);
170  gmtime_r(&now, &timestamp);
171 
172  char buffer[17];
173  snprintf(buffer, sizeof(buffer), "%04d%02d%02dT%02d%02d%02dZ",
174  timestamp.tm_year + 1900,
175  timestamp.tm_mon + 1,
176  timestamp.tm_mday,
177  timestamp.tm_hour,
178  timestamp.tm_min,
179  timestamp.tm_sec);
180  return string(buffer);
181 }
182 
183 
187 std::string WhitelistTimestamp(time_t when) {
188  struct tm timestamp;
189  gmtime_r(&when, &timestamp);
190 
191  char buffer[15];
192  snprintf(buffer, sizeof(buffer), "%04d%02d%02d%02d%02d%02d",
193  timestamp.tm_year + 1900,
194  timestamp.tm_mon + 1,
195  timestamp.tm_mday,
196  timestamp.tm_hour,
197  timestamp.tm_min,
198  timestamp.tm_sec);
199  return string(buffer);
200 }
201 
202 
203 string StringifyTimeval(const timeval value) {
204  char buffer[64];
205  int64_t msec = value.tv_sec * 1000;
206  msec += value.tv_usec / 1000;
207  snprintf(buffer, sizeof(buffer), "%" PRId64 ".%03d", msec,
208  static_cast<int>(value.tv_usec % 1000));
209  return string(buffer);
210 }
211 
216 time_t IsoTimestamp2UtcTime(const std::string &iso8601) {
217  time_t utc_time = 0;
218  unsigned length = iso8601.length();
219 
220  if (length != 20) return utc_time;
221  if ((iso8601[4] != '-') || (iso8601[7] != '-') || (iso8601[10] != 'T') ||
222  (iso8601[13] != ':') || (iso8601[16] != ':') || (iso8601[19] != 'Z')) {
223  return utc_time;
224  }
225 
226  struct tm tm_wl;
227  memset(&tm_wl, 0, sizeof(struct tm));
228  tm_wl.tm_year = static_cast<int>(String2Int64(iso8601.substr(0, 4))) - 1900;
229  tm_wl.tm_mon = static_cast<int>(String2Int64(iso8601.substr(5, 2))) - 1;
230  tm_wl.tm_mday = static_cast<int>(String2Int64(iso8601.substr(8, 2)));
231  tm_wl.tm_hour = static_cast<int>(String2Int64(iso8601.substr(11, 2)));
232  tm_wl.tm_min = static_cast<int>(String2Int64(iso8601.substr(14, 2)));
233  tm_wl.tm_sec = static_cast<int>(String2Int64(iso8601.substr(17, 2)));
234  utc_time = timegm(&tm_wl);
235  if (utc_time < 0) return 0;
236 
237  return utc_time;
238 }
239 
240 int64_t String2Int64(const string &value) {
241  int64_t result;
242  sscanf(value.c_str(), "%" PRId64, &result);
243  return result;
244 }
245 
246 uint64_t String2Uint64(const string &value) {
247  uint64_t result;
248  if (sscanf(value.c_str(), "%" PRIu64, &result) == 1) {
249  return result;
250  }
251  return 0;
252 }
253 
263 bool String2Uint64Parse(const std::string &value, uint64_t *result) {
264  char *endptr = NULL;
265  errno = 0;
266  long long myval = strtoll(value.c_str(), &endptr, 10); // NOLINT
267  if ((value.size() == 0) || (endptr != (value.c_str() + value.size())) ||
268  (myval < 0)) {
269  errno = EINVAL;
270  return false;
271  }
272  if (errno) {
273  return false;
274  }
275  if (result) {
276  *result = myval;
277  }
278  return true;
279 }
280 
281 void String2Uint64Pair(const string &value, uint64_t *a, uint64_t *b) {
282  sscanf(value.c_str(), "%" PRIu64 " %" PRIu64, a, b);
283 }
284 
285 bool HasPrefix(const string &str, const string &prefix,
286  const bool ignore_case) {
287  if (prefix.length() > str.length()) return false;
288 
289  for (unsigned i = 0, l = prefix.length(); i < l; ++i) {
290  if (ignore_case) {
291  if (toupper(str[i]) != toupper(prefix[i])) return false;
292  } else {
293  if (str[i] != prefix[i]) return false;
294  }
295  }
296  return true;
297 }
298 
299 bool HasSuffix(const std::string &str, const std::string &suffix,
300  const bool ignore_case) {
301  if (suffix.size() > str.size()) return false;
302  const IgnoreCaseComperator icmp;
303  return (ignore_case)
304  ? std::equal(suffix.rbegin(), suffix.rend(), str.rbegin(), icmp)
305  : std::equal(suffix.rbegin(), suffix.rend(), str.rbegin());
306 }
307 
308 vector<string> SplitString(const string &str, char delim) {
309  return SplitStringBounded(0, str, delim);
310 }
311 
312 vector<string> SplitStringBounded(
313  unsigned max_chunks, const string &str, char delim)
314 {
315  vector<string> result;
316 
317  // edge case... one chunk is always the whole string
318  if (1 == max_chunks) {
319  result.push_back(str);
320  return result;
321  }
322 
323  // split the string
324  const unsigned size = str.size();
325  unsigned marker = 0;
326  unsigned chunks = 1;
327  unsigned i;
328  for (i = 0; i < size; ++i) {
329  if (str[i] == delim) {
330  result.push_back(str.substr(marker, i - marker));
331  marker = i + 1;
332 
333  // we got what we want... good bye
334  if (++chunks == max_chunks) break;
335  }
336  }
337 
338  // push the remainings of the string and return
339  result.push_back(str.substr(marker));
340  return result;
341 }
342 
343 vector<string> SplitStringMultiChar(const string &str, const string &delim) {
344  size_t pos_start = 0, pos_end = 0, delim_len = delim.length();
345  std::string substring;
346  std::vector<std::string> result;
347 
348  while ((pos_end = str.find(delim, pos_start)) != string::npos) {
349  substring = str.substr (pos_start, pos_end - pos_start);
350  pos_start = pos_end + delim_len;
351  result.push_back(substring);
352  }
353 
354  result.push_back(str.substr(pos_start));
355  return result;
356 
357 }
358 
359 string JoinStrings(const vector<string> &strings, const string &joint) {
360  string result = "";
361  const unsigned size = strings.size();
362 
363  if (size > 0) {
364  result = strings[0];
365  for (unsigned i = 1; i < size; ++i) result += joint + strings[i];
366  }
367 
368  return result;
369 }
370 
371 void ParseKeyvalMem(const unsigned char *buffer, const unsigned buffer_size,
372  map<char, string> *content) {
373  string line;
374  unsigned pos = 0;
375  while (pos < buffer_size) {
376  if (static_cast<char>(buffer[pos]) == '\n') {
377  if (line == "--") return;
378 
379  if (line != "") {
380  const string tail = (line.length() == 1) ? "" : line.substr(1);
381  // Special handling of 'Z' key because it can exist multiple times
382  if (line[0] != 'Z') {
383  (*content)[line[0]] = tail;
384  } else {
385  if (content->find(line[0]) == content->end()) {
386  (*content)[line[0]] = tail;
387  } else {
388  (*content)[line[0]] = (*content)[line[0]] + "|" + tail;
389  }
390  }
391  }
392  line = "";
393  } else {
394  line += static_cast<char>(buffer[pos]);
395  }
396  pos++;
397  }
398 }
399 
400 bool ParseKeyvalPath(const string &filename, map<char, string> *content) {
401  int fd = open(filename.c_str(), O_RDONLY);
402  if (fd < 0) return false;
403 
404  unsigned char buffer[4096];
405  ssize_t num_bytes = read(fd, buffer, sizeof(buffer));
406  close(fd);
407 
408  if ((num_bytes <= 0) || (unsigned(num_bytes) >= sizeof(buffer))) return false;
409 
410  ParseKeyvalMem(buffer, unsigned(num_bytes), content);
411  return true;
412 }
413 
414 string GetLineMem(const char *text, const int text_size) {
415  int pos = 0;
416  while ((pos < text_size) && (text[pos] != '\n')) pos++;
417  return string(text, pos);
418 }
419 
420 bool GetLineFile(FILE *f, std::string *line) {
421  int retval;
422  line->clear();
423  while (true) {
424  retval = fgetc(f);
425  if (ferror(f) && (errno == EINTR)) {
426  clearerr(f);
427  continue;
428  } else if (retval == EOF) {
429  break;
430  }
431  char c = static_cast<char>(retval);
432  if (c == '\n') break;
433  line->push_back(c);
434  }
435  return (retval != EOF) || !line->empty();
436 }
437 
438 bool GetLineFd(const int fd, std::string *line) {
439  ssize_t retval;
440  char c;
441  line->clear();
442  while (true) {
443  retval = read(fd, &c, 1);
444  if (retval == 0) {
445  break;
446  }
447  if ((retval == -1) && (errno == EINTR)) {
448  continue;
449  }
450  if (retval == -1) {
451  break;
452  }
453  if (c == '\n') break;
454  line->push_back(c);
455  }
456  return (retval == 1) || !line->empty();
457 }
458 
462 string Trim(const string &raw, bool trim_newline) {
463  if (raw.empty()) return "";
464 
465  unsigned start_pos = 0;
466  for (; (start_pos < raw.length()) &&
467  (raw[start_pos] == ' ' || raw[start_pos] == '\t' ||
468  (trim_newline && (raw[start_pos] == '\n' || raw[start_pos] == '\r')));
469  ++start_pos)
470  {
471  }
472  unsigned end_pos = raw.length() - 1; // at least one character in raw
473  for (;
474  (end_pos >= start_pos) &&
475  (raw[end_pos] == ' ' || raw[end_pos] == '\t' ||
476  (trim_newline && (raw[end_pos] == '\n' || raw[end_pos] == '\r')));
477  --end_pos)
478  {
479  }
480 
481  return raw.substr(start_pos, end_pos - start_pos + 1);
482 }
483 
484 std::string TrimString(
485  const std::string& path,
486  const std::string& toTrim,
487  const int trimMode)
488 {
489  std::string trimmed = path;
490  if (trimmed != toTrim) {
491  while ((trimMode & kTrimLeading) &&
492  HasPrefix(trimmed, toTrim, true) &&
493  (trimmed.size() > toTrim.size()))
494  {
495  trimmed = trimmed.substr(toTrim.size());
496  }
497  while ((trimMode & kTrimTrailing) &&
498  HasSuffix(trimmed, toTrim, true) &&
499  (trimmed.size() > toTrim.size()))
500  {
501  trimmed = trimmed.substr(0, trimmed.size() - toTrim.size());
502  }
503  }
504  return trimmed;
505 }
506 
510 string ToUpper(const string &mixed_case) {
511  string result(mixed_case);
512  for (unsigned i = 0, l = result.length(); i < l; ++i) {
513  result[i] = static_cast<char>(toupper(result[i]));
514  }
515  return result;
516 }
517 
518 string ReplaceAll(const string &haystack, const string &needle,
519  const string &replace_by) {
520  string result(haystack);
521  size_t pos = 0;
522  const unsigned needle_size = needle.size();
523  if (needle == "") return result;
524 
525  while ((pos = result.find(needle, pos)) != string::npos)
526  result.replace(pos, needle_size, replace_by);
527  return result;
528 }
529 
530 static inline void Base64Block(const unsigned char input[3], const char *table,
531  char output[4]) {
532  output[0] = table[(input[0] & 0xFD) >> 2];
533  output[1] = table[((input[0] & 0x03) << 4) | ((input[1] & 0xF0) >> 4)];
534  output[2] = table[((input[1] & 0x0F) << 2) | ((input[2] & 0xD0) >> 6)];
535  output[3] = table[input[2] & 0x3F];
536 }
537 
538 string Base64(const string &data) {
539  string result;
540  result.reserve((data.length() + 3) * 4 / 3);
541  unsigned pos = 0;
542  const unsigned char *data_ptr =
543  reinterpret_cast<const unsigned char *>(data.data());
544  const unsigned length = data.length();
545  while (pos + 2 < length) {
546  char encoded_block[4];
547  Base64Block(data_ptr + pos, b64_table, encoded_block);
548  result.append(encoded_block, 4);
549  pos += 3;
550  }
551  if (length % 3 != 0) {
552  unsigned char input[3];
553  input[0] = data_ptr[pos];
554  input[1] = ((length % 3) == 2) ? data_ptr[pos + 1] : 0;
555  input[2] = 0;
556  char encoded_block[4];
557  Base64Block(input, b64_table, encoded_block);
558  result.append(encoded_block, 2);
559  result.push_back(((length % 3) == 2) ? encoded_block[2] : '=');
560  result.push_back('=');
561  }
562 
563  return result;
564 }
565 
569 string Base64Url(const string &data) {
570  string base64 = Base64(data);
571  for (unsigned i = 0, l = base64.length(); i < l; ++i) {
572  if (base64[i] == '+') {
573  base64[i] = '-';
574  } else if (base64[i] == '/') {
575  base64[i] = '_';
576  }
577  }
578  return base64;
579 }
580 
581 static bool Debase64Block(const unsigned char input[4], unsigned char output[3])
582 {
583  int32_t dec[4];
584  for (int i = 0; i < 4; ++i) {
585  dec[i] = db64_table[input[i]];
586  if (dec[i] < 0) return false;
587  }
588 
589  output[0] = (dec[0] << 2) | (dec[1] >> 4);
590  output[1] = ((dec[1] & 0x0F) << 4) | (dec[2] >> 2);
591  output[2] = ((dec[2] & 0x03) << 6) | dec[3];
592  return true;
593 }
594 
598 bool Debase64(const string &data, string *decoded) {
599  decoded->clear();
600  decoded->reserve((data.length() + 4) * 3 / 4);
601  unsigned pos = 0;
602  const unsigned char *data_ptr =
603  reinterpret_cast<const unsigned char *>(data.data());
604  const unsigned length = data.length();
605  if (length == 0) return true;
606  if ((length % 4) != 0) return false;
607 
608  while (pos < length) {
609  unsigned char decoded_block[3];
610  bool retval = Debase64Block(data_ptr + pos, decoded_block);
611  if (!retval) return false;
612  decoded->append(reinterpret_cast<char *>(decoded_block), 3);
613  pos += 4;
614  }
615 
616  for (int i = 0; i < 2; ++i) {
617  pos--;
618  if (data[pos] == '=') decoded->erase(decoded->length() - 1);
619  }
620  return true;
621 }
622 
626 string Tail(const string &source, unsigned num_lines) {
627  if (source.empty() || (num_lines == 0)) return "";
628 
629  int l = static_cast<int>(source.length());
630  int i = l - 1;
631  for (; i >= 0; --i) {
632  char c = source.data()[i];
633  if (c == '\n') {
634  if (num_lines == 0) {
635  return source.substr(i + 1);
636  }
637  num_lines--;
638  }
639  }
640  return source;
641 }
642 
649 std::string GetGMTimestamp(const std::string &format) {
650  struct tm time_ptr;
651  char date_and_time[100];
652  time_t t = time(NULL);
653  gmtime_r(&t, &time_ptr); // take UTC
654  // return empty string if formatting fails
655  if (!strftime(date_and_time, 100, format.c_str(), &time_ptr)) {
656  return "";
657  }
658  std::string timestamp(date_and_time);
659  return timestamp;
660 }
661 
662 #ifdef CVMFS_NAMESPACE_GUARD
663 } // namespace CVMFS_NAMESPACE_GUARD
664 #endif
string GetLineMem(const char *text, const int text_size)
Definition: string.cc:414
std::string GetGMTimestamp(const std::string &format)
Definition: string.cc:649
string StringifyLocalTime(const time_t seconds)
Definition: string.cc:126
std::string IsoTimestamp()
Definition: string.cc:167
string Trim(const string &raw, bool trim_newline)
Definition: string.cc:462
string ReplaceAll(const string &haystack, const string &needle, const string &replace_by)
Definition: string.cc:518
static void Base64Block(const unsigned char input[3], const char *table, char output[4])
Definition: string.cc:530
string JoinStrings(const vector< string > &strings, const string &joint)
Definition: string.cc:359
const int kTrimLeading
Definition: string.h:19
string Tail(const string &source, unsigned num_lines)
Definition: string.cc:626
const int kTrimTrailing
Definition: string.h:20
string StringifyTime(const time_t seconds, const bool utc)
Definition: string.cc:105
string StringifyDouble(const double value)
Definition: string.cc:96
std::string StringifyUint(const uint64_t value)
Definition: string.cc:84
bool Debase64(const string &data, string *decoded)
Definition: string.cc:598
string StringifyByteAsHex(const unsigned char value)
Definition: string.cc:90
string StringifyBool(const bool value)
Definition: string.cc:76
bool String2Uint64Parse(const std::string &value, uint64_t *result)
Definition: string.cc:263
string Base64Url(const string &data)
Definition: string.cc:569
std::string RfcTimestamp()
Definition: string.cc:145
int64_t String2Int64(const string &value)
Definition: string.cc:240
bool GetLineFile(FILE *f, std::string *line)
Definition: string.cc:420
string ToUpper(const string &mixed_case)
Definition: string.cc:510
vector< string > SplitString(const string &str, char delim)
Definition: string.cc:308
bool HasSuffix(const std::string &str, const std::string &suffix, const bool ignore_case)
Definition: string.cc:299
std::string WhitelistTimestamp(time_t when)
Definition: string.cc:187
vector< string > SplitStringBounded(unsigned max_chunks, const string &str, char delim)
Definition: string.cc:312
string StringifyInt(const int64_t value)
Definition: string.cc:78
vector< string > SplitStringMultiChar(const string &str, const string &delim)
Definition: string.cc:343
bool HasPrefix(const string &str, const string &prefix, const bool ignore_case)
Definition: string.cc:285
const int const char * format
Definition: logging.h:23
time_t IsoTimestamp2UtcTime(const std::string &iso8601)
Definition: string.cc:216
bool GetLineFd(const int fd, std::string *line)
Definition: string.cc:438
string Base64(const string &data)
Definition: string.cc:538
uint64_t String2Uint64(const string &value)
Definition: string.cc:246
bool operator()(const std::string::value_type a, const std::string::value_type b) const
Definition: string.cc:68
bool ParseKeyvalPath(const string &filename, map< char, string > *content)
Definition: string.cc:400
std::string TrimString(const std::string &path, const std::string &toTrim, const int trimMode)
Definition: string.cc:484
static bool Debase64Block(const unsigned char input[4], unsigned char output[3])
Definition: string.cc:581
const char b64_table[]
Definition: string.cc:33
string StringifyTimeval(const timeval value)
Definition: string.cc:203
const int8_t db64_table[]
Definition: string.cc:43
static void size_t size
Definition: smalloc.h:54
void ParseKeyvalMem(const unsigned char *buffer, const unsigned buffer_size, map< char, string > *content)
Definition: string.cc:371
void String2Uint64Pair(const string &value, uint64_t *a, uint64_t *b)
Definition: string.cc:281