00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
#include "wvbase64.h"
00016
00017
00018 static char alphabet[67] =
00019
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n";
00020
00021
00022 static int lookup(
char ch)
00023 {
00024
if (ch >=
'A' && ch <=
'Z')
00025
return ch -
'A';
00026
if (ch >=
'a' && ch <=
'z')
00027
return ch -
'a' + 26;
00028
if (ch >=
'0' && ch <=
'9')
00029
return ch -
'0' + 52;
00030
if (ch ==
'+')
00031
return 62;
00032
if (ch ==
'/')
00033
return 63;
00034
if (ch ==
'=')
00035
return 64;
00036
if (ch ==
'\n' || ch ==
' ' || ch ==
'\r' || ch ==
'\t' ||
00037 ch ==
'\f' || ch ==
'\v')
00038
return 65;
00039
return -1;
00040 }
00041
00042
00043
00044
00045 WvBase64Encoder::WvBase64Encoder()
00046 {
00047
_reset();
00048 }
00049
00050
00051 bool WvBase64Encoder::_reset()
00052 {
00053 state = ATBIT0;
00054 bits = 0;
00055
return true;
00056 }
00057
00058
00059 bool WvBase64Encoder::_encode(
WvBuf &in,
WvBuf &out,
bool flush)
00060 {
00061
00062
while (in.
used() != 0)
00063 {
00064
unsigned char next = in.
getch();
00065 bits = (bits << 8) | next;
00066
switch (state)
00067 {
00068
case ATBIT0:
00069 out.
putch(
alphabet[bits >> 2]);
00070 bits &= 0x03;
00071 state = ATBIT2;
00072
break;
00073
case ATBIT2:
00074 out.
putch(
alphabet[bits >> 4]);
00075 bits &= 0x0f;
00076 state = ATBIT4;
00077
break;
00078
case ATBIT4:
00079 out.
putch(
alphabet[bits >> 6]);
00080 out.
putch(
alphabet[bits & 0x3f]);
00081 bits = 0;
00082 state = ATBIT0;
00083
break;
00084 }
00085 }
00086
00087
if (flush && state != ATBIT0)
00088
return false;
00089
return true;
00090 }
00091
00092
00093 bool WvBase64Encoder::_finish(
WvBuf &out)
00094 {
00095
00096
switch (state)
00097 {
00098
case ATBIT2:
00099 out.
putch(
alphabet[bits << 4]);
00100 out.
putch(
'=');
00101 out.
putch(
'=');
00102
break;
00103
case ATBIT4:
00104 out.
putch(
alphabet[bits << 2]);
00105 out.
putch(
'=');
00106
break;
00107
case ATBIT0:
00108
break;
00109 }
00110
return true;
00111 }
00112
00113
00114
00115
00116
00117 WvBase64Decoder::WvBase64Decoder()
00118 {
00119
_reset();
00120 }
00121
00122
00123 bool WvBase64Decoder::_reset()
00124 {
00125 state = ATBIT0;
00126 bits = 0;
00127
return true;
00128 }
00129
00130
00131 bool WvBase64Decoder::_encode(
WvBuf &in,
WvBuf &out,
bool flush)
00132 {
00133
00134
while (in.
used() != 0)
00135 {
00136
unsigned char next = in.
getch();
00137
int symbol =
lookup(next);
00138
switch (symbol)
00139 {
00140
case -1:
00141 seterror(
"invalid character '%s' in base64 input", next);
00142
return false;
00143
00144
case 64:
00145
00146
00147
setfinished();
00148 state = PAD;
00149
break;
00150
00151
case 65:
00152
break;
00153
00154
default:
00155 bits = (bits << 6) | symbol;
00156
switch (state)
00157 {
00158
case ATBIT0:
00159 state = ATBIT2;
00160
break;
00161
case ATBIT2:
00162 out.
putch(bits >> 4);
00163 bits &= 0x0f;
00164 state = ATBIT4;
00165
break;
00166
case ATBIT4:
00167 out.
putch(bits >> 2);
00168 bits &= 0x03;
00169 state = ATBIT6;
00170
break;
00171
case ATBIT6:
00172 out.
putch(bits);
00173 bits = 0;
00174 state = ATBIT0;
00175
break;
00176
00177
case PAD:
00178 seterror(
"invalid character '%s' "
00179
"after base64 padding", next);
00180
return false;
00181 }
00182
break;
00183 }
00184 }
00185
00186
if (flush && (state == ATBIT2 || state == ATBIT4 || state == ATBIT6))
00187
return false;
00188
return true;
00189 }