| 1215 | } |
| 1216 | |
| 1217 | int Base64EscapeInternal(const unsigned char *src, int szsrc, |
| 1218 | char *dest, int szdest, const char *base64, |
| 1219 | bool do_padding) { |
| 1220 | static const char kPad64 = '='; |
| 1221 | |
| 1222 | if (szsrc <= 0) return 0; |
| 1223 | |
| 1224 | char *cur_dest = dest; |
| 1225 | const unsigned char *cur_src = src; |
| 1226 | |
| 1227 | // Three bytes of data encodes to four characters of cyphertext. |
| 1228 | // So we can pump through three-byte chunks atomically. |
| 1229 | while (szsrc > 2) { /* keep going until we have less than 24 bits */ |
| 1230 | if ((szdest -= 4) < 0) return 0; |
| 1231 | cur_dest[0] = base64[cur_src[0] >> 2]; |
| 1232 | cur_dest[1] = base64[((cur_src[0] & 0x03) << 4) + (cur_src[1] >> 4)]; |
| 1233 | cur_dest[2] = base64[((cur_src[1] & 0x0f) << 2) + (cur_src[2] >> 6)]; |
| 1234 | cur_dest[3] = base64[cur_src[2] & 0x3f]; |
| 1235 | |
| 1236 | cur_dest += 4; |
| 1237 | cur_src += 3; |
| 1238 | szsrc -= 3; |
| 1239 | } |
| 1240 | |
| 1241 | /* now deal with the tail (<=2 bytes) */ |
| 1242 | switch (szsrc) { |
| 1243 | case 0: |
| 1244 | // Nothing left; nothing more to do. |
| 1245 | break; |
| 1246 | case 1: |
| 1247 | // One byte left: this encodes to two characters, and (optionally) |
| 1248 | // two pad characters to round out the four-character cypherblock. |
| 1249 | if ((szdest -= 2) < 0) return 0; |
| 1250 | cur_dest[0] = base64[cur_src[0] >> 2]; |
| 1251 | cur_dest[1] = base64[(cur_src[0] & 0x03) << 4]; |
| 1252 | cur_dest += 2; |
| 1253 | if (do_padding) { |
| 1254 | if ((szdest -= 2) < 0) return 0; |
| 1255 | cur_dest[0] = kPad64; |
| 1256 | cur_dest[1] = kPad64; |
| 1257 | cur_dest += 2; |
| 1258 | } |
| 1259 | break; |
| 1260 | case 2: |
| 1261 | // Two bytes left: this encodes to three characters, and (optionally) |
| 1262 | // one pad character to round out the four-character cypherblock. |
| 1263 | if ((szdest -= 3) < 0) return 0; |
| 1264 | cur_dest[0] = base64[cur_src[0] >> 2]; |
| 1265 | cur_dest[1] = base64[((cur_src[0] & 0x03) << 4) + (cur_src[1] >> 4)]; |
| 1266 | cur_dest[2] = base64[(cur_src[1] & 0x0f) << 2]; |
| 1267 | cur_dest += 3; |
| 1268 | if (do_padding) { |
| 1269 | if ((szdest -= 1) < 0) return 0; |
| 1270 | cur_dest[0] = kPad64; |
| 1271 | cur_dest += 1; |
| 1272 | } |
| 1273 | break; |
| 1274 | default: |
no test coverage detected