summaryrefslogtreecommitdiff
path: root/xdelta1/libedsio/base64.c
diff options
context:
space:
mode:
Diffstat (limited to 'xdelta1/libedsio/base64.c')
-rw-r--r--xdelta1/libedsio/base64.c525
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
15static 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
23static gint16 base64_inverse_table[128];
24
25static void
26init_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
40GByteArray*
41edsio_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
61gboolean
62edsio_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
102GByteArray*
103edsio_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
123gboolean
124edsio_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 */
210typedef struct _Base64Sink Base64Sink;
211
212static gboolean base64_sink_close (SerialSink* sink);
213static gboolean base64_sink_write (SerialSink* sink, const guint8 *ptr, guint32 len);
214static void base64_sink_free (SerialSink* sink);
215static gboolean base64_sink_quantum (SerialSink* sink);
216
217struct _Base64Sink
218{
219 SerialSink sink;
220
221 SerialSink* out;
222
223 guint32 word;
224 guint32 count;
225};
226
227SerialSink*
228serializeio_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
245gboolean
246base64_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
288gboolean
289base64_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
352void
353base64_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
362gboolean
363base64_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
376typedef struct _Base64Source Base64Source;
377
378struct _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
390static gboolean base64_source_close (SerialSource* source);
391static gboolean base64_source_read (SerialSource* source, guint8 *ptr, guint32 len);
392static void base64_source_free (SerialSource* source);
393
394SerialSource*
395serializeio_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
413gboolean
414base64_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
424gboolean
425base64_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
517void
518base64_source_free (SerialSource* fsource)
519{
520 Base64Source* source = (Base64Source*) fsource;
521
522 source->in->source_free (source->in);
523
524 g_free (source);
525}