1 | #include "config.h" |
2 | |
3 | // Function parameters for encoding functions: |
4 | #define BASE64_ENC_PARAMS \ |
5 | ( struct base64_state *state \ |
6 | , const char *src \ |
7 | , size_t srclen \ |
8 | , char *out \ |
9 | , size_t *outlen \ |
10 | ) |
11 | |
12 | // Function parameters for decoding functions: |
13 | #define BASE64_DEC_PARAMS \ |
14 | ( struct base64_state *state \ |
15 | , const char *src \ |
16 | , size_t srclen \ |
17 | , char *out \ |
18 | , size_t *outlen \ |
19 | ) |
20 | |
21 | // Function signature for encoding functions: |
22 | #define BASE64_ENC_FUNCTION(arch) \ |
23 | void \ |
24 | base64_stream_encode_ ## arch \ |
25 | BASE64_ENC_PARAMS |
26 | |
27 | // Function signature for decoding functions: |
28 | #define BASE64_DEC_FUNCTION(arch) \ |
29 | int \ |
30 | base64_stream_decode_ ## arch \ |
31 | BASE64_DEC_PARAMS |
32 | |
33 | // Cast away unused variable, silence compiler: |
34 | #define UNUSED(x) ((void)(x)) |
35 | |
36 | // Stub function when encoder arch unsupported: |
37 | #define BASE64_ENC_STUB \ |
38 | UNUSED(state); \ |
39 | UNUSED(src); \ |
40 | UNUSED(srclen); \ |
41 | UNUSED(out); \ |
42 | \ |
43 | *outlen = 0; |
44 | |
45 | // Stub function when decoder arch unsupported: |
46 | #define BASE64_DEC_STUB \ |
47 | UNUSED(state); \ |
48 | UNUSED(src); \ |
49 | UNUSED(srclen); \ |
50 | UNUSED(out); \ |
51 | UNUSED(outlen); \ |
52 | \ |
53 | return -1; |
54 | |
55 | struct codec |
56 | { |
57 | void (* enc) BASE64_ENC_PARAMS; |
58 | int (* dec) BASE64_DEC_PARAMS; |
59 | }; |
60 | |
61 | // Define machine endianness. This is for GCC: |
62 | #if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) |
63 | # define BASE64_LITTLE_ENDIAN 1 |
64 | #else |
65 | # define BASE64_LITTLE_ENDIAN 0 |
66 | #endif |
67 | |
68 | // This is for Clang: |
69 | #ifdef __LITTLE_ENDIAN__ |
70 | # define BASE64_LITTLE_ENDIAN 1 |
71 | #endif |
72 | |
73 | #ifdef __BIG_ENDIAN__ |
74 | # define BASE64_LITTLE_ENDIAN 0 |
75 | #endif |
76 | |
77 | // Endian conversion functions: |
78 | #if BASE64_LITTLE_ENDIAN |
79 | # ifdef _MSC_VER |
80 | // Microsoft Visual C++: |
81 | # define BASE64_HTOBE32(x) _byteswap_ulong(x) |
82 | # define BASE64_HTOBE64(x) _byteswap_uint64(x) |
83 | # else |
84 | // GCC and Clang: |
85 | # define BASE64_HTOBE32(x) __builtin_bswap32(x) |
86 | # define BASE64_HTOBE64(x) __builtin_bswap64(x) |
87 | # endif |
88 | #else |
89 | // No conversion needed: |
90 | # define BASE64_HTOBE32(x) (x) |
91 | # define BASE64_HTOBE64(x) (x) |
92 | #endif |
93 | |
94 | // Detect word size: |
95 | #ifdef _INTEGRAL_MAX_BITS |
96 | # define BASE64_WORDSIZE _INTEGRAL_MAX_BITS |
97 | #else |
98 | # define BASE64_WORDSIZE __WORDSIZE |
99 | #endif |
100 | |
101 | // End-of-file definitions. |
102 | // Almost end-of-file when waiting for the last '=' character: |
103 | #define BASE64_AEOF 1 |
104 | // End-of-file when stream end has been reached or invalid input provided: |
105 | #define BASE64_EOF 2 |
106 | |
107 | // GCC 7 defaults to issuing a warning for fallthrough in switch statements, |
108 | // unless the fallthrough cases are marked with an attribute. As we use |
109 | // fallthrough deliberately, define an alias for the attribute: |
110 | #if __GNUC__ >= 7 |
111 | # define BASE64_FALLTHROUGH __attribute__((fallthrough)); |
112 | #else |
113 | # define BASE64_FALLTHROUGH |
114 | #endif |
115 | |
116 | extern void codec_choose (struct codec *, int flags); |
117 | |
118 | // These tables are used by all codecs for fallback plain encoding/decoding: |
119 | extern const uint8_t base64_table_enc[]; |
120 | extern const uint8_t base64_table_dec[]; |
121 | |
122 | extern const uint32_t base64_table_dec_d0[]; |
123 | extern const uint32_t base64_table_dec_d1[]; |
124 | extern const uint32_t base64_table_dec_d2[]; |
125 | extern const uint32_t base64_table_dec_d3[]; |
126 | |