summaryrefslogtreecommitdiff
path: root/xs_encdec.h
diff options
context:
space:
mode:
Diffstat (limited to 'xs_encdec.h')
-rw-r--r--xs_encdec.h155
1 files changed, 0 insertions, 155 deletions
diff --git a/xs_encdec.h b/xs_encdec.h
deleted file mode 100644
index 14cb36e..0000000
--- a/xs_encdec.h
+++ /dev/null
@@ -1,155 +0,0 @@
1/* copyright (c) 2022 - 2023 grunfink / MIT license */
2
3#ifndef _XS_ENCDEC_H
4
5#define _XS_ENCDEC_H
6
7 xs_str *xs_base64_enc(const xs_val *data, int sz);
8 xs_val *xs_base64_dec(const xs_str *data, int *size);
9 int xs_is_base64(const char *str);
10
11
12#ifdef XS_IMPLEMENTATION
13
14/** base64 */
15
16static char *xs_b64_tbl = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
17 "abcdefghijklmnopqrstuvwxyz"
18 "0123456789+/=";
19
20xs_str *xs_base64_enc_tbl(const xs_val *data, int sz, const char *b64_tbl)
21/* encodes data to base64 using a table */
22{
23 xs_str *s;
24 unsigned char *p;
25 char *i;
26 int bsz, n;
27
28 bsz = ((sz + 3 - 1) / 3) * 4;
29 i = s = xs_realloc(NULL, _xs_blk_size(bsz + 1));
30 p = (unsigned char *)data;
31
32 for (n = 0; n < sz; n += 3) {
33 int l = sz - n;
34
35 if (l == 1) {
36 *i++ = b64_tbl[(p[n] >> 2) & 0x3f];
37 *i++ = b64_tbl[(p[n] << 4) & 0x3f];
38 *i++ = '=';
39 *i++ = '=';
40 }
41 else
42 if (l == 2) {
43 *i++ = b64_tbl[(p[n] >> 2) & 0x3f];
44 *i++ = b64_tbl[(p[n] << 4 | p[n + 1] >> 4) & 0x3f];
45 *i++ = b64_tbl[(p[n + 1] << 2) & 0x3f];
46 *i++ = '=';
47 }
48 else {
49 *i++ = b64_tbl[(p[n] >> 2) & 0x3f];
50 *i++ = b64_tbl[(p[n] << 4 | p[n + 1] >> 4) & 0x3f];
51 *i++ = b64_tbl[(p[n + 1] << 2 | p[n + 2] >> 6) & 0x3f];
52 *i++ = b64_tbl[(p[n + 2]) & 0x3f];
53 }
54 }
55
56 *i = '\0';
57
58 return s;
59}
60
61
62xs_str *xs_base64_enc(const xs_val *data, int sz)
63/* encodes data to base64 */
64{
65 return xs_base64_enc_tbl(data, sz, xs_b64_tbl);
66}
67
68
69xs_val *xs_base64_dec_tbl(const xs_str *data, int *size, const char *b64_tbl)
70/* decodes data from base64 using a table */
71{
72 xs_val *s = NULL;
73 int sz = 0;
74 char *p;
75
76 p = (char *)data;
77
78 /* size of data must be a multiple of 4 */
79 if (strlen(p) % 4)
80 return NULL;
81
82 for (p = (char *)data; *p; p += 4) {
83 int cs[4];
84 int n;
85 unsigned char tmp[3];
86
87 for (n = 0; n < 4; n++) {
88 char *ss = strchr(b64_tbl, p[n]);
89
90 if (ss == NULL) {
91 /* not a base64 char */
92 return xs_free(s);
93 }
94
95 cs[n] = ss - b64_tbl;
96 }
97
98 n = 0;
99
100 /* first byte */
101 tmp[n++] = cs[0] << 2 | ((cs[1] >> 4) & 0x0f);
102
103 /* second byte */
104 if (cs[2] != 64)
105 tmp[n++] = cs[1] << 4 | ((cs[2] >> 2) & 0x3f);
106
107 /* third byte */
108 if (cs[3] != 64)
109 tmp[n++] = cs[2] << 6 | (cs[3] & 0x3f);
110
111 /* must be done manually because data can be pure binary */
112 s = xs_realloc(s, _xs_blk_size(sz + n));
113 memcpy(s + sz, tmp, n);
114 sz += n;
115 }
116
117 /* asciiz it to use it as a string */
118 s = xs_realloc(s, _xs_blk_size(sz + 1));
119 s[sz] = '\0';
120
121 *size = sz;
122
123 return s;
124}
125
126
127xs_val *xs_base64_dec(const xs_str *data, int *size)
128/* decodes data from base64 */
129{
130 return xs_base64_dec_tbl(data, size, xs_b64_tbl);
131}
132
133
134int xs_is_base64_tbl(const char *str, const char *b64_tbl)
135/* returns 1 if str is a base64 string, with table */
136{
137 while (*str) {
138 if (strchr(b64_tbl, *str++) == NULL)
139 return 0;
140 }
141
142 return 1;
143}
144
145
146int xs_is_base64(const char *str)
147/* returns 1 if str is a base64 string */
148{
149 return xs_is_base64_tbl(str, xs_b64_tbl);
150}
151
152
153#endif /* XS_IMPLEMENTATION */
154
155#endif /* _XS_ENCDEC_H */