ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/ermyth/libermyth/util/base64.C
Revision: 1.1
Committed: Sat Sep 22 14:27:26 2007 UTC (16 years, 8 months ago) by pippijn
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Log Message:
split up ermyth into ermyth-modules, libermyth (currently just ermyth-util) and ermyth-core

File Contents

# Content
1 #include <util/base64.h>
2
3 namespace base64
4 {
5 const int CHARS_PER_LINE = 72;
6
7 void base64_init_encodestate (base64_encodestate * state_in)
8 {
9 state_in->step = step_A;
10 state_in->result = 0;
11 state_in->stepcount = 0;
12 }
13
14 char base64_encode_value (char value_in)
15 {
16 static const char *encoding = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
17 if (value_in > 63)
18 return '=';
19 return encoding[(int) value_in];
20 }
21
22 int base64_encode_block (const char *plaintext_in, int length_in, char *code_out, base64_encodestate * state_in)
23 {
24 const char *plainchar = plaintext_in;
25 const char *const plaintextend = plaintext_in + length_in;
26 char *codechar = code_out;
27 char result;
28 char fragment;
29
30 result = state_in->result;
31
32 switch (state_in->step)
33 {
34 while (1)
35 {
36 case step_A:
37 if (plainchar == plaintextend)
38 {
39 state_in->result = result;
40 state_in->step = step_A;
41 return codechar - code_out;
42 }
43 fragment = *plainchar++;
44 result = (fragment & 0x0fc) >> 2;
45 *codechar++ = base64_encode_value (result);
46 result = (fragment & 0x003) << 4;
47 case step_B:
48 if (plainchar == plaintextend)
49 {
50 state_in->result = result;
51 state_in->step = step_B;
52 return codechar - code_out;
53 }
54 fragment = *plainchar++;
55 result |= (fragment & 0x0f0) >> 4;
56 *codechar++ = base64_encode_value (result);
57 result = (fragment & 0x00f) << 2;
58 case step_C:
59 if (plainchar == plaintextend)
60 {
61 state_in->result = result;
62 state_in->step = step_C;
63 return codechar - code_out;
64 }
65 fragment = *plainchar++;
66 result |= (fragment & 0x0c0) >> 6;
67 *codechar++ = base64_encode_value (result);
68 result = (fragment & 0x03f) >> 0;
69 *codechar++ = base64_encode_value (result);
70
71 ++(state_in->stepcount);
72 if (state_in->stepcount == CHARS_PER_LINE / 4)
73 {
74 *codechar++ = '\n';
75 state_in->stepcount = 0;
76 }
77 }
78 }
79 /* control should not reach here */
80 return codechar - code_out;
81 }
82
83 int base64_encode_blockend (char *code_out, base64_encodestate * state_in)
84 {
85 char *codechar = code_out;
86
87 switch (state_in->step)
88 {
89 case step_B:
90 *codechar++ = base64_encode_value (state_in->result);
91 *codechar++ = '=';
92 *codechar++ = '=';
93 break;
94 case step_C:
95 *codechar++ = base64_encode_value (state_in->result);
96 *codechar++ = '=';
97 break;
98 case step_A:
99 break;
100 }
101 *codechar++ = '\n';
102
103 return codechar - code_out;
104 }
105
106 //////////////////////
107 int base64_decode_value (char value_in)
108 {
109 static const char decoding[] = { 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 };
110 static const char decoding_size = sizeof (decoding);
111 value_in -= 43;
112 if (value_in < 0 || value_in > decoding_size)
113 return -1;
114 return decoding[(int) value_in];
115 }
116
117 void base64_init_decodestate (base64_decodestate * state_in)
118 {
119 state_in->step = step_a;
120 state_in->plainchar = 0;
121 }
122
123 int base64_decode_block (const char *code_in, const int length_in, char *plaintext_out, base64_decodestate * state_in)
124 {
125 const char *codechar = code_in;
126 char *plainchar = plaintext_out;
127 char fragment;
128
129 *plainchar = state_in->plainchar;
130
131 switch (state_in->step)
132 {
133 while (1)
134 {
135 case step_a:
136 do
137 {
138 if (codechar == code_in + length_in)
139 {
140 state_in->step = step_a;
141 state_in->plainchar = *plainchar;
142 return plainchar - plaintext_out;
143 }
144 fragment = (char) base64_decode_value (*codechar++);
145 }
146 while (fragment < 0);
147 *plainchar = (fragment & 0x03f) << 2;
148 case step_b:
149 do
150 {
151 if (codechar == code_in + length_in)
152 {
153 state_in->step = step_b;
154 state_in->plainchar = *plainchar;
155 return plainchar - plaintext_out;
156 }
157 fragment = (char) base64_decode_value (*codechar++);
158 }
159 while (fragment < 0);
160 *plainchar++ |= (fragment & 0x030) >> 4;
161 *plainchar = (fragment & 0x00f) << 4;
162 case step_c:
163 do
164 {
165 if (codechar == code_in + length_in)
166 {
167 state_in->step = step_c;
168 state_in->plainchar = *plainchar;
169 return plainchar - plaintext_out;
170 }
171 fragment = (char) base64_decode_value (*codechar++);
172 }
173 while (fragment < 0);
174 *plainchar++ |= (fragment & 0x03c) >> 2;
175 *plainchar = (fragment & 0x003) << 6;
176 case step_d:
177 do
178 {
179 if (codechar == code_in + length_in)
180 {
181 state_in->step = step_d;
182 state_in->plainchar = *plainchar;
183 return plainchar - plaintext_out;
184 }
185 fragment = (char) base64_decode_value (*codechar++);
186 }
187 while (fragment < 0);
188 *plainchar++ |= (fragment & 0x03f);
189 }
190 }
191 /* control should not reach here */
192 return plainchar - plaintext_out;
193 }
194 }