7 #ifndef __STDC_FORMAT_MACROS
9 #define __STDC_FORMAT_MACROS
29 #ifdef CVMFS_NAMESPACE_GUARD
30 namespace CVMFS_NAMESPACE_GUARD {
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',
'+',
'/'};
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,
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,
69 const std::string::value_type b)
const {
70 return std::tolower(a) == std::tolower(b);
80 snprintf(buffer,
sizeof(buffer),
"%" PRId64, value);
81 return string(buffer);
86 snprintf(buffer,
sizeof(buffer),
"%" PRIu64, value);
87 return string(buffer);
92 snprintf(buffer,
sizeof(buffer),
"%02x", value);
93 return string(buffer);
98 snprintf(buffer,
sizeof(buffer),
"%.03f", value);
99 return string(buffer);
108 localtime_r(&seconds, ×tamp);
110 gmtime_r(&seconds, ×tamp);
113 const char *months[] = {
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
114 "Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec"};
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);
120 return string(buffer);
128 localtime_r(&seconds, ×tamp);
130 const char *months[] = {
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
131 "Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec"};
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);
138 return string(buffer);
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"};
151 time_t now = time(NULL);
152 gmtime_r(&now, ×tamp);
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,
160 return string(buffer);
169 time_t now = time(NULL);
170 gmtime_r(&now, ×tamp);
173 snprintf(buffer,
sizeof(buffer),
"%04d%02d%02dT%02d%02d%02dZ",
174 timestamp.tm_year + 1900,
175 timestamp.tm_mon + 1,
180 return string(buffer);
189 gmtime_r(&when, ×tamp);
192 snprintf(buffer,
sizeof(buffer),
"%04d%02d%02d%02d%02d%02d",
193 timestamp.tm_year + 1900,
194 timestamp.tm_mon + 1,
199 return string(buffer);
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);
218 unsigned length = iso8601.length();
220 if (length != 20)
return utc_time;
221 if ((iso8601[4] !=
'-') || (iso8601[7] !=
'-') || (iso8601[10] !=
'T') ||
222 (iso8601[13] !=
':') || (iso8601[16] !=
':') || (iso8601[19] !=
'Z')) {
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;
242 sscanf(value.c_str(),
"%" PRId64, &result);
248 if (sscanf(value.c_str(),
"%" PRIu64, &result) == 1) {
266 long long myval = strtoll(value.c_str(), &endptr, 10);
267 if ((value.size() == 0) || (endptr != (value.c_str() + value.size())) ||
282 sscanf(value.c_str(),
"%" PRIu64
" %" PRIu64, a, b);
286 const bool ignore_case) {
287 if (prefix.length() > str.length())
return false;
289 for (
unsigned i = 0, l = prefix.length(); i < l; ++i) {
291 if (toupper(str[i]) != toupper(prefix[i]))
return false;
293 if (str[i] != prefix[i])
return false;
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;
304 ? std::equal(suffix.rbegin(), suffix.rend(), str.rbegin(), icmp)
305 : std::equal(suffix.rbegin(), suffix.rend(), str.rbegin());
313 unsigned max_chunks,
const string &str,
char delim)
315 vector<string> result;
318 if (1 == max_chunks) {
319 result.push_back(str);
324 const unsigned size = str.size();
328 for (i = 0; i <
size; ++i) {
329 if (str[i] == delim) {
330 result.push_back(str.substr(marker, i - marker));
334 if (++chunks == max_chunks)
break;
339 result.push_back(str.substr(marker));
343 string JoinStrings(
const vector<string> &strings,
const string &joint) {
345 const unsigned size = strings.size();
349 for (
unsigned i = 1; i <
size; ++i) result += joint + strings[i];
356 map<char, string> *content) {
359 while (pos < buffer_size) {
360 if (static_cast<char>(buffer[pos]) ==
'\n') {
361 if (line ==
"--")
return;
364 const string tail = (line.length() == 1) ?
"" : line.substr(1);
366 if (line[0] !=
'Z') {
367 (*content)[line[0]] = tail;
369 if (content->find(line[0]) == content->end()) {
370 (*content)[line[0]] = tail;
372 (*content)[line[0]] = (*content)[line[0]] +
"|" + tail;
378 line +=
static_cast<char>(buffer[pos]);
385 int fd = open(filename.c_str(), O_RDONLY);
386 if (fd < 0)
return false;
388 unsigned char buffer[4096];
389 ssize_t num_bytes = read(fd, buffer,
sizeof(buffer));
392 if ((num_bytes <= 0) || (
unsigned(num_bytes) >=
sizeof(buffer)))
return false;
400 while ((pos < text_size) && (text[pos] !=
'\n')) pos++;
401 return string(text, pos);
409 if (ferror(f) && (errno == EINTR)) {
412 }
else if (retval == EOF) {
415 char c =
static_cast<char>(retval);
416 if (c ==
'\n')
break;
419 return (retval != EOF) || !line->empty();
427 retval = read(fd, &c, 1);
431 if ((retval == -1) && (errno == EINTR)) {
437 if (c ==
'\n')
break;
440 return (retval == 1) || !line->empty();
446 string Trim(
const string &raw,
bool trim_newline) {
447 if (raw.empty())
return "";
449 unsigned start_pos = 0;
450 for (; (start_pos < raw.length()) &&
451 (raw[start_pos] ==
' ' || raw[start_pos] ==
'\t' ||
452 (trim_newline && (raw[start_pos] ==
'\n' || raw[start_pos] ==
'\r')));
456 unsigned end_pos = raw.length() - 1;
458 (end_pos >= start_pos) &&
459 (raw[end_pos] ==
' ' || raw[end_pos] ==
'\t' ||
460 (trim_newline && (raw[end_pos] ==
'\n' || raw[end_pos] ==
'\r')));
465 return raw.substr(start_pos, end_pos - start_pos + 1);
469 const std::string& path,
470 const std::string& toTrim,
473 std::string trimmed = path;
474 if (trimmed != toTrim) {
477 (trimmed.size() > toTrim.size()))
479 trimmed = trimmed.substr(toTrim.size());
483 (trimmed.size() > toTrim.size()))
485 trimmed = trimmed.substr(0, trimmed.size() - toTrim.size());
495 string result(mixed_case);
496 for (
unsigned i = 0, l = result.length(); i < l; ++i) {
497 result[i] =
static_cast<char>(toupper(result[i]));
502 string ReplaceAll(
const string &haystack,
const string &needle,
503 const string &replace_by) {
504 string result(haystack);
506 const unsigned needle_size = needle.size();
507 if (needle ==
"")
return result;
509 while ((pos = result.find(needle, pos)) != string::npos)
510 result.replace(pos, needle_size, replace_by);
514 static inline void Base64Block(
const unsigned char input[3],
const char *table,
516 output[0] = table[(input[0] & 0xFD) >> 2];
517 output[1] = table[((input[0] & 0x03) << 4) | ((input[1] & 0xF0) >> 4)];
518 output[2] = table[((input[1] & 0x0F) << 2) | ((input[2] & 0xD0) >> 6)];
519 output[3] = table[input[2] & 0x3F];
524 result.reserve((data.length() + 3) * 4 / 3);
526 const unsigned char *data_ptr =
527 reinterpret_cast<const unsigned char *
>(data.data());
528 const unsigned length = data.length();
529 while (pos + 2 < length) {
530 char encoded_block[4];
532 result.append(encoded_block, 4);
535 if (length % 3 != 0) {
536 unsigned char input[3];
537 input[0] = data_ptr[pos];
538 input[1] = ((length % 3) == 2) ? data_ptr[pos + 1] : 0;
540 char encoded_block[4];
542 result.append(encoded_block, 2);
543 result.push_back(((length % 3) == 2) ? encoded_block[2] :
'=');
544 result.push_back(
'=');
554 string base64 =
Base64(data);
555 for (
unsigned i = 0, l = base64.length(); i < l; ++i) {
556 if (base64[i] ==
'+') {
558 }
else if (base64[i] ==
'/') {
565 static bool Debase64Block(
const unsigned char input[4],
unsigned char output[3])
568 for (
int i = 0; i < 4; ++i) {
570 if (dec[i] < 0)
return false;
573 output[0] = (dec[0] << 2) | (dec[1] >> 4);
574 output[1] = ((dec[1] & 0x0F) << 4) | (dec[2] >> 2);
575 output[2] = ((dec[2] & 0x03) << 6) | dec[3];
582 bool Debase64(
const string &data,
string *decoded) {
584 decoded->reserve((data.length() + 4) * 3 / 4);
586 const unsigned char *data_ptr =
587 reinterpret_cast<const unsigned char *
>(data.data());
588 const unsigned length = data.length();
589 if (length == 0)
return true;
590 if ((length % 4) != 0)
return false;
592 while (pos < length) {
593 unsigned char decoded_block[3];
595 if (!retval)
return false;
596 decoded->append(reinterpret_cast<char *>(decoded_block), 3);
600 for (
int i = 0; i < 2; ++i) {
602 if (data[pos] ==
'=') decoded->erase(decoded->length() - 1);
610 string Tail(
const string &source,
unsigned num_lines) {
611 if (source.empty() || (num_lines == 0))
return "";
613 int l =
static_cast<int>(source.length());
615 for (; i >= 0; --i) {
616 char c = source.data()[i];
618 if (num_lines == 0) {
619 return source.substr(i + 1);
635 char date_and_time[100];
636 time_t t = time(NULL);
637 gmtime_r(&t, &time_ptr);
639 if (!strftime(date_and_time, 100, format.c_str(), &time_ptr)) {
642 std::string timestamp(date_and_time);
646 #ifdef CVMFS_NAMESPACE_GUARD
string GetLineMem(const char *text, const int text_size)
std::string GetGMTimestamp(const std::string &format)
string StringifyLocalTime(const time_t seconds)
std::string IsoTimestamp()
string Trim(const string &raw, bool trim_newline)
string ReplaceAll(const string &haystack, const string &needle, const string &replace_by)
static void Base64Block(const unsigned char input[3], const char *table, char output[4])
string JoinStrings(const vector< string > &strings, const string &joint)
string Tail(const string &source, unsigned num_lines)
string StringifyTime(const time_t seconds, const bool utc)
string StringifyDouble(const double value)
std::string StringifyUint(const uint64_t value)
bool Debase64(const string &data, string *decoded)
string StringifyByteAsHex(const unsigned char value)
string StringifyBool(const bool value)
bool String2Uint64Parse(const std::string &value, uint64_t *result)
string Base64Url(const string &data)
std::string RfcTimestamp()
int64_t String2Int64(const string &value)
bool GetLineFile(FILE *f, std::string *line)
string ToUpper(const string &mixed_case)
vector< string > SplitString(const string &str, char delim)
bool HasSuffix(const std::string &str, const std::string &suffix, const bool ignore_case)
std::string WhitelistTimestamp(time_t when)
vector< string > SplitStringBounded(unsigned max_chunks, const string &str, char delim)
string StringifyInt(const int64_t value)
bool HasPrefix(const string &str, const string &prefix, const bool ignore_case)
const int const char * format
time_t IsoTimestamp2UtcTime(const std::string &iso8601)
bool GetLineFd(const int fd, std::string *line)
string Base64(const string &data)
uint64_t String2Uint64(const string &value)
bool operator()(const std::string::value_type a, const std::string::value_type b) const
bool ParseKeyvalPath(const string &filename, map< char, string > *content)
std::string TrimString(const std::string &path, const std::string &toTrim, const int trimMode)
static bool Debase64Block(const unsigned char input[4], unsigned char output[3])
string StringifyTimeval(const timeval value)
const int8_t db64_table[]
void ParseKeyvalMem(const unsigned char *buffer, const unsigned buffer_size, map< char, string > *content)
void String2Uint64Pair(const string &value, uint64_t *a, uint64_t *b)