1 static inline void
enc_loop_generic_32_inner(const uint8_t ** s,uint8_t ** o)2 enc_loop_generic_32_inner (const uint8_t **s, uint8_t **o)
3 {
4 uint32_t src;
5
6 // Load input:
7 memcpy(&src, *s, sizeof (src));
8
9 // Reorder to 32-bit big-endian, if not already in that format. The
10 // workset must be in big-endian, otherwise the shifted bits do not
11 // carry over properly among adjacent bytes:
12 src = BASE64_HTOBE32(src);
13
14 // Two indices for the 12-bit lookup table:
15 const size_t index0 = (src >> 20) & 0xFFFU;
16 const size_t index1 = (src >> 8) & 0xFFFU;
17
18 // Table lookup and store:
19 memcpy(*o + 0, base64_table_enc_12bit + index0, 2);
20 memcpy(*o + 2, base64_table_enc_12bit + index1, 2);
21
22 *s += 3;
23 *o += 4;
24 }
25
26 static inline void
enc_loop_generic_32(const uint8_t ** s,size_t * slen,uint8_t ** o,size_t * olen)27 enc_loop_generic_32 (const uint8_t **s, size_t *slen, uint8_t **o, size_t *olen)
28 {
29 if (*slen < 4) {
30 return;
31 }
32
33 // Process blocks of 3 bytes at a time. Because blocks are loaded 4
34 // bytes at a time, ensure that there will be at least one remaining
35 // byte after the last round, so that the final read will not pass
36 // beyond the bounds of the input buffer:
37 size_t rounds = (*slen - 1) / 3;
38
39 *slen -= rounds * 3; // 3 bytes consumed per round
40 *olen += rounds * 4; // 4 bytes produced per round
41
42 do {
43 if (rounds >= 8) {
44 enc_loop_generic_32_inner(s, o);
45 enc_loop_generic_32_inner(s, o);
46 enc_loop_generic_32_inner(s, o);
47 enc_loop_generic_32_inner(s, o);
48 enc_loop_generic_32_inner(s, o);
49 enc_loop_generic_32_inner(s, o);
50 enc_loop_generic_32_inner(s, o);
51 enc_loop_generic_32_inner(s, o);
52 rounds -= 8;
53 continue;
54 }
55 if (rounds >= 4) {
56 enc_loop_generic_32_inner(s, o);
57 enc_loop_generic_32_inner(s, o);
58 enc_loop_generic_32_inner(s, o);
59 enc_loop_generic_32_inner(s, o);
60 rounds -= 4;
61 continue;
62 }
63 if (rounds >= 2) {
64 enc_loop_generic_32_inner(s, o);
65 enc_loop_generic_32_inner(s, o);
66 rounds -= 2;
67 continue;
68 }
69 enc_loop_generic_32_inner(s, o);
70 break;
71
72 } while (rounds > 0);
73 }
74