7 #ifndef __STDC_FORMAT_MACROS
9 #define __STDC_FORMAT_MACROS
13 #include "cvmfs_config.h"
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 const char *months[] = {
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
129 "Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec"};
130 const char *day_of_week[] = {
"Sun",
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat"};
133 time_t now = time(NULL);
134 gmtime_r(&now, ×tamp);
137 snprintf(buffer,
sizeof(buffer),
"%s, %02d %s %d %02d:%02d:%02d %s",
138 day_of_week[timestamp.tm_wday], timestamp.tm_mday,
139 months[timestamp.tm_mon], timestamp.tm_year + 1900,
140 timestamp.tm_hour, timestamp.tm_min, timestamp.tm_sec,
142 return string(buffer);
151 time_t now = time(NULL);
152 gmtime_r(&now, ×tamp);
155 snprintf(buffer,
sizeof(buffer),
"%04d%02d%02dT%02d%02d%02dZ",
156 timestamp.tm_year + 1900,
157 timestamp.tm_mon + 1,
162 return string(buffer);
171 gmtime_r(&when, ×tamp);
174 snprintf(buffer,
sizeof(buffer),
"%04d%02d%02d%02d%02d%02d",
175 timestamp.tm_year + 1900,
176 timestamp.tm_mon + 1,
181 return string(buffer);
187 int64_t msec = value.tv_sec * 1000;
188 msec += value.tv_usec / 1000;
189 snprintf(buffer,
sizeof(buffer),
"%" PRId64
".%03d", msec,
190 static_cast<int>(value.tv_usec % 1000));
191 return string(buffer);
200 unsigned length = iso8601.length();
202 if (length != 20)
return utc_time;
203 if ((iso8601[4] !=
'-') || (iso8601[7] !=
'-') || (iso8601[10] !=
'T') ||
204 (iso8601[13] !=
':') || (iso8601[16] !=
':') || (iso8601[19] !=
'Z')) {
209 memset(&tm_wl, 0,
sizeof(
struct tm));
210 tm_wl.tm_year =
static_cast<int>(
String2Int64(iso8601.substr(0, 4))) - 1900;
211 tm_wl.tm_mon =
static_cast<int>(
String2Int64(iso8601.substr(5, 2))) - 1;
212 tm_wl.tm_mday =
static_cast<int>(
String2Int64(iso8601.substr(8, 2)));
213 tm_wl.tm_hour =
static_cast<int>(
String2Int64(iso8601.substr(11, 2)));
214 tm_wl.tm_min =
static_cast<int>(
String2Int64(iso8601.substr(14, 2)));
215 tm_wl.tm_sec =
static_cast<int>(
String2Int64(iso8601.substr(17, 2)));
216 utc_time = timegm(&tm_wl);
217 if (utc_time < 0)
return 0;
224 sscanf(value.c_str(),
"%" PRId64, &result);
230 sscanf(value.c_str(),
"%" PRIu64, &result);
246 long long myval = strtoll(value.c_str(), &endptr, 10);
247 if ((value.size() == 0) || (endptr != (value.c_str() + value.size())) ||
262 sscanf(value.c_str(),
"%" PRIu64
" %" PRIu64, a, b);
266 const bool ignore_case) {
267 if (prefix.length() > str.length())
return false;
269 for (
unsigned i = 0, l = prefix.length(); i < l; ++i) {
271 if (toupper(str[i]) != toupper(prefix[i]))
return false;
273 if (str[i] != prefix[i])
return false;
279 bool HasSuffix(
const std::string &str,
const std::string &suffix,
280 const bool ignore_case) {
281 if (suffix.size() > str.size())
return false;
282 const IgnoreCaseComperator icmp;
284 ? std::equal(suffix.rbegin(), suffix.rend(), str.rbegin(), icmp)
285 : std::equal(suffix.rbegin(), suffix.rend(), str.rbegin());
289 const unsigned max_chunks) {
290 vector<string> result;
293 if (1 == max_chunks) {
294 result.push_back(str);
299 const unsigned size = str.size();
303 for (i = 0; i <
size; ++i) {
304 if (str[i] == delim) {
305 result.push_back(str.substr(marker, i - marker));
309 if (++chunks == max_chunks)
break;
314 result.push_back(str.substr(marker));
318 string JoinStrings(
const vector<string> &strings,
const string &joint) {
320 const unsigned size = strings.size();
324 for (
unsigned i = 1; i <
size; ++i) result += joint + strings[i];
331 map<char, string> *content) {
334 while (pos < buffer_size) {
335 if (static_cast<char>(buffer[pos]) ==
'\n') {
336 if (line ==
"--")
return;
339 const string tail = (line.length() == 1) ?
"" : line.substr(1);
341 if (line[0] !=
'Z') {
342 (*content)[line[0]] = tail;
344 if (content->find(line[0]) == content->end()) {
345 (*content)[line[0]] = tail;
347 (*content)[line[0]] = (*content)[line[0]] +
"|" + tail;
353 line +=
static_cast<char>(buffer[pos]);
360 int fd = open(filename.c_str(), O_RDONLY);
361 if (fd < 0)
return false;
363 unsigned char buffer[4096];
364 ssize_t num_bytes = read(fd, buffer,
sizeof(buffer));
367 if ((num_bytes <= 0) || (
unsigned(num_bytes) >=
sizeof(buffer)))
return false;
375 while ((pos < text_size) && (text[pos] !=
'\n')) pos++;
376 return string(text, pos);
384 if (ferror(f) && (errno == EINTR)) {
387 }
else if (retval == EOF) {
390 char c =
static_cast<char>(retval);
391 if (c ==
'\n')
break;
394 return (retval != EOF) || !line->empty();
402 retval = read(fd, &c, 1);
406 if ((retval == -1) && (errno == EINTR)) {
412 if (c ==
'\n')
break;
415 return (retval == 1) || !line->empty();
421 string Trim(
const string &raw,
bool trim_newline) {
422 if (raw.empty())
return "";
424 unsigned start_pos = 0;
425 for (; (start_pos < raw.length()) &&
426 (raw[start_pos] ==
' ' || raw[start_pos] ==
'\t' ||
427 (trim_newline && (raw[start_pos] ==
'\n' || raw[start_pos] ==
'\r')));
431 unsigned end_pos = raw.length() - 1;
433 (end_pos >= start_pos) &&
434 (raw[end_pos] ==
' ' || raw[end_pos] ==
'\t' ||
435 (trim_newline && (raw[end_pos] ==
'\n' || raw[end_pos] ==
'\r')));
440 return raw.substr(start_pos, end_pos - start_pos + 1);
444 const std::string& path,
445 const std::string& toTrim,
448 std::string trimmed = path;
449 if (trimmed != toTrim) {
452 (trimmed.size() > toTrim.size()))
454 trimmed = trimmed.substr(toTrim.size());
458 (trimmed.size() > toTrim.size()))
460 trimmed = trimmed.substr(0, trimmed.size() - toTrim.size());
470 string result(mixed_case);
471 for (
unsigned i = 0, l = result.length(); i < l; ++i) {
472 result[i] =
static_cast<char>(toupper(result[i]));
477 string ReplaceAll(
const string &haystack,
const string &needle,
478 const string &replace_by) {
479 string result(haystack);
481 const unsigned needle_size = needle.size();
482 if (needle ==
"")
return result;
484 while ((pos = result.find(needle, pos)) != string::npos)
485 result.replace(pos, needle_size, replace_by);
489 static inline void Base64Block(
const unsigned char input[3],
const char *table,
491 output[0] = table[(input[0] & 0xFD) >> 2];
492 output[1] = table[((input[0] & 0x03) << 4) | ((input[1] & 0xF0) >> 4)];
493 output[2] = table[((input[1] & 0x0F) << 2) | ((input[2] & 0xD0) >> 6)];
494 output[3] = table[input[2] & 0x3F];
499 result.reserve((data.length() + 3) * 4 / 3);
501 const unsigned char *data_ptr =
502 reinterpret_cast<const unsigned char *
>(data.data());
503 const unsigned length = data.length();
504 while (pos + 2 < length) {
505 char encoded_block[4];
507 result.append(encoded_block, 4);
510 if (length % 3 != 0) {
511 unsigned char input[3];
512 input[0] = data_ptr[pos];
513 input[1] = ((length % 3) == 2) ? data_ptr[pos + 1] : 0;
515 char encoded_block[4];
517 result.append(encoded_block, 2);
518 result.push_back(((length % 3) == 2) ? encoded_block[2] :
'=');
519 result.push_back(
'=');
529 string base64 =
Base64(data);
530 for (
unsigned i = 0, l = base64.length(); i < l; ++i) {
531 if (base64[i] ==
'+') {
533 }
else if (base64[i] ==
'/') {
540 static bool Debase64Block(
const unsigned char input[4],
unsigned char output[3])
543 for (
int i = 0; i < 4; ++i) {
545 if (dec[i] < 0)
return false;
548 output[0] = (dec[0] << 2) | (dec[1] >> 4);
549 output[1] = ((dec[1] & 0x0F) << 4) | (dec[2] >> 2);
550 output[2] = ((dec[2] & 0x03) << 6) | dec[3];
557 bool Debase64(
const string &data,
string *decoded) {
559 decoded->reserve((data.length() + 4) * 3 / 4);
561 const unsigned char *data_ptr =
562 reinterpret_cast<const unsigned char *
>(data.data());
563 const unsigned length = data.length();
564 if (length == 0)
return true;
565 if ((length % 4) != 0)
return false;
567 while (pos < length) {
568 unsigned char decoded_block[3];
570 if (!retval)
return false;
571 decoded->append(reinterpret_cast<char *>(decoded_block), 3);
575 for (
int i = 0; i < 2; ++i) {
577 if (data[pos] ==
'=') decoded->erase(decoded->length() - 1);
585 string Tail(
const string &source,
unsigned num_lines) {
586 if (source.empty() || (num_lines == 0))
return "";
588 int l =
static_cast<int>(source.length());
590 for (; i >= 0; --i) {
591 char c = source.data()[i];
593 if (num_lines == 0) {
594 return source.substr(i + 1);
610 char date_and_time[100];
611 time_t t = time(NULL);
612 gmtime_r(&t, &time_ptr);
614 if (!strftime(date_and_time, 100, format.c_str(), &time_ptr)) {
617 std::string timestamp(date_and_time);
621 #ifdef CVMFS_NAMESPACE_GUARD
string GetLineMem(const char *text, const int text_size)
std::string GetGMTimestamp(const std::string &format)
vector< string > SplitString(const string &str, const char delim, const unsigned max_chunks)
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)
bool HasSuffix(const std::string &str, const std::string &suffix, const bool ignore_case)
std::string WhitelistTimestamp(time_t when)
string StringifyInt(const int64_t value)
bool HasPrefix(const string &str, const string &prefix, const bool ignore_case)
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)