* * Base64ToByteStream * ------------------ * * Converts BASE64 encoded string to binary format. If input buffer is * not properly padded, buffer of negative length is returned * */
| 149 | * |
| 150 | */ |
| 151 | size_t Base64ToByteStream ( // Number of output bytes |
| 152 | std::string_view base64Str, // BASE64 encoded string |
| 153 | uint8_t * OutBuffer, // output buffer length |
| 154 | size_t len // length of output buffer |
| 155 | ) |
| 156 | { |
| 157 | unsigned char * pd; |
| 158 | unsigned char acc_1; |
| 159 | unsigned char acc_2; |
| 160 | size_t outCount; |
| 161 | |
| 162 | if (base64Str.empty () || base64Str[0] == P64) return 0; |
| 163 | auto d = std::div (base64Str.length (), 4); |
| 164 | if (!d.rem) |
| 165 | outCount = 3 * d.quot; |
| 166 | else |
| 167 | return 0; |
| 168 | |
| 169 | if (isFirstTime) iT64Build(); |
| 170 | |
| 171 | auto pos = base64Str.find_last_not_of (P64); |
| 172 | if (pos == base64Str.npos) return 0; |
| 173 | outCount -= (base64Str.length () - pos - 1); |
| 174 | if (outCount > len) return 0; |
| 175 | |
| 176 | auto ps = base64Str.begin (); |
| 177 | pd = OutBuffer; |
| 178 | auto endOfOutBuffer = OutBuffer + outCount; |
| 179 | for (int i = 0; i < d.quot; i++) |
| 180 | { |
| 181 | acc_1 = iT64[uint8_t(*ps++)]; |
| 182 | acc_2 = iT64[uint8_t(*ps++)]; |
| 183 | acc_1 <<= 2; |
| 184 | acc_1 |= acc_2 >> 4; |
| 185 | *pd++ = acc_1; |
| 186 | if (pd >= endOfOutBuffer) |
| 187 | break; |
| 188 | |
| 189 | acc_2 <<= 4; |
| 190 | acc_1 = iT64[uint8_t(*ps++)]; |
| 191 | acc_2 |= acc_1 >> 2; |
| 192 | *pd++ = acc_2; |
| 193 | if (pd >= endOfOutBuffer) |
| 194 | break; |
| 195 | |
| 196 | acc_2 = iT64[uint8_t(*ps++)]; |
| 197 | acc_2 |= acc_1 << 6; |
| 198 | *pd++ = acc_2; |
| 199 | } |
| 200 | |
| 201 | return outCount; |
| 202 | } |
| 203 | |
| 204 | std::string ToBase64Standard (std::string_view in) |
| 205 | { |