103 size_t& input_consumed,
111 static const byte BASE64_TO_BIN[256] = {
112 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80,
113 0x80, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
114 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
115 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
116 0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xFF, 0xFF, 0x3F, 0x34, 0x35,
117 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0xFF, 0xFF,
118 0xFF, 0x81, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04,
119 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
120 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
121 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1A, 0x1B, 0x1C,
122 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26,
123 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
124 0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
125 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
126 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
127 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
128 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
129 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
130 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
131 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
132 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
133 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
134 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
135 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
136 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
137 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
139 byte* out_ptr = output;
141 size_t decode_buf_pos = 0;
142 size_t final_truncate = 0;
146 for(
size_t i = 0; i != input_length; ++i)
148 const byte bin = BASE64_TO_BIN[
static_cast<byte>(input[i])];
152 decode_buf[decode_buf_pos] = bin;
155 else if(!(bin == 0x81 || (bin == 0x80 && ignore_ws)))
157 std::string bad_char(1, input[i]);
160 else if(bad_char ==
"\n")
162 else if(bad_char ==
"\r")
165 throw std::invalid_argument(
166 std::string(
"base64_decode: invalid base64 character '") +
173 if(final_inputs && (i == input_length - 1))
177 for(
size_t i = decode_buf_pos; i != 4; ++i)
179 final_truncate = (4 - decode_buf_pos);
184 if(decode_buf_pos == 4)
186 out_ptr[0] = (decode_buf[0] << 2) | (decode_buf[1] >> 4);
187 out_ptr[1] = (decode_buf[1] << 4) | (decode_buf[2] >> 2);
188 out_ptr[2] = (decode_buf[2] << 6) | decode_buf[3];
192 input_consumed = i+1;
196 while(input_consumed < input_length &&
197 BASE64_TO_BIN[
static_cast<byte>(input[input_consumed])] == 0x80)
202 size_t written = (out_ptr - output) - final_truncate;