| 120 | } |
| 121 | |
| 122 | size_t Decode(const char *in, size_t inLength, uint8_t *&out) { |
| 123 | if (in == nullptr) { |
| 124 | out = nullptr; |
| 125 | return 0; |
| 126 | } |
| 127 | |
| 128 | if (inLength % 4 != 0) { |
| 129 | throw DeadlyImportError("Invalid base64 encoded data: \"", std::string(in, std::min(size_t(32), inLength)), |
| 130 | "\", length:", inLength); |
| 131 | } |
| 132 | |
| 133 | if (inLength < 4) { |
| 134 | out = nullptr; |
| 135 | return 0; |
| 136 | } |
| 137 | |
| 138 | int nEquals = int(in[inLength - 1] == '=') + |
| 139 | int(in[inLength - 2] == '='); |
| 140 | |
| 141 | size_t outLength = (inLength * 3) / 4 - nEquals; |
| 142 | out = new uint8_t[outLength]; |
| 143 | memset(out, 0, outLength); |
| 144 | |
| 145 | size_t i, j = 0; |
| 146 | |
| 147 | for (i = 0; i + 4 < inLength; i += 4) { |
| 148 | uint8_t b0 = DecodeChar(in[i]); |
| 149 | uint8_t b1 = DecodeChar(in[i + 1]); |
| 150 | uint8_t b2 = DecodeChar(in[i + 2]); |
| 151 | uint8_t b3 = DecodeChar(in[i + 3]); |
| 152 | |
| 153 | out[j++] = (uint8_t)((b0 << 2) | (b1 >> 4)); |
| 154 | out[j++] = (uint8_t)((b1 << 4) | (b2 >> 2)); |
| 155 | out[j++] = (uint8_t)((b2 << 6) | b3); |
| 156 | } |
| 157 | |
| 158 | { |
| 159 | uint8_t b0 = DecodeChar(in[i]); |
| 160 | uint8_t b1 = DecodeChar(in[i + 1]); |
| 161 | uint8_t b2 = DecodeChar(in[i + 2]); |
| 162 | uint8_t b3 = DecodeChar(in[i + 3]); |
| 163 | |
| 164 | out[j++] = (uint8_t)((b0 << 2) | (b1 >> 4)); |
| 165 | if (b2 < 64) out[j++] = (uint8_t)((b1 << 4) | (b2 >> 2)); |
| 166 | if (b3 < 64) out[j++] = (uint8_t)((b2 << 6) | b3); |
| 167 | } |
| 168 | |
| 169 | return outLength; |
| 170 | } |
| 171 | |
| 172 | size_t Decode(const std::string &in, std::vector<uint8_t> &out) { |
| 173 | uint8_t *outPtr = nullptr; |
nothing calls this directly
no test coverage detected