Line | Branch | Exec | Source |
---|---|---|---|
1 | #ifndef UTIL_BASE64_H | ||
2 | #define UTIL_BASE64_H | ||
3 | |||
4 | #include <stddef.h> | ||
5 | #include <stdint.h> | ||
6 | #include "macros.h" | ||
7 | |||
8 | extern const uint8_t base64_decode_table[80]; | ||
9 | extern const char base64_encode_table[64]; | ||
10 | |||
11 | enum { | ||
12 | BASE64_PADDING = 1 << 6, // Return value for padding bytes (=) | ||
13 | BASE64_INVALID = 1 << 7, // Return value for invalid bytes ([^A-Za-z0-9+/=]) | ||
14 | }; | ||
15 | |||
16 | // Decodes a single, base64 digit and returns a numerical value between 0-63, | ||
17 | // or one of the special enum values above | ||
18 | 13467 | static inline unsigned int base64_decode(unsigned char c) | |
19 | { | ||
20 | 13467 | c -= '+'; // Lookup table starts at '+' | |
21 |
2/2✓ Branch 0 (2→3) taken 13282 times.
✓ Branch 1 (2→4) taken 185 times.
|
13467 | return base64_decode_table[(c < sizeof(base64_decode_table)) ? c : 1]; |
22 | } | ||
23 | |||
24 | // Like base64_decode(), but implemented in a way that's more amenable to | ||
25 | // constant propagation when `c` is known at compile-time | ||
26 | 256 | static inline unsigned int base64_decode_branchy(unsigned char c) | |
27 | { | ||
28 |
2/2✓ Branch 0 (2→3) taken 26 times.
✓ Branch 1 (2→4) taken 230 times.
|
256 | if (c >= 'A' && c <= 'Z') { |
29 | 26 | return c - 'A'; | |
30 | } | ||
31 |
2/2✓ Branch 0 (4→5) taken 26 times.
✓ Branch 1 (4→6) taken 204 times.
|
230 | if (c >= 'a' && c <= 'z') { |
32 | 26 | return (c - 'a') + 26; | |
33 | } | ||
34 |
2/2✓ Branch 0 (6→7) taken 10 times.
✓ Branch 1 (6→8) taken 194 times.
|
204 | if (c >= '0' && c <= '9') { |
35 | 10 | return (c - '0') + 52; | |
36 | } | ||
37 |
2/2✓ Branch 0 (8→9) taken 193 times.
✓ Branch 1 (8→12) taken 1 times.
|
194 | if (c == '+') { |
38 | return 62; | ||
39 | } | ||
40 |
2/2✓ Branch 0 (9→10) taken 192 times.
✓ Branch 1 (9→12) taken 1 times.
|
193 | if (c == '/') { |
41 | return 63; | ||
42 | } | ||
43 |
2/2✓ Branch 0 (10→11) taken 1 times.
✓ Branch 1 (10→12) taken 191 times.
|
192 | if (c == '=') { |
44 | 1 | return BASE64_PADDING; | |
45 | } | ||
46 | return BASE64_INVALID; | ||
47 | } | ||
48 | |||
49 | size_t base64_encode_block(const char *in, size_t ilen, char *out, size_t olen) NONNULL_ARGS; | ||
50 | void base64_encode_final(const char *in, size_t ilen, char out[4]) NONNULL_ARGS; | ||
51 | |||
52 | #endif | ||
53 |