/* * $Id: base64.h,v 1.1 2007/07/19 08:24:50 pippijn Exp $ */ /* base64.h - base64 enc algorithm */ #ifndef BASE64_H #define BASE64_H #include namespace base64 { class encoder { enum step { step_a, step_b, step_c }; struct state { enum step step; char result; int stepcnt; }; static size_t enc_block (char const * const text, size_t inlen, char *code, state *st); static size_t enc_blockend (char *code, state *st); static size_t const CHARS_PER_LINE = 72; static char enc_value (char val) { static char const * const enc = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; if (val > 63) return '='; return enc[(size_t) val]; } state m_state; size_t m_bufsize; size_t enc_end (char *outtext) { return enc_blockend (outtext, &m_state); } public: encoder (size_t bufsize = 4096) : m_bufsize (bufsize) { } size_t encode (char val) { return enc_value (val); } size_t encode (char const * const code, size_t const inlen, char *outtext) { return enc_block (code, inlen, outtext, &m_state); } bool encode (char const * const code, size_t const inlen, char **outtext) { size_t outlen = 1 + (((inlen + 2) / 3) * 4); if (inlen > outlen) { *outtext = NULL; return 0; } *outtext = new char[outlen]; if (*outtext) encode (code, inlen, *outtext); return outlen - 1; } }; class decoder { enum step { step_a, step_b, step_c, step_d }; struct state { enum step step; char plainchar; }; static size_t dec_block (char const * const code, size_t const inlen, char *outtext, state *st); static size_t dec_value (char val) { static char const dec[] = { 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 }; static char const decsize = sizeof (dec); val -= 43; if (val < 0 || val > decsize) return -1; return dec[(size_t) val]; } state m_state; size_t m_bufsize; public: decoder (size_t bufsize = 4096) : m_bufsize (bufsize) { } size_t decode (char val) { return dec_value (val); } size_t decode (char const * const code, size_t const inlen, char *outtext) { return dec_block (code, inlen, outtext, &m_state); } bool decode (char const * const code, size_t const inlen, char **outtext, size_t *outlen) { size_t needlen = 3 * (inlen / 4) + 3; *outtext = new char[needlen]; if (!*outtext) return false; if (!decode (code, inlen, *outtext)) { delete[] *outtext; *outtext = NULL; return false; } (*outtext)[needlen] = '\0'; if (outlen) *outlen = needlen; return true; } }; } // namespace base64 #endif // BASE64_H