diff options
Diffstat (limited to 'xdelta1/libedsio/base64.c')
-rw-r--r-- | xdelta1/libedsio/base64.c | 525 |
1 files changed, 0 insertions, 525 deletions
diff --git a/xdelta1/libedsio/base64.c b/xdelta1/libedsio/base64.c deleted file mode 100644 index c37ddae..0000000 --- a/xdelta1/libedsio/base64.c +++ /dev/null | |||
@@ -1,525 +0,0 @@ | |||
1 | /* -*-Mode: C;-*- | ||
2 | * $Id: base64.c 1.1 Sun, 28 Jan 2007 10:02:26 -0800 jmacd $ | ||
3 | * | ||
4 | * Copyright (C) 1998, 1999, Josh MacDonald. | ||
5 | * All Rights Reserved. | ||
6 | * | ||
7 | * Author: Josh MacDonald <jmacd@CS.Berkeley.EDU> | ||
8 | */ | ||
9 | |||
10 | #include "edsio.h" | ||
11 | |||
12 | /* BASE64 Encoding | ||
13 | */ | ||
14 | |||
15 | static const unsigned char base64_table[64] = { | ||
16 | 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', | ||
17 | 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', | ||
18 | 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', | ||
19 | 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', | ||
20 | '3', '4', '5', '6', '7', '8', '9', '+', '/' | ||
21 | }; | ||
22 | |||
23 | static gint16 base64_inverse_table[128]; | ||
24 | |||
25 | static void | ||
26 | init_inverse_table (void) | ||
27 | { | ||
28 | static int i = 0; | ||
29 | static int j = 0; | ||
30 | |||
31 | for (; j < 128; j += 1) | ||
32 | base64_inverse_table[j] = -1; | ||
33 | |||
34 | for (; i < 64; i += 1) | ||
35 | base64_inverse_table[base64_table[i]] = i; | ||
36 | |||
37 | base64_inverse_table['='] = 0; | ||
38 | } | ||
39 | |||
40 | GByteArray* | ||
41 | edsio_base64_encode_region (const guint8* data, guint len) | ||
42 | { | ||
43 | GByteArray* out = g_byte_array_new (); | ||
44 | guint real_len; | ||
45 | |||
46 | g_byte_array_set_size (out, (len+2)*4/3); | ||
47 | |||
48 | real_len = out->len; | ||
49 | |||
50 | if (! edsio_base64_encode_region_into (data, len, out->data, &real_len)) | ||
51 | { | ||
52 | g_byte_array_free (out, TRUE); | ||
53 | return NULL; | ||
54 | } | ||
55 | |||
56 | g_byte_array_set_size (out, real_len); | ||
57 | |||
58 | return out; | ||
59 | } | ||
60 | |||
61 | gboolean | ||
62 | edsio_base64_encode_region_into (const guint8* data, guint len, guint8* out, guint *out_len) | ||
63 | { | ||
64 | gint i; | ||
65 | guint32 word = 0, count = 0; | ||
66 | |||
67 | if ((*out_len) < (len + 2) * 4/3) | ||
68 | { | ||
69 | edsio_generate_void_event (EC_EdsioInvalidBase64Encoding); | ||
70 | return FALSE; | ||
71 | } | ||
72 | |||
73 | *out_len = 0; | ||
74 | |||
75 | for (i = 0; i < len; i += 1) | ||
76 | { | ||
77 | word |= data[i] << (8*(2-(count++))); | ||
78 | |||
79 | if (count == 3) | ||
80 | { | ||
81 | out[(*out_len)++] = base64_table[(word>>18) & 0x3f]; | ||
82 | out[(*out_len)++] = base64_table[(word>>12) & 0x3f]; | ||
83 | out[(*out_len)++] = base64_table[(word>> 6) & 0x3f]; | ||
84 | out[(*out_len)++] = base64_table[(word ) & 0x3f]; | ||
85 | |||
86 | count = 0; | ||
87 | word = 0; | ||
88 | } | ||
89 | } | ||
90 | |||
91 | if (count > 0) | ||
92 | { | ||
93 | out[(*out_len)++] = base64_table[(word>>18) & 0x3f]; | ||
94 | out[(*out_len)++] = base64_table[(word>>12) & 0x3f]; | ||
95 | out[(*out_len)++] = (count > 1) ? base64_table[(word>>6) & 0x3f] : '='; | ||
96 | out[(*out_len)++] = '='; | ||
97 | } | ||
98 | |||
99 | return TRUE; | ||
100 | } | ||
101 | |||
102 | GByteArray* | ||
103 | edsio_base64_decode_region (const guint8* data, guint data_len) | ||
104 | { | ||
105 | GByteArray* it = g_byte_array_new (); | ||
106 | guint real_len; | ||
107 | |||
108 | g_byte_array_set_size (it, data_len*3/4); | ||
109 | |||
110 | real_len = it->len; | ||
111 | |||
112 | if (! edsio_base64_decode_region_into (data, data_len, it->data, &real_len)) | ||
113 | { | ||
114 | g_byte_array_free (it, TRUE); | ||
115 | return NULL; | ||
116 | } | ||
117 | |||
118 | g_byte_array_set_size (it, real_len); | ||
119 | |||
120 | return it; | ||
121 | } | ||
122 | |||
123 | gboolean | ||
124 | edsio_base64_decode_region_into (const guint8* data, guint len, guint8* out, guint *out_len) | ||
125 | { | ||
126 | guint32 pos = 0; | ||
127 | gboolean found_end = FALSE; | ||
128 | gint found_end_at = 0; | ||
129 | |||
130 | init_inverse_table (); | ||
131 | |||
132 | if ((*out_len) < (len*3/4)) | ||
133 | { | ||
134 | edsio_generate_void_event (EC_EdsioOutputBufferShort); | ||
135 | return FALSE; | ||
136 | } | ||
137 | |||
138 | (*out_len) = 0; | ||
139 | |||
140 | while (pos < len) | ||
141 | { | ||
142 | gint i, x; | ||
143 | gint word = 0, junk = 0; | ||
144 | |||
145 | if (len - pos < 4) | ||
146 | { | ||
147 | edsio_generate_void_event (EC_EdsioInvalidBase64Encoding); | ||
148 | return FALSE; | ||
149 | } | ||
150 | |||
151 | for (i = 0; i < 4; i += 1) | ||
152 | { | ||
153 | x = data[pos++]; | ||
154 | |||
155 | if (x > 127 || base64_inverse_table[x] < 0) | ||
156 | { | ||
157 | edsio_generate_void_event (EC_EdsioInvalidBase64Encoding); | ||
158 | return FALSE; | ||
159 | } | ||
160 | |||
161 | if (x == '=') | ||
162 | { | ||
163 | if (! found_end) | ||
164 | found_end_at = i; | ||
165 | |||
166 | found_end = TRUE; | ||
167 | } | ||
168 | else | ||
169 | { | ||
170 | if (found_end) | ||
171 | { | ||
172 | edsio_generate_void_event (EC_EdsioInvalidBase64Encoding); | ||
173 | return FALSE; | ||
174 | } | ||
175 | |||
176 | word |= base64_inverse_table[x] << (6*(3-i)); | ||
177 | } | ||
178 | } | ||
179 | |||
180 | if (found_end) | ||
181 | { | ||
182 | if (found_end_at < 2) | ||
183 | { | ||
184 | edsio_generate_void_event (EC_EdsioInvalidBase64Encoding); | ||
185 | return FALSE; | ||
186 | } | ||
187 | |||
188 | if (found_end_at == 2) | ||
189 | junk = 2; | ||
190 | else if (found_end_at == 3) | ||
191 | junk = 1; | ||
192 | } | ||
193 | else | ||
194 | junk = 0; | ||
195 | |||
196 | out[(*out_len)++] = (word >> 16) & 0xff; | ||
197 | |||
198 | if (junk < 2) | ||
199 | out[(*out_len)++] = (word >> 8) & 0xff; | ||
200 | |||
201 | if (junk < 1) | ||
202 | out[(*out_len)++] = (word >> 0) & 0xff; | ||
203 | } | ||
204 | |||
205 | return TRUE; | ||
206 | } | ||
207 | |||
208 | /* Base64 sink | ||
209 | */ | ||
210 | typedef struct _Base64Sink Base64Sink; | ||
211 | |||
212 | static gboolean base64_sink_close (SerialSink* sink); | ||
213 | static gboolean base64_sink_write (SerialSink* sink, const guint8 *ptr, guint32 len); | ||
214 | static void base64_sink_free (SerialSink* sink); | ||
215 | static gboolean base64_sink_quantum (SerialSink* sink); | ||
216 | |||
217 | struct _Base64Sink | ||
218 | { | ||
219 | SerialSink sink; | ||
220 | |||
221 | SerialSink* out; | ||
222 | |||
223 | guint32 word; | ||
224 | guint32 count; | ||
225 | }; | ||
226 | |||
227 | SerialSink* | ||
228 | serializeio_base64_sink (SerialSink* out) | ||
229 | { | ||
230 | Base64Sink* it = g_new0 (Base64Sink, 1); | ||
231 | SerialSink* sink = (SerialSink*) it; | ||
232 | |||
233 | serializeio_sink_init (sink, | ||
234 | NULL, | ||
235 | base64_sink_close, | ||
236 | base64_sink_write, | ||
237 | base64_sink_free, | ||
238 | base64_sink_quantum); | ||
239 | |||
240 | it->out = out; | ||
241 | |||
242 | return sink; | ||
243 | } | ||
244 | |||
245 | gboolean | ||
246 | base64_sink_write (SerialSink* fsink, const guint8 *ptr, guint32 len) | ||
247 | { | ||
248 | guint32 i; | ||
249 | |||
250 | Base64Sink* sink = (Base64Sink*) fsink; | ||
251 | |||
252 | for (i = 0; i < len; ) | ||
253 | { | ||
254 | if (sink->count == 3) | ||
255 | { | ||
256 | guint8 out[4]; | ||
257 | |||
258 | out[0] = base64_table[(sink->word>>18) & 0x3f]; | ||
259 | out[1] = base64_table[(sink->word>>12) & 0x3f]; | ||
260 | out[2] = base64_table[(sink->word>> 6) & 0x3f]; | ||
261 | out[3] = base64_table[(sink->word ) & 0x3f]; | ||
262 | |||
263 | #if 0 | ||
264 | g_print ("%02x %02x %02x -> %c%c%c%c (3)\n", | ||
265 | (sink->word>>16) & 0xff, | ||
266 | (sink->word>>8) & 0xff, | ||
267 | (sink->word>>0) & 0xff, | ||
268 | out[0], | ||
269 | out[1], | ||
270 | out[2], | ||
271 | out[3]); | ||
272 | #endif | ||
273 | |||
274 | if (! sink->out->sink_write (sink->out, out, 4)) | ||
275 | return FALSE; | ||
276 | |||
277 | sink->count = 0; | ||
278 | sink->word = 0; | ||
279 | } | ||
280 | |||
281 | while (sink->count < 3 && i < len) | ||
282 | sink->word |= ptr[i++] << (8*(2-(sink->count++))); | ||
283 | } | ||
284 | |||
285 | return TRUE; | ||
286 | } | ||
287 | |||
288 | gboolean | ||
289 | base64_sink_close (SerialSink* fsink) | ||
290 | { | ||
291 | Base64Sink* sink = (Base64Sink*) fsink; | ||
292 | |||
293 | if (sink->count == 3) | ||
294 | { | ||
295 | guint8 out[4]; | ||
296 | |||
297 | out[0] = base64_table[(sink->word>>18) & 0x3f]; | ||
298 | out[1] = base64_table[(sink->word>>12) & 0x3f]; | ||
299 | out[2] = base64_table[(sink->word>> 6) & 0x3f]; | ||
300 | out[3] = base64_table[(sink->word ) & 0x3f]; | ||
301 | |||
302 | #if 0 | ||
303 | g_print ("%02x %02x %02x -> %c%c%c%c (3)\n", | ||
304 | (sink->word>>16) & 0xff, | ||
305 | (sink->word>>8) & 0xff, | ||
306 | (sink->word>>0) & 0xff, | ||
307 | out[0], | ||
308 | out[1], | ||
309 | out[2], | ||
310 | out[3]); | ||
311 | #endif | ||
312 | |||
313 | if (! sink->out->sink_write (sink->out, out, 4)) | ||
314 | return FALSE; | ||
315 | |||
316 | sink->count = 0; | ||
317 | sink->word = 0; | ||
318 | } | ||
319 | |||
320 | if (sink->count > 0) | ||
321 | { | ||
322 | guint8 out[4]; | ||
323 | |||
324 | out[0] = base64_table[(sink->word>>18) & 0x3f]; | ||
325 | out[1] = base64_table[(sink->word>>12) & 0x3f]; | ||
326 | out[2] = (sink->count > 1) ? base64_table[(sink->word>>6) & 0x3f] : '='; | ||
327 | out[3] = '='; | ||
328 | |||
329 | #if 0 | ||
330 | g_print ("%02x %02x %02x -> %c%c%c%c (%d)\n", | ||
331 | (sink->word>>16) & 0xff, | ||
332 | (sink->word>>8) & 0xff, | ||
333 | (sink->word>>0) & 0xff, | ||
334 | out[0], | ||
335 | out[1], | ||
336 | out[2], | ||
337 | out[3], | ||
338 | sink->count); | ||
339 | #endif | ||
340 | |||
341 | if (! sink->out->sink_write (sink->out, out, 4)) | ||
342 | return FALSE; | ||
343 | |||
344 | sink->count = 0; | ||
345 | sink->word = 0; | ||
346 | } | ||
347 | |||
348 | return sink->out->sink_close (sink->out); | ||
349 | } | ||
350 | |||
351 | |||
352 | void | ||
353 | base64_sink_free (SerialSink* fsink) | ||
354 | { | ||
355 | Base64Sink* sink = (Base64Sink*) fsink; | ||
356 | |||
357 | sink->out->sink_free (sink->out); | ||
358 | |||
359 | g_free (sink); | ||
360 | } | ||
361 | |||
362 | gboolean | ||
363 | base64_sink_quantum (SerialSink* fsink) | ||
364 | { | ||
365 | Base64Sink* sink = (Base64Sink*) fsink; | ||
366 | |||
367 | if (sink->out->sink_quantum) | ||
368 | return sink->out->sink_quantum (sink->out); | ||
369 | |||
370 | return TRUE; | ||
371 | } | ||
372 | |||
373 | /* Base64 source | ||
374 | */ | ||
375 | |||
376 | typedef struct _Base64Source Base64Source; | ||
377 | |||
378 | struct _Base64Source { | ||
379 | SerialSource source; | ||
380 | |||
381 | SerialSource *in; | ||
382 | |||
383 | guint32 avail; | ||
384 | guint32 count; | ||
385 | gboolean found_end; | ||
386 | gint found_end_at; | ||
387 | guint8 buf[3]; | ||
388 | }; | ||
389 | |||
390 | static gboolean base64_source_close (SerialSource* source); | ||
391 | static gboolean base64_source_read (SerialSource* source, guint8 *ptr, guint32 len); | ||
392 | static void base64_source_free (SerialSource* source); | ||
393 | |||
394 | SerialSource* | ||
395 | serializeio_base64_source (SerialSource* in0) | ||
396 | { | ||
397 | Base64Source* it = g_new0 (Base64Source, 1); | ||
398 | SerialSource* source = (SerialSource*) it; | ||
399 | |||
400 | serializeio_source_init (source, | ||
401 | NULL, | ||
402 | base64_source_close, | ||
403 | base64_source_read, | ||
404 | base64_source_free, | ||
405 | NULL, | ||
406 | NULL); | ||
407 | |||
408 | it->in = in0; | ||
409 | |||
410 | return source; | ||
411 | } | ||
412 | |||
413 | gboolean | ||
414 | base64_source_close (SerialSource* fsource) | ||
415 | { | ||
416 | Base64Source* source = (Base64Source*) fsource; | ||
417 | |||
418 | if (! source->in->source_close (source->in)) | ||
419 | return FALSE; | ||
420 | |||
421 | return TRUE; | ||
422 | } | ||
423 | |||
424 | gboolean | ||
425 | base64_source_read (SerialSource* fsource, guint8 *ptr, guint32 len) | ||
426 | { | ||
427 | guint32 pos; | ||
428 | Base64Source* source = (Base64Source*) fsource; | ||
429 | |||
430 | init_inverse_table (); | ||
431 | |||
432 | for (pos = 0; pos < len; ) | ||
433 | { | ||
434 | if (source->count == 0) | ||
435 | { | ||
436 | guint8 buf[4]; | ||
437 | guint32 i, word = 0, junk; | ||
438 | |||
439 | if (source->found_end) | ||
440 | { | ||
441 | edsio_generate_void_event (EC_EdsioInvalidBase64Encoding); | ||
442 | return FALSE; | ||
443 | } | ||
444 | |||
445 | if (! source->in->source_read (source->in, buf, 4)) | ||
446 | return FALSE; | ||
447 | |||
448 | for (i = 0; i < 4; i += 1) | ||
449 | { | ||
450 | gint x = buf[i]; | ||
451 | |||
452 | if (x > 127 || base64_inverse_table[x] < 0) | ||
453 | { | ||
454 | edsio_generate_void_event (EC_EdsioInvalidBase64Encoding); | ||
455 | return FALSE; | ||
456 | } | ||
457 | |||
458 | if (x == '=') | ||
459 | { | ||
460 | if (! source->found_end) | ||
461 | source->found_end_at = i; | ||
462 | |||
463 | source->found_end = TRUE; | ||
464 | } | ||
465 | else | ||
466 | { | ||
467 | if (source->found_end) | ||
468 | { | ||
469 | edsio_generate_void_event (EC_EdsioInvalidBase64Encoding); | ||
470 | return FALSE; | ||
471 | } | ||
472 | |||
473 | word |= base64_inverse_table[x] << (6*(3-i)); | ||
474 | } | ||
475 | } | ||
476 | |||
477 | if (source->found_end) | ||
478 | { | ||
479 | if (source->found_end_at == 2) | ||
480 | junk = 2; | ||
481 | else if (source->found_end_at == 3) | ||
482 | junk = 1; | ||
483 | else | ||
484 | { | ||
485 | edsio_generate_void_event (EC_EdsioInvalidBase64Encoding); | ||
486 | return FALSE; | ||
487 | } | ||
488 | } | ||
489 | else | ||
490 | junk = 0; | ||
491 | |||
492 | source->avail = source->count = 3 - junk; | ||
493 | |||
494 | source->buf[0] = (word >> 16) & 0xff; | ||
495 | source->buf[1] = (word >> 8) & 0xff; | ||
496 | source->buf[2] = (word >> 0) & 0xff; | ||
497 | |||
498 | #if 0 | ||
499 | g_print ("%c%c%c%c -> %02x %02x %02x (%d)\n", | ||
500 | buf[0], | ||
501 | buf[1], | ||
502 | buf[2], | ||
503 | buf[3], | ||
504 | (word>>16) & 0xff, | ||
505 | (word>>8) & 0xff, | ||
506 | (word>>0) & 0xff, | ||
507 | 3-junk); | ||
508 | #endif | ||
509 | } | ||
510 | |||
511 | ptr[pos++] = source->buf[source->avail-(source->count--)]; | ||
512 | } | ||
513 | |||
514 | return TRUE; | ||
515 | } | ||
516 | |||
517 | void | ||
518 | base64_source_free (SerialSource* fsource) | ||
519 | { | ||
520 | Base64Source* source = (Base64Source*) fsource; | ||
521 | |||
522 | source->in->source_free (source->in); | ||
523 | |||
524 | g_free (source); | ||
525 | } | ||