diff options
Diffstat (limited to 'libmail/base64.C')
| -rw-r--r-- | libmail/base64.C | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/libmail/base64.C b/libmail/base64.C new file mode 100644 index 0000000..6b2d19a --- /dev/null +++ b/libmail/base64.C @@ -0,0 +1,198 @@ +/* +** Copyright 2002, Double Precision Inc. +** +** See COPYING for distribution information. +*/ +#include "libmail_config.h" +#include "base64.H" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +using namespace std; + +// base64 decoding table. + +static const unsigned char decode64tab[256]={ + 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, + 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, + 100,100,100,100,100,100,100,100,100,100,100,62,100,100,100,63, + 52,53,54,55,56,57,58,59,60,61,100,100,100,99,100,100, + 100,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,100,100,100,100,100, + 100,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,100,100,100,100,100, + 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, + 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, + 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, + 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, + 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, + 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, + 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, + 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100}; + + +mail::decodebase64::decodebase64() +{ + decodeBuffer=""; +} + +mail::decodebase64::~decodebase64() +{ +} + +void mail::decodebase64::decode(string text) +{ + char workbuf[BUFSIZ]; + + // Toss out the crud (newlines, spaces, etc..) + + string::iterator b=text.begin(), e=text.end(); + string::iterator c=b; + + while (b != e) + { + if (decode64tab[(int)(unsigned char)*b] == 100) + { + // Ignore non-base64 characters. + b++; + continue; + } + *c++=*b++; + } + + // Something might be left over from the previous run. Tis ok. + + b=text.begin(); + + if (c != b) + decodeBuffer.append(b, c); + + + size_t i=decodeBuffer.length()/4; // The remainder gets left over. + + char aa,bb,cc; + + b=decodeBuffer.begin(); + + size_t k=0; + + string decodedbuf=""; + + while (i) + { + unsigned char d=*b++; + unsigned char e=*b++; + unsigned char f=*b++; + unsigned char g=*b++; + + int w=decode64tab[d]; + int x=decode64tab[e]; + int y=decode64tab[f]; + int z=decode64tab[g]; + + aa= (w << 2) | (x >> 4); + bb= (x << 4) | (y >> 2); + cc= (y << 6) | z; + + workbuf[k++]=aa; + if ( f != '=') + workbuf[k++]=bb; + if ( g != '=') + workbuf[k++]=cc; + + if (k >= sizeof(workbuf)-10) + { + decodedbuf.append(workbuf, k); + k=0; + } + --i; + } + if (k > 0) + decodedbuf.append(workbuf, k); + + string left=""; + left.append(b, decodeBuffer.end()); + decodeBuffer=left; + + decoded(decodedbuf); +} + +// +// The encoder does NOT insert newline breaks. That's the superclass's job. + +mail::encodebase64::encodebase64() +{ + libmail_encode_start(&encodeInfo, "base64", &callback_func, this); +} + +mail::encodebase64::~encodebase64() +{ +} + +void mail::encodebase64::encode(string text) +{ + libmail_encode(&encodeInfo, &text[0], text.size()); +} + +void mail::encodebase64::flush() +{ + libmail_encode_end(&encodeInfo); +} + +int mail::encodebase64::callback_func(const char *ptr, size_t len, void *vp) +{ + string s=string(ptr, ptr+len); + size_t n; + + while ((n=s.find('\n')) != std::string::npos) + s.erase(s.begin()+n); + + ((mail::encodebase64 *)vp)->encoded(s); + return 0; +} + +///////////////////////////////////////////////////////////////////////////// +// +// The convenience classes. + +mail::decodebase64str::decodebase64str() + : challengeStr("") +{ +} + +mail::decodebase64str::decodebase64str(string s) + : challengeStr("") +{ + decode(s); +} + +mail::decodebase64str::~decodebase64str() +{ +} + +void mail::decodebase64str::decoded(string s) +{ + challengeStr += s; +} + +mail::encodebase64str::encodebase64str() : responseStr("") +{ +} + +mail::encodebase64str::encodebase64str(string s) + : responseStr("") +{ + encode(s); + flush(); +} + +mail::encodebase64str::~encodebase64str() +{ +} + +void mail::encodebase64str::encoded(string s) +{ + responseStr += s; +} + |
