15 * |
15 * |
16 */ |
16 */ |
17 |
17 |
18 |
18 |
19 #include <e32base.h> |
19 #include <e32base.h> |
20 #include "base64.h" |
20 #include "Base64.h" |
21 |
21 |
22 /* 6 LOCAL DEFINITIONS */ |
22 /* 6 LOCAL DEFINITIONS */ |
23 |
23 |
24 /* 6.1 Local include files */ |
24 /* 6.1 Local include files */ |
25 |
25 |
26 /* 6.2 Local constants */ |
26 /* 6.2 Local constants */ |
27 |
27 |
28 LOCAL_C const TUint8 pBase64[] = |
28 LOCAL_C const TUint8 pBase64[] = |
29 { |
29 { |
30 0x3e, 0x7f, 0x7f, 0x7f, 0x3f, 0x34, 0x35, 0x36, |
30 0x3e, 0x7f, 0x7f, 0x7f, 0x3f, 0x34, 0x35, 0x36, |
31 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x7f, |
31 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x7f, |
32 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x00, 0x01, |
32 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x00, 0x01, |
33 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, |
33 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, |
34 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, |
34 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, |
35 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, |
35 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, |
36 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x1a, 0x1b, |
36 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x1a, 0x1b, |
37 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, |
37 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, |
38 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, |
38 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, |
39 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33 |
39 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33 |
40 }; |
40 }; |
41 |
41 |
42 /* 6.3 Local macros */ |
42 /* 6.3 Local macros */ |
43 #define b64blocks(l) (((l) + 2) / 3 * 4) |
43 #define b64blocks(l) (((l) + 2) / 3 * 4) |
44 /* #define b64octets(l) ((l) / 4 * 3) */ |
44 /* #define b64octets(l) ((l) / 4 * 3) */ |
45 |
45 |
82 * |
82 * |
83 destination_length |
83 destination_length |
84 * |
84 * |
85 * Return values |
85 * Return values |
86 * |
86 * |
87 * byte 0 if OK else > 0 |
87 * byte 0 if OK else > 0 |
88 */ |
88 */ |
89 |
89 |
90 /* ---------------------------------------------------------------------- */ |
90 /* ---------------------------------------------------------------------- */ |
91 |
91 |
92 TInt b64decode(TUint8 *source, TUint32 length, TUint8 *destination, TUint32 *destination_length) |
92 TInt b64decode(TUint8 *source, TUint32 length, TUint8 *destination, TUint32 *destination_length) |
93 { |
93 { |
94 /* Data structures */ |
94 /* Data structures */ |
95 |
95 |
96 /* Code */ |
96 /* Code */ |
97 |
97 |
98 TUint8 *buf/*, *pbuf*/; /* Decoding buffer pointers. */ |
98 TUint8 *buf/*, *pbuf*/; /* Decoding buffer pointers. */ |
99 register TUint32 x = 0; /* General purpose integers. */ |
99 register TUint32 x = 0; /* General purpose integers. */ |
100 TUint32 buf_index = 0; /* current index in destination buffer */ |
100 TUint32 buf_index = 0; /* current index in destination buffer */ |
101 |
101 |
102 |
102 |
103 /* buffer to avoid allocating wholly new buffer for output */ |
103 /* buffer to avoid allocating wholly new buffer for output */ |
104 TUint8 localBuffer[4] = {0,0,0,0}; |
104 TUint8 localBuffer[4] = {0,0,0,0}; |
105 TUint8* pLocalBufferOutPointer = 0; |
105 TUint8* pLocalBufferOutPointer = 0; |
106 |
106 |
107 register TUint32 i = 0; |
107 register TUint32 i = 0; |
108 TUint32 num; |
108 TUint32 num; |
109 |
109 |
110 TUint8 c = 0; /* Character to decode. */ |
110 TUint8 c = 0; /* Character to decode. */ |
111 TUint8 localBufferIndex = 0; |
111 TUint8 localBufferIndex = 0; |
112 |
112 |
113 /* int32 buf_length = 0; */ /* new length of destination buf */ |
113 /* int32 buf_length = 0; */ /* new length of destination buf */ |
114 const TUint8 pad = 0x3d; /* '=' */ |
114 const TUint8 pad = 0x3d; /* '=' */ |
115 |
115 |
116 if(!source || length == 0 || !destination || !destination_length) |
116 if(!source || length == 0 || !destination || !destination_length) |
117 { |
117 { |
118 return KErrArgument; |
118 return KErrArgument; |
119 } |
119 } |
120 |
120 |
121 /* Collating sequence independant "===". */ |
121 /* Collating sequence independant "===". */ |
122 |
122 |
123 /* Calculate the amount of '=' in the end of the source */ |
123 /* Calculate the amount of '=' in the end of the source */ |
124 for(x=0, buf=source + (length-1); *buf == pad; buf --) |
124 for(x=0, buf=source + (length-1); *buf == pad; buf --) |
125 { |
125 { |
126 x++; |
126 x++; |
127 } |
127 } |
128 |
128 |
129 /* max allow 3 "===" in the end of content */ |
129 /* max allow 3 "===" in the end of content */ |
130 if (x > 3) |
130 if (x > 3) |
131 { |
131 { |
132 return KErrArgument; |
132 return KErrArgument; |
133 } |
133 } |
134 |
134 |
135 /* Save the encoded string pointer. */ |
135 /* Save the encoded string pointer. */ |
136 // pbuf = destination; |
136 // pbuf = destination; |
137 |
137 |
138 /* save address for first output block */ |
138 /* save address for first output block */ |
139 pLocalBufferOutPointer = destination; |
139 pLocalBufferOutPointer = destination; |
140 x = 0; /* Initialize index. */ |
140 x = 0; /* Initialize index. */ |
141 |
141 |
142 localBufferIndex = 0; |
142 localBufferIndex = 0; |
143 |
143 |
144 |
144 |
145 Mem::Copy(localBuffer, source, 4); |
145 Mem::Copy(localBuffer, source, 4); |
146 |
146 |
147 for (i = length; i != 0; i-- ) /* Decode every byte of the base 64 string */ |
147 for (i = length; i != 0; i-- ) /* Decode every byte of the base 64 string */ |
148 { |
148 { |
149 /* c = *pbuf++; */ |
149 /* c = *pbuf++; */ |
150 c = localBuffer[localBufferIndex++]; |
150 c = localBuffer[localBufferIndex++]; |
151 |
151 |
152 if(localBufferIndex == 4) |
152 if(localBufferIndex == 4) |
153 { |
153 { |
154 localBufferIndex = 0; |
154 localBufferIndex = 0; |
155 |
155 |
156 source = source + 4; |
156 source = source + 4; |
157 |
157 |
158 /* INPUT: copy next input block to local buffer */ |
158 /* INPUT: copy next input block to local buffer */ |
159 num = i > 4 ? 4 : i - 1; |
159 num = i > 4 ? 4 : i - 1; |
160 if(num > 0) |
160 if(num > 0) |
161 { |
161 { |
162 Mem::Copy(localBuffer, source, num); |
162 Mem::Copy(localBuffer, source, num); |
163 } |
163 } |
164 } |
164 } |
165 |
165 |
166 /* Ignore "=". */ |
166 /* Ignore "=". */ |
167 if (c == pad) |
167 if (c == pad) |
168 { |
168 { |
169 break; /* this must be the end of the buffer, or else ve have a invalid character */ |
169 break; /* this must be the end of the buffer, or else ve have a invalid character */ |
170 } |
170 } |
171 |
171 |
172 if (c == '\n' || c == '\r' || c == '\t') /* ignore linefeed tab and cr */ |
172 if (c == '\n' || c == '\r' || c == '\t') /* ignore linefeed tab and cr */ |
173 { |
173 { |
174 continue; |
174 continue; |
175 } |
175 } |
176 |
176 |
177 /* Valid Base64 Index? */ |
177 /* Valid Base64 Index? */ |
178 if (!b64valid(&c)) |
178 if (!b64valid(&c)) |
179 { |
179 { |
180 /* b64free(buf); */ |
180 /* b64free(buf); */ |
181 return KErrArgument; |
181 return KErrArgument; |
182 } |
182 } |
183 |
183 |
184 /* Decode 4 byte words into 3 byte octets.*/ |
184 /* Decode 4 byte words into 3 byte octets.*/ |
185 switch(x % 4) |
185 switch(x % 4) |
186 { |
186 { |
187 case 0: /* Byte 0 of word.*/ |
187 case 0: /* Byte 0 of word.*/ |
188 pLocalBufferOutPointer[buf_index] = (TInt8)(c << 2); |
188 pLocalBufferOutPointer[buf_index] = (TInt8)(c << 2); |
189 break; |
189 break; |
190 case 1: /* Byte 1 of word. */ |
190 case 1: /* Byte 1 of word. */ |
191 pLocalBufferOutPointer[buf_index] |= c >> 4; |
191 pLocalBufferOutPointer[buf_index] |= c >> 4; |
192 buf_index ++; |
192 buf_index ++; |
193 pLocalBufferOutPointer[buf_index] = (TInt8)( (c & 0x0f) << 4 ); |
193 pLocalBufferOutPointer[buf_index] = (TInt8)( (c & 0x0f) << 4 ); |
194 break; |
194 break; |
195 case 2: /* Byte 2 of word. */ |
195 case 2: /* Byte 2 of word. */ |
196 pLocalBufferOutPointer[buf_index] |= c >> 2; |
196 pLocalBufferOutPointer[buf_index] |= c >> 2; |
197 buf_index ++; |
197 buf_index ++; |
198 pLocalBufferOutPointer[buf_index] = (TInt8)( (c & 0x03) << 6 ); |
198 pLocalBufferOutPointer[buf_index] = (TInt8)( (c & 0x03) << 6 ); |
199 break; |
199 break; |
200 case 3: /* Byte 3 of word. */ |
200 case 3: /* Byte 3 of word. */ |
201 pLocalBufferOutPointer[buf_index] |= c; |
201 pLocalBufferOutPointer[buf_index] |= c; |
202 buf_index ++; |
202 buf_index ++; |
203 break; |
203 break; |
204 default: /* useless, just to depress warnings */ |
204 default: /* useless, just to depress warnings */ |
205 break; |
205 break; |
206 } |
206 } |
207 |
207 |
208 x++; /* Increment word byte. */ |
208 x++; /* Increment word byte. */ |
209 |
209 |
210 |
210 |
211 } /* while */ |
211 } /* while */ |
212 |
212 |
213 |
213 |
214 /* make sure that there is zero at the end of the buffer |
214 /* make sure that there is zero at the end of the buffer |
215 though buf[buf_index] shoule be zero after decoding |
215 though buf[buf_index] shoule be zero after decoding |
216 */ |
216 */ |
217 |
217 |
218 |
218 |
219 /* pbuf[buf_index+1] = 0; */ |
219 /* pbuf[buf_index+1] = 0; */ |
220 |
220 |
221 /*buf[buf_index+1]=0*/ |
221 /*buf[buf_index+1]=0*/ |
222 /* don't return the size of the buffer (buf_length), but the data size we put in (buf_index)*/ |
222 /* don't return the size of the buffer (buf_length), but the data size we put in (buf_index)*/ |
223 *destination_length = buf_index; |
223 *destination_length = buf_index; |
224 return KErrNone; |
224 return KErrNone; |
225 } |
225 } |
226 |
226 |
227 /* 7.3 */ |
227 /* 7.3 */ |
228 |
228 |
229 /* Functional description |
229 /* Functional description |
230 * |
230 * |