33 #include <google/protobuf/stubs/strutil.h>
43 #include <google/protobuf/stubs/logging.h>
44 #include <google/protobuf/stubs/stl_util.h>
57 #define snprintf _snprintf
73 return (
'0' <= c && c <=
'9') ||
74 (
'a' <=
c &&
c <=
'f') ||
75 (
'A' <= c && c <=
'F');
79 return c >= 0x20 &&
c <= 0x7E;
88 const char *str_start = s->c_str();
89 const char *
str = str_start;
90 for (
str = strpbrk(
str, remove);
92 str = strpbrk(
str + 1, remove)) {
93 (*s)[
str - str_start] = replacewith;
98 int str_length =
str->length();
106 if (
first == str_length) {
116 int last = str_length - 1;
120 if (last != (str_length - 1) && last >= 0) {
121 str->erase(last + 1, std::string::npos);
135 if (oldsub.empty()) {
140 std::string::size_type start_pos = 0;
141 std::string::size_type
pos;
143 pos = s.find(oldsub, start_pos);
144 if (
pos == std::string::npos) {
147 res->append(s, start_pos,
pos - start_pos);
149 start_pos =
pos + oldsub.size();
150 }
while (replace_all);
151 res->append(s, start_pos, s.length() - start_pos);
178 template <
typename ITR>
180 const char *delim, ITR &
result) {
182 if (delim[0] !=
'\0' && delim[1] ==
'\0') {
184 const char* p = full.
data();
185 const char*
end = p + full.
size();
190 const char*
start = p;
191 while (++p !=
end && *p != c);
198 std::string::size_type begin_index, end_index;
200 while (begin_index != std::string::npos) {
202 if (end_index == std::string::npos) {
213 std::vector<std::string> *
result) {
214 std::back_insert_iterator<std::vector<std::string> >
it(*
result);
229 template <
typename ITR>
232 int pieces, ITR &
result) {
233 std::string::size_type begin_index, end_index;
236 for (
int i = 0; (
i < pieces-1) || (pieces == 0);
i++) {
238 if (end_index == std::string::npos) {
244 begin_index = end_index + 1;
250 std::vector<std::string> *
result) {
251 std::back_insert_iterator<std::vector<std::string> >
it(*
result);
261 template <
class ITERATOR>
266 int delim_length = strlen(delim);
281 result->append(delim, delim_length);
287 void JoinStrings(
const std::vector<std::string> &components,
const char *delim,
304 #define IS_OCTAL_DIGIT(c) (((c) >= '0') && ((c) <= '7'))
308 #define LOG_STRING(LEVEL, VECTOR) GOOGLE_LOG_IF(LEVEL, false)
315 std::vector<std::string> *
errors) {
319 const char* p = source;
322 while ( p == d && *p !=
'\0' && *p !=
'\\' )
334 case 'a': *d++ =
'\a';
break;
335 case 'b': *d++ =
'\b';
break;
336 case 'f': *d++ =
'\f';
break;
337 case 'n': *d++ =
'\n';
break;
338 case 'r': *d++ =
'\r';
break;
339 case 't': *d++ =
'\t';
break;
340 case 'v': *d++ =
'\v';
break;
341 case '\\': *d++ =
'\\';
break;
342 case '?': *d++ =
'\?';
break;
343 case '\'': *d++ =
'\'';
break;
344 case '"': *d++ =
'\"';
break;
345 case '0':
case '1':
case '2':
case '3':
346 case '4':
case '5':
case '6':
case '7': {
349 ch =
ch * 8 + *++p -
'0';
351 ch =
ch * 8 + *++p -
'0';
355 case 'x':
case 'X': {
361 "\\x cannot be followed by non-hex digit: \\" << *p << p[1];
366 const char *hex_start = p;
372 <<
"\\" <<
std::string(hex_start, p + 1 - hex_start)
373 <<
" exceeds 8 bits";
377 #if 0 // TODO(kenton): Support \u and \U? Requires runetochar().
381 const char *hex_start = p;
382 for (
int i = 0;
i < 4; ++
i) {
387 <<
"\\u must be followed by 4 hex digits: \\"
398 const char *hex_start = p;
399 for (
int i = 0;
i < 8; ++
i) {
404 if (newrune > 0x10FFFF) {
408 <<
" exceeds Unicode limit (0x10FFFF)";
415 <<
"\\U must be followed by 8 hex digits: \\"
453 std::vector<std::string> *
errors) {
454 std::unique_ptr<char[]> unescaped(
new char[src.size() + 1]);
457 dest->assign(unescaped.get(),
len);
462 std::unique_ptr<char[]> unescaped(
new char[src.size() + 1]);
480 int dest_len,
bool use_hex,
bool utf8_safe) {
481 const char* src_end = src + src_len;
483 bool last_hex_escape =
false;
485 for (; src < src_end; src++) {
486 if (dest_len - used < 2)
489 bool is_hex_escape =
false;
491 case '\n':
dest[used++] =
'\\';
dest[used++] =
'n';
break;
492 case '\r':
dest[used++] =
'\\';
dest[used++] =
'r';
break;
493 case '\t':
dest[used++] =
'\\';
dest[used++] =
't';
break;
494 case '\"':
dest[used++] =
'\\';
dest[used++] =
'\"';
break;
495 case '\'':
dest[used++] =
'\\';
dest[used++] =
'\'';
break;
496 case '\\':
dest[used++] =
'\\';
dest[used++] =
'\\';
break;
501 if ((!utf8_safe ||
static_cast<uint8>(*src) < 0x80) &&
503 (last_hex_escape &&
isxdigit(*src)))) {
504 if (dest_len - used < 4)
506 sprintf(
dest + used, (use_hex ?
"\\x%02x" :
"\\%03o"),
507 static_cast<uint8>(*src));
508 is_hex_escape = use_hex;
511 dest[used++] = *src;
break;
514 last_hex_escape = is_hex_escape;
517 if (dest_len - used < 1)
529 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 4, 4, 2, 4, 4,
530 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
531 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1,
532 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
533 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
534 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1,
535 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
536 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4,
537 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
538 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
539 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
540 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
541 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
542 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
543 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
544 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
547 size_t escaped_len = 0;
549 unsigned char c =
static_cast<unsigned char>(src[
i]);
563 if (escaped_len == src.
size()) {
568 size_t cur_dest_len =
dest->size();
569 dest->resize(cur_dest_len + escaped_len);
570 char* append_ptr = &(*dest)[cur_dest_len];
573 unsigned char c =
static_cast<unsigned char>(src[
i]);
575 case '\n': *append_ptr++ =
'\\'; *append_ptr++ =
'n';
break;
576 case '\r': *append_ptr++ =
'\\'; *append_ptr++ =
'r';
break;
577 case '\t': *append_ptr++ =
'\\'; *append_ptr++ =
't';
break;
578 case '\"': *append_ptr++ =
'\\'; *append_ptr++ =
'\"';
break;
579 case '\'': *append_ptr++ =
'\\'; *append_ptr++ =
'\'';
break;
580 case '\\': *append_ptr++ =
'\\'; *append_ptr++ =
'\\';
break;
583 *append_ptr++ =
'\\';
584 *append_ptr++ =
'0' + c / 64;
585 *append_ptr++ =
'0' + (c % 64) / 8;
586 *append_ptr++ =
'0' + c % 8;
604 const int dest_length = src.size() * 4 + 1;
605 std::unique_ptr<char[]>
dest(
new char[dest_length]);
607 dest.get(), dest_length,
false,
true);
613 const int dest_length = src.size() * 4 + 1;
614 std::unique_ptr<char[]>
dest(
new char[dest_length]);
616 dest.get(), dest_length,
true,
false);
632 const int saved_errno = errno;
634 const long result = strtol(nptr, endptr,
base);
635 if (errno == ERANGE &&
result == LONG_MIN) {
637 }
else if (errno == ERANGE &&
result == LONG_MAX) {
652 const int saved_errno = errno;
654 const unsigned long result = strtoul(nptr, endptr,
base);
655 if (errno == ERANGE &&
result == ULONG_MAX) {
667 bool *negative_ptr ) {
683 *negative_ptr = (
start[0] ==
'-');
684 if (*negative_ptr ||
start[0] ==
'+') {
694 template <
typename IntType>
700 assert(vmax >=
base);
701 const IntType vmax_over_base = vmax /
base;
706 unsigned char c =
static_cast<unsigned char>(
start[0]);
708 if (digit >=
base || digit < 0) {
712 if (
value > vmax_over_base) {
717 if (
value > vmax - digit) {
727 template <
typename IntType>
733 assert(vmin <= 0 -
base);
734 IntType vmin_over_base = vmin /
base;
739 if (vmin %
base > 0) {
746 unsigned char c =
static_cast<unsigned char>(
start[0]);
748 if (digit >=
base || digit < 0) {
752 if (
value < vmin_over_base) {
757 if (
value < vmin + digit) {
767 template <
typename IntType>
781 template <
typename IntType>
887 GOOGLE_CHECK(i >= 0) <<
"FastHexToBuffer() wants non-negative integers, not " <<
i;
889 static const char *hexdigits =
"0123456789abcdef";
893 *p-- = hexdigits[
i & 15];
900 static const char *hexdigits =
"0123456789abcdef";
902 for (
int i = num_byte - 1;
i >= 0;
i--) {
941 {
'0',
'0'}, {
'0',
'1'}, {
'0',
'2'}, {
'0',
'3'}, {
'0',
'4'},
942 {
'0',
'5'}, {
'0',
'6'}, {
'0',
'7'}, {
'0',
'8'}, {
'0',
'9'},
943 {
'1',
'0'}, {
'1',
'1'}, {
'1',
'2'}, {
'1',
'3'}, {
'1',
'4'},
944 {
'1',
'5'}, {
'1',
'6'}, {
'1',
'7'}, {
'1',
'8'}, {
'1',
'9'},
945 {
'2',
'0'}, {
'2',
'1'}, {
'2',
'2'}, {
'2',
'3'}, {
'2',
'4'},
946 {
'2',
'5'}, {
'2',
'6'}, {
'2',
'7'}, {
'2',
'8'}, {
'2',
'9'},
947 {
'3',
'0'}, {
'3',
'1'}, {
'3',
'2'}, {
'3',
'3'}, {
'3',
'4'},
948 {
'3',
'5'}, {
'3',
'6'}, {
'3',
'7'}, {
'3',
'8'}, {
'3',
'9'},
949 {
'4',
'0'}, {
'4',
'1'}, {
'4',
'2'}, {
'4',
'3'}, {
'4',
'4'},
950 {
'4',
'5'}, {
'4',
'6'}, {
'4',
'7'}, {
'4',
'8'}, {
'4',
'9'},
951 {
'5',
'0'}, {
'5',
'1'}, {
'5',
'2'}, {
'5',
'3'}, {
'5',
'4'},
952 {
'5',
'5'}, {
'5',
'6'}, {
'5',
'7'}, {
'5',
'8'}, {
'5',
'9'},
953 {
'6',
'0'}, {
'6',
'1'}, {
'6',
'2'}, {
'6',
'3'}, {
'6',
'4'},
954 {
'6',
'5'}, {
'6',
'6'}, {
'6',
'7'}, {
'6',
'8'}, {
'6',
'9'},
955 {
'7',
'0'}, {
'7',
'1'}, {
'7',
'2'}, {
'7',
'3'}, {
'7',
'4'},
956 {
'7',
'5'}, {
'7',
'6'}, {
'7',
'7'}, {
'7',
'8'}, {
'7',
'9'},
957 {
'8',
'0'}, {
'8',
'1'}, {
'8',
'2'}, {
'8',
'3'}, {
'8',
'4'},
958 {
'8',
'5'}, {
'8',
'6'}, {
'8',
'7'}, {
'8',
'8'}, {
'8',
'9'},
959 {
'9',
'0'}, {
'9',
'1'}, {
'9',
'2'}, {
'9',
'3'}, {
'9',
'4'},
960 {
'9',
'5'}, {
'9',
'6'}, {
'9',
'7'}, {
'9',
'8'}, {
'9',
'9'}
965 const char *ASCII_digits =
nullptr;
972 if (u >= 1000000000) {
973 digits =
u / 100000000;
975 buffer[0] = ASCII_digits[0];
976 buffer[1] = ASCII_digits[1];
979 u -= digits * 100000000;
981 digits =
u / 1000000;
983 buffer[0] = ASCII_digits[0];
984 buffer[1] = ASCII_digits[1];
987 u -= digits * 1000000;
991 buffer[0] = ASCII_digits[0];
992 buffer[1] = ASCII_digits[1];
999 buffer[0] = ASCII_digits[0];
1000 buffer[1] = ASCII_digits[1];
1007 buffer[0] = ASCII_digits[0];
1008 buffer[1] = ASCII_digits[1];
1017 if (u >= 10)
goto lt100;
1018 *
buffer++ =
'0' + digits;
1022 if (u >= 1000)
goto lt10_000;
1024 *
buffer++ =
'0' + digits;
1028 if (u >= 100000)
goto lt1_000_000;
1030 *
buffer++ =
'0' + digits;
1033 if (u < 100000000) {
1034 if (u >= 10000000)
goto lt100_000_000;
1035 digits =
u / 1000000;
1036 *
buffer++ =
'0' + digits;
1037 goto sublt1_000_000;
1040 digits =
u / 100000000;
1041 *
buffer++ =
'0' + digits;
1042 goto sublt100_000_000;
1058 const char *ASCII_digits =
nullptr;
1063 uint64 top_11_digits = u64 / 1000000000;
1065 u = u64 - (top_11_digits * 1000000000);
1067 digits =
u / 10000000;
1070 buffer[0] = ASCII_digits[0];
1071 buffer[1] = ASCII_digits[1];
1073 u -= digits * 10000000;
1074 digits =
u / 100000;
1076 buffer[0] = ASCII_digits[0];
1077 buffer[1] = ASCII_digits[1];
1079 u -= digits * 100000;
1082 buffer[0] = ASCII_digits[0];
1083 buffer[1] = ASCII_digits[1];
1088 buffer[0] = ASCII_digits[0];
1089 buffer[1] = ASCII_digits[1];
1093 *
buffer++ =
'0' + digits;
1118 return (
sizeof(i) == 4) ?
1132 return (
sizeof(i) == 4) ?
1146 return (
sizeof(i) == 4) ?
1210 return (
'0' <= c && c <=
'9') ||
1211 c ==
'e' || c ==
'E' ||
1212 c ==
'+' || c ==
'-';
1218 if (strchr(
buffer,
'.') !=
nullptr)
return;
1247 static_assert(DBL_DIG < 20,
"DBL_DIG_is_too_big");
1249 if (
value == std::numeric_limits<double>::infinity()) {
1252 }
else if (
value == -std::numeric_limits<double>::infinity()) {
1260 int snprintf_result =
1274 if (parsed_value !=
value) {
1287 const unsigned char *us1 =
reinterpret_cast<const unsigned char *
>(s1);
1288 const unsigned char *us2 =
reinterpret_cast<const unsigned char *
>(s2);
1290 for (
size_t i = 0;
i <
len;
i++) {
1292 static_cast<int>(
static_cast<unsigned char>(
ascii_tolower(us1[
i]))) -
1293 static_cast<int>(
static_cast<unsigned char>(
ascii_tolower(us2[
i])));
1299 inline bool CaseEqual(StringPiece s1, StringPiece s2) {
1300 if (s1.size() != s2.size())
return false;
1301 return memcasecmp(s1.data(), s2.data(), s1.size()) == 0;
1324 #if defined(_WIN32) || defined (__hpux) // has no strtof()
1329 return *
str != 0 && *endptr == 0 && errno == 0;
1335 if (endptr !=
str) {
1341 return *
str !=
'\0' && *endptr ==
'\0';
1365 static_assert(FLT_DIG < 10,
"FLT_DIG_is_too_big");
1367 if (
value == std::numeric_limits<double>::infinity()) {
1370 }
else if (
value == -std::numeric_limits<double>::infinity()) {
1378 int snprintf_result =
1409 static const char hexdigits[] =
"0123456789abcdef";
1414 }
while (mask != 0);
1440 if (x1.
size() > 0) {
1444 if (x2.
size() > 0) {
1453 if (x1.
size() > 0) {
1457 if (x2.
size() > 0) {
1461 if (x3.
size() > 0) {
1465 if (x4.
size() > 0) {
1474 result.resize(
a.size() +
b.size());
1483 result.resize(
a.size() +
b.size() + c.size());
1492 const AlphaNum &d) {
1494 result.resize(
a.size() +
b.size() +
c.size() +
d.size());
1502 const AlphaNum &d,
const AlphaNum &e) {
1504 result.resize(
a.size() +
b.size() +
c.size() +
d.size() +
e.size());
1513 const AlphaNum &d,
const AlphaNum &e,
const AlphaNum &f) {
1515 result.resize(
a.size() +
b.size() +
c.size() +
d.size() +
e.size() +
1525 const AlphaNum &d,
const AlphaNum &e,
const AlphaNum &f,
1526 const AlphaNum &g) {
1528 result.resize(
a.size() +
b.size() +
c.size() +
d.size() +
e.size() +
1529 f.size() +
g.size());
1539 const AlphaNum &d,
const AlphaNum &e,
const AlphaNum &f,
1540 const AlphaNum &g,
const AlphaNum &h) {
1542 result.resize(
a.size() +
b.size() +
c.size() +
d.size() +
e.size() +
1543 f.size() +
g.size() +
h.size());
1552 const AlphaNum &d,
const AlphaNum &e,
const AlphaNum &f,
1553 const AlphaNum &g,
const AlphaNum &h,
const AlphaNum &i) {
1555 result.resize(
a.size() +
b.size() +
c.size() +
d.size() +
e.size() +
1556 f.size() +
g.size() +
h.size() +
i.size());
1569 #define GOOGLE_DCHECK_NO_OVERLAP(dest, src) \
1570 GOOGLE_DCHECK_GT(uintptr_t((src).data() - (dest).data()), \
1571 uintptr_t((dest).size()))
1575 result->append(
a.data(),
a.size());
1617 if (s->empty() || substring.empty())
1620 int num_replacements = 0;
1623 s->find(substring.data(),
pos, substring.length());
1624 match_pos != std::string::npos;
pos = match_pos + substring.length(),
1625 match_pos = s->find(substring.data(),
pos,
1626 substring.length())) {
1631 tmp.append(replacement.begin(), replacement.end());
1635 if (num_replacements > 0) {
1639 return num_replacements;
1658 int len = (input_len / 3) * 4;
1660 if (input_len % 3 == 0) {
1665 }
else if (input_len % 3 == 1) {
1685 assert(
len >= input_len);
1719 char *
dest,
int szdest,
1720 const signed char* unbase64) {
1721 static const char kPad64Equals =
'=';
1722 static const char kPad64Dot =
'.';
1727 unsigned int ch = 0;
1728 unsigned int temp = 0;
1733 const unsigned char *src =
reinterpret_cast<const unsigned char*
>(src_param);
1741 #define GET_INPUT(label, remain) \
1745 decode = unbase64[ch]; \
1747 if (ascii_isspace(ch) && szsrc >= remain) \
1749 state = 4 - remain; \
1765 while (szsrc >= 4) {
1774 if (!src[0] || !src[1] || !src[2] ||
1775 (
temp = ((
unsigned(unbase64[src[0]]) << 18) |
1776 (
unsigned(unbase64[src[1]]) << 12) |
1777 (
unsigned(unbase64[src[2]]) << 6) |
1778 (
unsigned(unbase64[src[3]])))) & 0x80000000) {
1806 if (destidx+3 > szdest)
return -1;
1815 while (szsrc >= 4) {
1816 if (!src[0] || !src[1] || !src[2] ||
1817 (
temp = ((
unsigned(unbase64[src[0]]) << 18) |
1818 (
unsigned(unbase64[src[1]]) << 12) |
1819 (
unsigned(unbase64[src[2]]) << 6) |
1820 (
unsigned(unbase64[src[3]])))) & 0x80000000) {
1843 if (
ch == kPad64Equals ||
ch == kPad64Dot) {
1861 }
else if (
ch ==
'\0') {
1863 }
else if (
ch == kPad64Equals ||
ch == kPad64Dot) {
1881 if (destidx+3 > szdest)
return -1;
1896 int expected_equals = 0;
1909 if (destidx+1 > szdest)
return -1;
1914 expected_equals = 2;
1920 if (destidx+2 > szdest)
return -1;
1927 expected_equals = 1;
1941 while (szsrc > 0 && *src) {
1942 if (*src == kPad64Equals || *src == kPad64Dot)
1950 return (equals == 0 || equals == expected_equals) ? destidx : -1;
1984 -1, -1, -1, -1, -1, -1, -1, -1,
1985 -1, -1, -1, -1, -1, -1, -1, -1,
1986 -1, -1, -1, -1, -1, -1, -1, -1,
1987 -1, -1, -1, -1, -1, -1, -1, -1,
1988 -1, -1, -1, -1, -1, -1, -1, -1,
1989 -1, -1, -1, 62, -1, -1, -1, 63,
1990 52, 53, 54, 55, 56, 57, 58, 59,
1991 60, 61, -1, -1, -1, -1, -1, -1,
1992 -1, 0, 1, 2, 3, 4, 5, 6,
1993 7, 8, 9, 10, 11, 12, 13, 14,
1994 15, 16, 17, 18, 19, 20, 21, 22,
1995 23, 24, 25, -1, -1, -1, -1, -1,
1996 -1, 26, 27, 28, 29, 30, 31, 32,
1997 33, 34, 35, 36, 37, 38, 39, 40,
1998 41, 42, 43, 44, 45, 46, 47, 48,
1999 49, 50, 51, -1, -1, -1, -1, -1,
2000 -1, -1, -1, -1, -1, -1, -1, -1,
2001 -1, -1, -1, -1, -1, -1, -1, -1,
2002 -1, -1, -1, -1, -1, -1, -1, -1,
2003 -1, -1, -1, -1, -1, -1, -1, -1,
2004 -1, -1, -1, -1, -1, -1, -1, -1,
2005 -1, -1, -1, -1, -1, -1, -1, -1,
2006 -1, -1, -1, -1, -1, -1, -1, -1,
2007 -1, -1, -1, -1, -1, -1, -1, -1,
2008 -1, -1, -1, -1, -1, -1, -1, -1,
2009 -1, -1, -1, -1, -1, -1, -1, -1,
2010 -1, -1, -1, -1, -1, -1, -1, -1,
2011 -1, -1, -1, -1, -1, -1, -1, -1,
2012 -1, -1, -1, -1, -1, -1, -1, -1,
2013 -1, -1, -1, -1, -1, -1, -1, -1,
2014 -1, -1, -1, -1, -1, -1, -1, -1,
2015 -1, -1, -1, -1, -1, -1, -1, -1
2018 -1, -1, -1, -1, -1, -1, -1, -1,
2019 -1, -1, -1, -1, -1, -1, -1, -1,
2020 -1, -1, -1, -1, -1, -1, -1, -1,
2021 -1, -1, -1, -1, -1, -1, -1, -1,
2022 -1, -1, -1, -1, -1, -1, -1, -1,
2023 -1, -1, -1, -1, -1, 62, -1, -1,
2024 52, 53, 54, 55, 56, 57, 58, 59,
2025 60, 61, -1, -1, -1, -1, -1, -1,
2026 -1, 0, 1, 2, 3, 4, 5, 6,
2027 7, 8, 9, 10, 11, 12, 13, 14,
2028 15, 16, 17, 18, 19, 20, 21, 22,
2029 23, 24, 25, -1, -1, -1, -1, 63,
2030 -1, 26, 27, 28, 29, 30, 31, 32,
2031 33, 34, 35, 36, 37, 38, 39, 40,
2032 41, 42, 43, 44, 45, 46, 47, 48,
2033 49, 50, 51, -1, -1, -1, -1, -1,
2034 -1, -1, -1, -1, -1, -1, -1, -1,
2035 -1, -1, -1, -1, -1, -1, -1, -1,
2036 -1, -1, -1, -1, -1, -1, -1, -1,
2037 -1, -1, -1, -1, -1, -1, -1, -1,
2038 -1, -1, -1, -1, -1, -1, -1, -1,
2039 -1, -1, -1, -1, -1, -1, -1, -1,
2040 -1, -1, -1, -1, -1, -1, -1, -1,
2041 -1, -1, -1, -1, -1, -1, -1, -1,
2042 -1, -1, -1, -1, -1, -1, -1, -1,
2043 -1, -1, -1, -1, -1, -1, -1, -1,
2044 -1, -1, -1, -1, -1, -1, -1, -1,
2045 -1, -1, -1, -1, -1, -1, -1, -1,
2046 -1, -1, -1, -1, -1, -1, -1, -1,
2047 -1, -1, -1, -1, -1, -1, -1, -1,
2048 -1, -1, -1, -1, -1, -1, -1, -1,
2049 -1, -1, -1, -1, -1, -1, -1, -1
2057 const signed char *unbase64) {
2061 const int dest_len = 3 * (slen / 4) + (slen % 4);
2063 dest->resize(dest_len);
2068 dest_len, unbase64);
2090 char *
dest,
int szdest,
const char *base64,
2092 static const char kPad64 =
'=';
2094 if (szsrc <= 0)
return 0;
2096 if (szsrc * 4 > szdest * 3)
return 0;
2098 char *cur_dest =
dest;
2099 const unsigned char *cur_src = src;
2101 char *limit_dest =
dest + szdest;
2102 const unsigned char *limit_src = src + szsrc;
2106 while (cur_src < limit_src - 3) {
2109 cur_dest[0] = base64[
in >> 18];
2111 cur_dest[1] = base64[
in >> 12];
2113 cur_dest[2] = base64[
in >> 6];
2115 cur_dest[3] = base64[
in];
2121 szdest = limit_dest - cur_dest;
2122 szsrc = limit_src - cur_src;
2132 if ((szdest -= 2) < 0)
return 0;
2134 cur_dest[0] = base64[
in >> 2];
2136 cur_dest[1] = base64[
in << 4];
2139 if ((szdest -= 2) < 0)
return 0;
2140 cur_dest[0] = kPad64;
2141 cur_dest[1] = kPad64;
2149 if ((szdest -= 3) < 0)
return 0;
2151 cur_dest[0] = base64[
in >> 10];
2153 cur_dest[1] = base64[
in >> 4];
2155 cur_dest[2] = base64[
in << 2];
2158 if ((szdest -= 1) < 0)
return 0;
2159 cur_dest[0] = kPad64;
2168 if ((szdest -= 4) < 0)
return 0;
2170 cur_dest[0] = base64[
in >> 18];
2172 cur_dest[1] = base64[
in >> 12];
2174 cur_dest[2] = base64[
in >> 6];
2176 cur_dest[3] = base64[
in];
2186 return (cur_dest -
dest);
2190 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
2193 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
2195 int Base64Escape(
const unsigned char *src,
int szsrc,
char *
dest,
int szdest) {
2199 int szdest,
bool do_padding) {
2207 const int calc_escaped_size =
2209 dest->resize(calc_escaped_size);
2216 dest->erase(escaped_len);
2249 if (code_point <= 0x7f) {
2252 }
else if (code_point <= 0x07ff) {
2254 ((code_point & 0x07c0) << 2) |
2255 (code_point & 0x003f);
2257 }
else if (code_point <= 0xffff) {
2259 ((code_point & 0xf000) << 4) |
2260 ((code_point & 0x0fc0) << 2) |
2261 (code_point & 0x003f);
2267 ((code_point & 0x1c0000) << 6) |
2268 ((code_point & 0x03f000) << 4) |
2269 ((code_point & 0x000fc0) << 2) |
2270 (code_point & 0x003f);
2280 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2281 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2282 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2283 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2284 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2285 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2287 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2288 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2289 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2,
2290 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2291 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
2292 3, 3, 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
2336 bool auto_end_last_line) {
2348 ptrdiff_t output_pos = 0;
2349 bool r_seen =
false;
2350 ptrdiff_t
len =
str->size();
2352 char *p = &(*str)[0];
2354 for (ptrdiff_t input_pos = 0; input_pos <
len;) {
2355 if (!r_seen && input_pos + 8 <
len) {
2366 #define has_less(x, n) (((x) - ~0ULL / 255 * (n)) & ~(x) & ~0ULL / 255 * 128)
2370 if (output_pos != input_pos) {
2380 if (r_seen) p[output_pos++] =
'\n';
2382 }
else if (
in ==
'\n') {
2383 if (input_pos != output_pos)
2384 p[output_pos++] =
'\n';
2389 if (r_seen) p[output_pos++] =
'\n';
2391 if (input_pos != output_pos)
2392 p[output_pos++] =
in;
2399 (auto_end_last_line && output_pos > 0 && p[output_pos - 1] !=
'\n')) {
2400 str->resize(output_pos + 1);
2401 str->operator[](output_pos) =
'\n';
2402 }
else if (output_pos <
len) {
2403 str->resize(output_pos);
2436 result.append(radix_pos + 1);
2450 double result = strtod(
str, &temp_endptr);
2451 if (endptr != NULL) *endptr = temp_endptr;
2452 if (*temp_endptr !=
'.')
return result;
2458 const char *localized_cstr = localized.c_str();
2459 char *localized_endptr;
2460 result = strtod(localized_cstr, &localized_endptr);
2461 if ((localized_endptr - localized_cstr) > (temp_endptr -
str)) {
2464 if (endptr != NULL) {
2466 int size_diff = localized.size() - strlen(
str);
2468 *endptr =
const_cast<char *
>(
2469 str + (localized_endptr - localized_cstr - size_diff));