correctly handle filter file loading error, small tweak
[mkp224o.git] / base64_from.c
blob3f967488c82a6402a0caecb4413c0a8b7e992291
1 #include <stddef.h>
2 #include <stdint.h>
3 #include "types.h"
4 #include "base64.h"
6 static const u8 base64f[256] = {
7 //00 01 02 03 04 05 06 07
8 //08 09 0A 0B 0C 0D 0E 0F
9 // 0x00..0x3F
10 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x00
11 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x08
12 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x10
13 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x18
14 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x20
15 0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xFF, 0xFF, 0x3F, // 0x28
16 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, // 0x30
17 0x3C, 0x3D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x38
18 // 0x40..0x7F
19 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // 0x40
20 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, // 0x48
21 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, // 0x50
22 0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x58
23 0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, // 0x60
24 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, // 0x68
25 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, // 0x70
26 0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x78
27 // 0x80..0xBF
28 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
29 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
30 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
31 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
32 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
33 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
34 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
35 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
36 // 0xC0..0xFF
37 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
38 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
39 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
40 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
41 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
42 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
43 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
44 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
47 size_t base64_from(u8 *dst,const char *src,size_t srclen)
49 if (srclen % 4) {
50 return -1;
51 } else if (!srclen) {
52 return 0;
55 size_t dstlen = BASE64_FROM_LEN(srclen);
56 dstlen -= (src[srclen - 1] == '=');
57 dstlen -= (src[srclen - 2] == '=');
59 for (size_t i = 0, j = 0; i < srclen;) {
60 u32 sixbits[4];
62 sixbits[0] = base64f[(unsigned char)src[i++]];
63 sixbits[1] = base64f[(unsigned char)src[i++]];
64 sixbits[2] = (src[i] == '=' ? (0 & i++) : base64f[(unsigned char)src[i++]]);
65 sixbits[3] = (src[i] == '=' ? (0 & i++) : base64f[(unsigned char)src[i++]]);
67 u32 threebytes = 0
68 | (sixbits[0] << (3 * 6))
69 | (sixbits[1] << (2 * 6))
70 | (sixbits[2] << (1 * 6))
71 | (sixbits[3] << (0 * 6));
73 if (j < dstlen) dst[j++] = (threebytes >> (2 * 8));
74 if (j < dstlen) dst[j++] = (threebytes >> (1 * 8)) & 0xff;
75 if (j < dstlen) dst[j++] = (threebytes >> (0 * 8)) & 0xff;
77 return dstlen;
80 int base64_valid(const char *src,size_t *count)
82 const char *p;
84 for (p = src;base64f[(u8)*p] != 0xFF;++p)
87 for (;((size_t) (p - src)) % 4 != 0 && *p == '=';++p)
90 if (count)
91 *count = (size_t) (p - src);
92 return !*p && ((size_t) (p - src)) % 4 == 0;