• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 static inline void
enc_loop_generic_64_inner(const uint8_t ** s,uint8_t ** o)2 enc_loop_generic_64_inner (const uint8_t **s, uint8_t **o)
3 {
4 	uint64_t src;
5 
6 	// Load input:
7 	memcpy(&src, *s, sizeof (src));
8 
9 	// Reorder to 64-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_HTOBE64(src);
13 
14 	// Four indices for the 12-bit lookup table:
15 	const size_t index0 = (src >> 52) & 0xFFFU;
16 	const size_t index1 = (src >> 40) & 0xFFFU;
17 	const size_t index2 = (src >> 28) & 0xFFFU;
18 	const size_t index3 = (src >> 16) & 0xFFFU;
19 
20 	// Table lookup and store:
21 	memcpy(*o + 0, base64_table_enc_12bit + index0, 2);
22 	memcpy(*o + 2, base64_table_enc_12bit + index1, 2);
23 	memcpy(*o + 4, base64_table_enc_12bit + index2, 2);
24 	memcpy(*o + 6, base64_table_enc_12bit + index3, 2);
25 
26 	*s += 6;
27 	*o += 8;
28 }
29 
30 static inline void
enc_loop_generic_64(const uint8_t ** s,size_t * slen,uint8_t ** o,size_t * olen)31 enc_loop_generic_64 (const uint8_t **s, size_t *slen, uint8_t **o, size_t *olen)
32 {
33 	if (*slen < 8) {
34 		return;
35 	}
36 
37 	// Process blocks of 6 bytes at a time. Because blocks are loaded 8
38 	// bytes at a time, ensure that there will be at least 2 remaining
39 	// bytes after the last round, so that the final read will not pass
40 	// beyond the bounds of the input buffer:
41 	size_t rounds = (*slen - 2) / 6;
42 
43 	*slen -= rounds * 6;	// 6 bytes consumed per round
44 	*olen += rounds * 8;	// 8 bytes produced per round
45 
46 	do {
47 		if (rounds >= 8) {
48 			enc_loop_generic_64_inner(s, o);
49 			enc_loop_generic_64_inner(s, o);
50 			enc_loop_generic_64_inner(s, o);
51 			enc_loop_generic_64_inner(s, o);
52 			enc_loop_generic_64_inner(s, o);
53 			enc_loop_generic_64_inner(s, o);
54 			enc_loop_generic_64_inner(s, o);
55 			enc_loop_generic_64_inner(s, o);
56 			rounds -= 8;
57 			continue;
58 		}
59 		if (rounds >= 4) {
60 			enc_loop_generic_64_inner(s, o);
61 			enc_loop_generic_64_inner(s, o);
62 			enc_loop_generic_64_inner(s, o);
63 			enc_loop_generic_64_inner(s, o);
64 			rounds -= 4;
65 			continue;
66 		}
67 		if (rounds >= 2) {
68 			enc_loop_generic_64_inner(s, o);
69 			enc_loop_generic_64_inner(s, o);
70 			rounds -= 2;
71 			continue;
72 		}
73 		enc_loop_generic_64_inner(s, o);
74 		break;
75 
76 	} while (rounds > 0);
77 }
78