2 * Worldvisions Weaver Software:
3 * Copyright (C) 1997-2002 Net Integration Technologies, Inc.
5 * Functions for encoding and decoding strings in MIME's Base64 notation.
7 * Base 64 is pretty easy. The input is processed in groups of three bytes.
8 * These 24 bits are split into 4 groups of 6 bits. Each group of six bits
9 * is represented by one character in the base64 alphabet, in the encoded
10 * output. The alphabet is as follows:
11 * ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=
12 * Where 'A' through '/' represent 000000 through 011111, the 64 different
13 * combinations. The '=' (100000) is padding and has no value when decoded.
17 // maps codes to the Base64 alphabet
18 static char alphabet
[67] =
19 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n";
21 // finds codes in the Base64 alphabet
22 static int lookup(char ch
)
24 if (ch
>= 'A' && ch
<= 'Z')
26 if (ch
>= 'a' && ch
<= 'z')
28 if (ch
>= '0' && ch
<= '9')
36 if (ch
== '\n' || ch
== ' ' || ch
== '\r' || ch
== '\t' ||
37 ch
== '\f' || ch
== '\v')
38 return 65; // whitespace
43 /***** WvBase64Encoder *****/
45 WvBase64Encoder::WvBase64Encoder()
51 bool WvBase64Encoder::_reset()
59 bool WvBase64Encoder::_encode(WvBuf
&in
, WvBuf
&out
, bool flush
)
61 // base 64 encode the entire buffer
62 while (in
.used() != 0)
64 unsigned char next
= in
.getch();
65 bits
= (bits
<< 8) | next
;
69 out
.putch(alphabet
[bits
>> 2]);
74 out
.putch(alphabet
[bits
>> 4]);
79 out
.putch(alphabet
[bits
>> 6]);
80 out
.putch(alphabet
[bits
& 0x3f]);
86 // do not consider the data flushed if we need padding
87 if (flush
&& state
!= ATBIT0
)
93 bool WvBase64Encoder::_finish(WvBuf
&out
)
99 out
.putch(alphabet
[bits
<< 4]);
104 out
.putch(alphabet
[bits
<< 2]);
115 /***** WvBase64Decoder *****/
117 WvBase64Decoder::WvBase64Decoder()
123 bool WvBase64Decoder::_reset()
131 bool WvBase64Decoder::_encode(WvBuf
&in
, WvBuf
&out
, bool flush
)
133 // base 64 decode the entire buffer
134 while (in
.used() != 0)
136 unsigned char next
= in
.getch();
137 int symbol
= lookup(next
);
140 case -1: // invalid character
141 seterror("invalid character #%s in base64 input", next
);
145 // strip out any remaining padding
146 // we are lenient in that we do not track how much padding we skip
151 case 65: // whitespace
154 default: // other symbol
155 bits
= (bits
<< 6) | symbol
;
162 out
.putch(bits
>> 4);
167 out
.putch(bits
>> 2);
178 seterror("invalid character #%s "
179 "after base64 padding", next
);
185 // if flushing and we did not get sufficient padding, then fail
186 if (flush
&& (state
== ATBIT2
|| state
== ATBIT4
|| state
== ATBIT6
))
187 return false; // insufficient padding to flush!