#include "P64.h" P64Decoder::P64Decoder() { for (int i = 0; i < 256; i++) { value[i] = badValue; } int currentValue = 0; for (int i = 'a'; i <= 'z'; i++) { value[i] = currentValue++; } for (int i = 'A'; i <= 'Z'; i++) { value[i] = currentValue++; } for (int i = '0'; i <= '9'; i++) { value[i] = currentValue++; } value['_'] = currentValue++; value['-'] = currentValue; } bool P64Decoder::decode(std::string input, std::string &output) const { int inputLength = input.length(); int q = inputLength / 4; int r = inputLength % 4; if (r == 1) { return false; } int outputLength = q * 3; if (r > 0) { outputLength += r - 1; } unsigned char *workspace = new unsigned char[outputLength]; unsigned int tail = 0; // Note: We may need the extra character added at the end by c_str(). We // won't actually use its value. But it will copy it into our buffer. This // makes the code much simpler. const unsigned char *inputPointer = (const unsigned char *)(input.c_str()); unsigned char *outputPointer = workspace; unsigned char *finished = outputPointer + outputLength; int position = 0; while (outputPointer < finished) { int newValue = value[*inputPointer++]; if (newValue == badValue) { delete[] workspace; return false; } tail <<= 6; tail |= newValue; switch (position) { case 0: position = 1; break; case 1: *outputPointer++ = (tail >> 4); position = 2; break; case 2: *outputPointer++ = (tail >> 2); position = 3; break; case 3: *outputPointer++ = tail; position = 0; break; } } output.assign((char *)(workspace), outputLength); delete[] workspace; return true; }