1 :
2 : #define EX_UTILS_NO_FUNCS 1
3 : #include "ex_utils.h"
4 :
5 : #include "base64.h"
6 :
7 : /*
8 : * Translation Table as described in RFC1113
9 : */
10 : static const char b64[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
11 : "abcdefghijklmnopqrstuvwxyz"
12 : "0123456789" "+/";
13 :
14 :
15 : int vstr_x_conv_base64_encode(Vstr_base *dst, size_t dpos,
16 : const Vstr_base *src, size_t spos, size_t slen,
17 : unsigned int flags)
18 1092 : {
19 : unsigned char sbuf[3];
20 : unsigned char dbuf[4];
21 1092 : size_t orig_dpos = dpos;
22 1092 : size_t orig_dlen = dst->len;
23 1092 : unsigned int nonl = 76 / 4;
24 :
25 8724 : while (slen)
26 : {
27 6540 : unsigned int i24 = 0;
28 6540 : unsigned int used = 3;
29 :
30 6540 : if (slen >= 3)
31 5448 : vstr_export_buf(src, spos, used, sbuf, sizeof(sbuf));
32 : else
33 : {
34 1092 : vstr_export_buf(src, spos, slen, sbuf, sizeof(sbuf));
35 1092 : switch (used = slen)
36 : {
37 1092 : case 1: sbuf[1] = 0;
38 1092 : case 2: sbuf[2] = 0;
39 : }
40 : }
41 :
42 6540 : i24 |= sbuf[0]; i24 <<= 8;
43 6540 : i24 |= sbuf[1]; i24 <<= 8;
44 6540 : i24 |= sbuf[2];
45 :
46 : ASSERT(sizeof(b64) == 64);
47 3270 : ASSERT(((i24 & 0x00FC0000) >> 18) < 64);
48 3270 : ASSERT(((i24 & 0x0003F000) >> 12) < 64);
49 3270 : ASSERT(((i24 & 0x00000FC0) >> 6) < 64);
50 3270 : ASSERT(((i24 & 0x0000003F) < 64));
51 :
52 6540 : dbuf[0] = (i24 & 0x00FC0000) >> 18; dbuf[0] = b64[dbuf[0]];
53 6540 : dbuf[1] = (i24 & 0x0003F000) >> 12; dbuf[1] = b64[dbuf[1]];
54 6540 : dbuf[2] = (i24 & 0x00000FC0) >> 6; dbuf[2] = b64[dbuf[2]];
55 6540 : dbuf[3] = (i24 & 0x0000003F); dbuf[3] = b64[dbuf[3]];
56 :
57 6540 : if (used == 3)
58 : {
59 5448 : if (!vstr_add_buf(dst, dpos, dbuf, sizeof(dbuf)))
60 0 : goto failed_add;
61 5448 : dpos += sizeof(dbuf);
62 : }
63 : else
64 : {
65 1092 : unsigned int out_map[3] = {0, 2, 3};
66 :
67 546 : ASSERT(out_map[used] <= sizeof(dbuf));
68 1092 : if (!vstr_add_buf(dst, dpos, dbuf, out_map[used]))
69 0 : goto failed_add;
70 1092 : dpos += out_map[used];
71 :
72 1092 : if (!vstr_add_rep_chr(dst, dpos, '=', 4 - out_map[used]))
73 0 : goto failed_add;
74 1092 : dpos += 4 - out_map[used];
75 : }
76 :
77 6540 : slen -= used; spos += used;
78 :
79 6540 : if (flags && (!--nonl || !slen))
80 : {
81 0 : nonl = 76 / 4;
82 0 : if (!vstr_add_cstr_buf(dst, dpos, "\n"))
83 0 : goto failed_add;
84 0 : ++dpos;
85 : }
86 : }
87 :
88 1092 : return (TRUE);
89 :
90 0 : failed_add:
91 0 : vstr_del(dst, orig_dpos, dst->len - orig_dlen);
92 0 : return (FALSE);
93 : }
94 :
95 : #if 0
96 : int vstr_x_conv_base64_decode(Vstr_base *dst, size_t dpos,
97 : const Vstr_base *src, size_t spos, size_t slen)
98 : {
99 : assert(FALSE);
100 : return (FALSE);
101 : }
102 : #endif
|