25 constexpr
const char kCodes[] =
26 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
29 #define GET_LOW_BITS(in, n) ((in) & ((1 << (n)) - 1)) 31 #define GET_BITS(in, a, b) GET_LOW_BITS((in) >> (a), (b) - (a)) 33 #define CEIL_DIVIDE(a, b) ((((a)-1) / (b)) + 1) 35 int32_t DecodeChar(
char c) {
36 const char* it = strchr(kCodes, c);
42 JsError BadEncoding() {
44 "The string to be decoded is not correctly encoded.");
70 const size_t out_size =
CEIL_DIVIDE(input.size(), 3) * 4;
71 std::string result(out_size,
'\0');
72 for (
size_t i = 0; i < input.size(); i++) {
74 temp |= (input[i] << ((2 - (i % 3)) * 8));
77 result[out_i++] = kCodes[
GET_BITS(temp, 18, 24)];
78 result[out_i++] = kCodes[
GET_BITS(temp, 12, 18)];
79 result[out_i++] = kCodes[
GET_BITS(temp, 6, 12)];
80 result[out_i++] = kCodes[
GET_BITS(temp, 0, 6)];
85 if (input.size() % 3 == 1) {
86 result[out_i++] = kCodes[
GET_BITS(temp, 18, 24)];
87 result[out_i++] = kCodes[
GET_BITS(temp, 12, 18)];
88 result[out_i++] =
'=';
89 result[out_i++] =
'=';
90 }
else if (input.size() % 3 == 2) {
91 result[out_i++] = kCodes[
GET_BITS(temp, 18, 24)];
92 result[out_i++] = kCodes[
GET_BITS(temp, 12, 18)];
93 result[out_i++] = kCodes[
GET_BITS(temp, 6, 12)];
94 result[out_i++] =
'=';
97 DCHECK_EQ(out_size, out_i);
105 const size_t out_size_max =
CEIL_DIVIDE(input.size() * 3, 4);
106 std::string result(out_size_max,
'\0');
113 for (i = 0; i < input.size(); i++) {
114 if (input[i] ==
'=') {
116 for (
size_t j = i; j < input.size(); j++) {
118 return BadEncoding();
123 const int32_t decoded = DecodeChar(input[i]);
125 return BadEncoding();
127 temp |= (decoded << ((3 - (i % 4)) * 6));
130 result[out_i++] =
GET_BITS(temp, 16, 24);
131 result[out_i++] =
GET_BITS(temp, 8, 16);
132 result[out_i++] =
GET_BITS(temp, 0, 8);
139 return BadEncoding();
141 result[out_i++] =
GET_BITS(temp, 16, 24);
144 result[out_i++] =
GET_BITS(temp, 16, 24);
145 result[out_i++] =
GET_BITS(temp, 8, 16);
148 result.resize(out_i);
153 std::string ret =
Encode(input);
154 for (
char& c : ret) {
160 ret.erase(ret.find(
'='));
165 std::string converted_input = input;
166 for (
char& c : converted_input) {
173 return Decode(converted_input);
static std::string EncodeUrl(ByteString input)
static ExceptionOr< ByteString > DecodeUrl(const std::string &input)
#define GET_BITS(in, a, b)
static ExceptionOr< ByteString > Decode(const std::string &input)
void RegisterGlobalFunction(const std::string &name, Func &&callback)
#define CEIL_DIVIDE(a, b)
static JsError TypeError(const std::string &message)
static std::string Encode(ByteString input)