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