• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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