Elaztek Developer Hub
Blamite Game Engine - Strings  00431.01.26.25.2126.blamite
A library containing general purpose utilities and classes for use in multiple projects.
base64.hpp
Go to the documentation of this file.
1 #ifndef BASE64_HPP_
2 #define BASE64_HPP_
3 
4 #include <algorithm>
5 #include <array>
6 #include <cassert>
7 #include <cstdint>
8 #include <cstring>
9 #include <stdexcept>
10 #include <string>
11 #include <string_view>
12 
13 #if defined(__cpp_lib_bit_cast)
14 #include <bit> // For std::bit_cast.
15 #endif
16 
17 namespace base64 {
18 
19 namespace detail {
20 
21 #if defined(__cpp_lib_bit_cast)
22 using std::bit_cast;
23 #else
24 template <class To, class From>
25 std::enable_if_t<sizeof(To) == sizeof(From) &&
26  std::is_trivially_copyable_v<From> &&
27  std::is_trivially_copyable_v<To>,
28  To>
29 bit_cast(const From& src) noexcept {
30  static_assert(std::is_trivially_constructible_v<To>,
31  "This implementation additionally requires "
32  "destination type to be trivially constructible");
33 
34  To dst;
35  std::memcpy(&dst, &src, sizeof(To));
36  return dst;
37 }
38 #endif
39 
40 inline constexpr char padding_char{'='};
41 inline constexpr uint32_t bad_char{0x01FFFFFF};
42 
43 #if !defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)
44 #if (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) || \
45  (defined(__BYTE_ORDER) && __BYTE_ORDER == __BIG_ENDIAN) || \
46  (defined(_BYTE_ORDER) && _BYTE_ORDER == _BIG_ENDIAN) || \
47  (defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN) || \
48  (defined(__sun) && defined(__SVR4) && defined(_BIG_ENDIAN)) || \
49  defined(__ARMEB__) || defined(__THUMBEB__) || defined(__AARCH64EB__) || \
50  defined(_MIBSEB) || defined(__MIBSEB) || defined(__MIBSEB__) || \
51  defined(_M_PPC)
52 #define __BIG_ENDIAN__
53 #elif (defined(__BYTE_ORDER__) && \
54  __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || /* gcc */ \
55  (defined(__BYTE_ORDER) && \
56  __BYTE_ORDER == __LITTLE_ENDIAN) /* linux header */ \
57  || (defined(_BYTE_ORDER) && _BYTE_ORDER == _LITTLE_ENDIAN) || \
58  (defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN) /* mingw header */ || \
59  (defined(__sun) && defined(__SVR4) && \
60  defined(_LITTLE_ENDIAN)) || /* solaris */ \
61  defined(__ARMEL__) || \
62  defined(__THUMBEL__) || defined(__AARCH64EL__) || defined(_MIPSEL) || \
63  defined(__MIPSEL) || defined(__MIPSEL__) || defined(_M_IX86) || \
64  defined(_M_X64) || defined(_M_IA64) || /* msvc for intel processors */ \
65  defined(_M_ARM) /* msvc code on arm executes in little endian mode */
66 #define __LITTLE_ENDIAN__
67 #endif
68 #endif
69 
70 #if !defined(__LITTLE_ENDIAN__) & !defined(__BIG_ENDIAN__)
71 #error "UNKNOWN Platform / endianness. Configure endianness explicitly."
72 #endif
73 
74 #if defined(__LITTLE_ENDIAN__)
75 std::array<std::uint32_t, 256> constexpr decode_table_0 = {
76  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
77  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
78  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
79  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
80  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
81  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
82  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
83  0x01ffffff, 0x000000f8, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x000000fc,
84  0x000000d0, 0x000000d4, 0x000000d8, 0x000000dc, 0x000000e0, 0x000000e4,
85  0x000000e8, 0x000000ec, 0x000000f0, 0x000000f4, 0x01ffffff, 0x01ffffff,
86  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000,
87  0x00000004, 0x00000008, 0x0000000c, 0x00000010, 0x00000014, 0x00000018,
88  0x0000001c, 0x00000020, 0x00000024, 0x00000028, 0x0000002c, 0x00000030,
89  0x00000034, 0x00000038, 0x0000003c, 0x00000040, 0x00000044, 0x00000048,
90  0x0000004c, 0x00000050, 0x00000054, 0x00000058, 0x0000005c, 0x00000060,
91  0x00000064, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
92  0x01ffffff, 0x00000068, 0x0000006c, 0x00000070, 0x00000074, 0x00000078,
93  0x0000007c, 0x00000080, 0x00000084, 0x00000088, 0x0000008c, 0x00000090,
94  0x00000094, 0x00000098, 0x0000009c, 0x000000a0, 0x000000a4, 0x000000a8,
95  0x000000ac, 0x000000b0, 0x000000b4, 0x000000b8, 0x000000bc, 0x000000c0,
96  0x000000c4, 0x000000c8, 0x000000cc, 0x01ffffff, 0x01ffffff, 0x01ffffff,
97  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
98  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
99  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
100  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
101  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
102  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
103  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
104  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
105  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
106  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
107  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
108  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
109  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
110  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
111  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
112  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
113  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
114  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
115  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
116  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
117  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
118  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff};
119 
120 std::array<std::uint32_t, 256> constexpr decode_table_1 = {
121  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
122  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
123  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
124  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
125  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
126  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
127  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
128  0x01ffffff, 0x0000e003, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x0000f003,
129  0x00004003, 0x00005003, 0x00006003, 0x00007003, 0x00008003, 0x00009003,
130  0x0000a003, 0x0000b003, 0x0000c003, 0x0000d003, 0x01ffffff, 0x01ffffff,
131  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000,
132  0x00001000, 0x00002000, 0x00003000, 0x00004000, 0x00005000, 0x00006000,
133  0x00007000, 0x00008000, 0x00009000, 0x0000a000, 0x0000b000, 0x0000c000,
134  0x0000d000, 0x0000e000, 0x0000f000, 0x00000001, 0x00001001, 0x00002001,
135  0x00003001, 0x00004001, 0x00005001, 0x00006001, 0x00007001, 0x00008001,
136  0x00009001, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
137  0x01ffffff, 0x0000a001, 0x0000b001, 0x0000c001, 0x0000d001, 0x0000e001,
138  0x0000f001, 0x00000002, 0x00001002, 0x00002002, 0x00003002, 0x00004002,
139  0x00005002, 0x00006002, 0x00007002, 0x00008002, 0x00009002, 0x0000a002,
140  0x0000b002, 0x0000c002, 0x0000d002, 0x0000e002, 0x0000f002, 0x00000003,
141  0x00001003, 0x00002003, 0x00003003, 0x01ffffff, 0x01ffffff, 0x01ffffff,
142  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
143  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
144  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
145  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
146  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
147  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
148  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
149  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
150  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
151  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
152  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
153  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
154  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
155  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
156  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
157  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
158  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
159  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
160  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
161  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
162  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
163  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff};
164 
165 std::array<std::uint32_t, 256> constexpr decode_table_2 = {
166  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
167  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
168  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
169  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
170  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
171  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
172  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
173  0x01ffffff, 0x00800f00, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00c00f00,
174  0x00000d00, 0x00400d00, 0x00800d00, 0x00c00d00, 0x00000e00, 0x00400e00,
175  0x00800e00, 0x00c00e00, 0x00000f00, 0x00400f00, 0x01ffffff, 0x01ffffff,
176  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000,
177  0x00400000, 0x00800000, 0x00c00000, 0x00000100, 0x00400100, 0x00800100,
178  0x00c00100, 0x00000200, 0x00400200, 0x00800200, 0x00c00200, 0x00000300,
179  0x00400300, 0x00800300, 0x00c00300, 0x00000400, 0x00400400, 0x00800400,
180  0x00c00400, 0x00000500, 0x00400500, 0x00800500, 0x00c00500, 0x00000600,
181  0x00400600, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
182  0x01ffffff, 0x00800600, 0x00c00600, 0x00000700, 0x00400700, 0x00800700,
183  0x00c00700, 0x00000800, 0x00400800, 0x00800800, 0x00c00800, 0x00000900,
184  0x00400900, 0x00800900, 0x00c00900, 0x00000a00, 0x00400a00, 0x00800a00,
185  0x00c00a00, 0x00000b00, 0x00400b00, 0x00800b00, 0x00c00b00, 0x00000c00,
186  0x00400c00, 0x00800c00, 0x00c00c00, 0x01ffffff, 0x01ffffff, 0x01ffffff,
187  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
188  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
189  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
190  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
191  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
192  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
193  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
194  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
195  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
196  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
197  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
198  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
199  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
200  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
201  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
202  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
203  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
204  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
205  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
206  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
207  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
208  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff};
209 
210 std::array<std::uint32_t, 256> constexpr decode_table_3 = {
211  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
212  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
213  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
214  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
215  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
216  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
217  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
218  0x01ffffff, 0x003e0000, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x003f0000,
219  0x00340000, 0x00350000, 0x00360000, 0x00370000, 0x00380000, 0x00390000,
220  0x003a0000, 0x003b0000, 0x003c0000, 0x003d0000, 0x01ffffff, 0x01ffffff,
221  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000,
222  0x00010000, 0x00020000, 0x00030000, 0x00040000, 0x00050000, 0x00060000,
223  0x00070000, 0x00080000, 0x00090000, 0x000a0000, 0x000b0000, 0x000c0000,
224  0x000d0000, 0x000e0000, 0x000f0000, 0x00100000, 0x00110000, 0x00120000,
225  0x00130000, 0x00140000, 0x00150000, 0x00160000, 0x00170000, 0x00180000,
226  0x00190000, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
227  0x01ffffff, 0x001a0000, 0x001b0000, 0x001c0000, 0x001d0000, 0x001e0000,
228  0x001f0000, 0x00200000, 0x00210000, 0x00220000, 0x00230000, 0x00240000,
229  0x00250000, 0x00260000, 0x00270000, 0x00280000, 0x00290000, 0x002a0000,
230  0x002b0000, 0x002c0000, 0x002d0000, 0x002e0000, 0x002f0000, 0x00300000,
231  0x00310000, 0x00320000, 0x00330000, 0x01ffffff, 0x01ffffff, 0x01ffffff,
232  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
233  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
234  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
235  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
236  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
237  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
238  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
239  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
240  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
241  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
242  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
243  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
244  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
245  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
246  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
247  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
248  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
249  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
250  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
251  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
252  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
253  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff};
254 
255 // TODO fix decoding tables to avoid the need for different indices in big
256 // endian?
257 inline constexpr size_t decidx0{0};
258 inline constexpr size_t decidx1{1};
259 inline constexpr size_t decidx2{2};
260 
261 #elif defined(__BIG_ENDIAN__)
262 
263 std::array<std::uint32_t, 256> constexpr decode_table_0 = {
264  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
265  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
266  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
267  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
268  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
269  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
270  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
271  0x01ffffff, 0x00f80000, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00fc0000,
272  0x00d00000, 0x00d40000, 0x00d80000, 0x00dc0000, 0x00e00000, 0x00e40000,
273  0x00e80000, 0x00ec0000, 0x00f00000, 0x00f40000, 0x01ffffff, 0x01ffffff,
274  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000,
275  0x00040000, 0x00080000, 0x000c0000, 0x00100000, 0x00140000, 0x00180000,
276  0x001c0000, 0x00200000, 0x00240000, 0x00280000, 0x002c0000, 0x00300000,
277  0x00340000, 0x00380000, 0x003c0000, 0x00400000, 0x00440000, 0x00480000,
278  0x004c0000, 0x00500000, 0x00540000, 0x00580000, 0x005c0000, 0x00600000,
279  0x00640000, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
280  0x01ffffff, 0x00680000, 0x006c0000, 0x00700000, 0x00740000, 0x00780000,
281  0x007c0000, 0x00800000, 0x00840000, 0x00880000, 0x008c0000, 0x00900000,
282  0x00940000, 0x00980000, 0x009c0000, 0x00a00000, 0x00a40000, 0x00a80000,
283  0x00ac0000, 0x00b00000, 0x00b40000, 0x00b80000, 0x00bc0000, 0x00c00000,
284  0x00c40000, 0x00c80000, 0x00cc0000, 0x01ffffff, 0x01ffffff, 0x01ffffff,
285  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
286  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
287  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
288  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
289  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
290  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
291  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
292  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
293  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
294  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
295  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
296  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
297  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
298  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
299  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
300  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
301  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
302  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
303  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
304  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
305  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
306  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff};
307 
308 std::array<std::uint32_t, 256> constexpr decode_table_1 = {
309  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
310  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
311  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
312  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
313  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
314  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
315  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
316  0x01ffffff, 0x0003e000, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x0003f000,
317  0x00034000, 0x00035000, 0x00036000, 0x00037000, 0x00038000, 0x00039000,
318  0x0003a000, 0x0003b000, 0x0003c000, 0x0003d000, 0x01ffffff, 0x01ffffff,
319  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000,
320  0x00001000, 0x00002000, 0x00003000, 0x00004000, 0x00005000, 0x00006000,
321  0x00007000, 0x00008000, 0x00009000, 0x0000a000, 0x0000b000, 0x0000c000,
322  0x0000d000, 0x0000e000, 0x0000f000, 0x00010000, 0x00011000, 0x00012000,
323  0x00013000, 0x00014000, 0x00015000, 0x00016000, 0x00017000, 0x00018000,
324  0x00019000, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
325  0x01ffffff, 0x0001a000, 0x0001b000, 0x0001c000, 0x0001d000, 0x0001e000,
326  0x0001f000, 0x00020000, 0x00021000, 0x00022000, 0x00023000, 0x00024000,
327  0x00025000, 0x00026000, 0x00027000, 0x00028000, 0x00029000, 0x0002a000,
328  0x0002b000, 0x0002c000, 0x0002d000, 0x0002e000, 0x0002f000, 0x00030000,
329  0x00031000, 0x00032000, 0x00033000, 0x01ffffff, 0x01ffffff, 0x01ffffff,
330  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
331  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
332  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
333  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
334  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
335  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
336  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
337  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
338  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
339  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
340  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
341  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
342  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
343  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
344  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
345  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
346  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
347  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
348  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
349  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
350  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
351  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff};
352 
353 std::array<std::uint32_t, 256> constexpr decode_table_2 = {
354  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
355  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
356  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
357  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
358  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
359  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
360  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
361  0x01ffffff, 0x00000f80, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000fc0,
362  0x00000d00, 0x00000d40, 0x00000d80, 0x00000dc0, 0x00000e00, 0x00000e40,
363  0x00000e80, 0x00000ec0, 0x00000f00, 0x00000f40, 0x01ffffff, 0x01ffffff,
364  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000,
365  0x00000040, 0x00000080, 0x000000c0, 0x00000100, 0x00000140, 0x00000180,
366  0x000001c0, 0x00000200, 0x00000240, 0x00000280, 0x000002c0, 0x00000300,
367  0x00000340, 0x00000380, 0x000003c0, 0x00000400, 0x00000440, 0x00000480,
368  0x000004c0, 0x00000500, 0x00000540, 0x00000580, 0x000005c0, 0x00000600,
369  0x00000640, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
370  0x01ffffff, 0x00000680, 0x000006c0, 0x00000700, 0x00000740, 0x00000780,
371  0x000007c0, 0x00000800, 0x00000840, 0x00000880, 0x000008c0, 0x00000900,
372  0x00000940, 0x00000980, 0x000009c0, 0x00000a00, 0x00000a40, 0x00000a80,
373  0x00000ac0, 0x00000b00, 0x00000b40, 0x00000b80, 0x00000bc0, 0x00000c00,
374  0x00000c40, 0x00000c80, 0x00000cc0, 0x01ffffff, 0x01ffffff, 0x01ffffff,
375  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
376  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
377  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
378  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
379  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
380  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
381  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
382  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
383  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
384  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
385  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
386  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
387  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
388  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
389  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
390  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
391  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
392  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
393  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
394  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
395  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
396  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff};
397 
398 std::array<std::uint32_t, 256> constexpr decode_table_3 = {
399  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
400  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
401  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
402  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
403  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
404  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
405  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
406  0x01ffffff, 0x0000003e, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x0000003f,
407  0x00000034, 0x00000035, 0x00000036, 0x00000037, 0x00000038, 0x00000039,
408  0x0000003a, 0x0000003b, 0x0000003c, 0x0000003d, 0x01ffffff, 0x01ffffff,
409  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000,
410  0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000006,
411  0x00000007, 0x00000008, 0x00000009, 0x0000000a, 0x0000000b, 0x0000000c,
412  0x0000000d, 0x0000000e, 0x0000000f, 0x00000010, 0x00000011, 0x00000012,
413  0x00000013, 0x00000014, 0x00000015, 0x00000016, 0x00000017, 0x00000018,
414  0x00000019, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
415  0x01ffffff, 0x0000001a, 0x0000001b, 0x0000001c, 0x0000001d, 0x0000001e,
416  0x0000001f, 0x00000020, 0x00000021, 0x00000022, 0x00000023, 0x00000024,
417  0x00000025, 0x00000026, 0x00000027, 0x00000028, 0x00000029, 0x0000002a,
418  0x0000002b, 0x0000002c, 0x0000002d, 0x0000002e, 0x0000002f, 0x00000030,
419  0x00000031, 0x00000032, 0x00000033, 0x01ffffff, 0x01ffffff, 0x01ffffff,
420  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
421  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
422  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
423  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
424  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
425  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
426  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
427  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
428  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
429  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
430  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
431  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
432  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
433  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
434  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
435  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
436  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
437  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
438  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
439  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
440  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
441  0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff};
442 
443 // TODO fix decoding tables to avoid the need for different indices in big
444 // endian?
445 inline constexpr size_t decidx0{1};
446 inline constexpr size_t decidx1{2};
447 inline constexpr size_t decidx2{3};
448 
449 #endif
450 
451 std::array<char, 256> constexpr encode_table_0 = {
452  'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'C', 'C', 'C', 'C', 'D', 'D', 'D',
453  'D', 'E', 'E', 'E', 'E', 'F', 'F', 'F', 'F', 'G', 'G', 'G', 'G', 'H', 'H',
454  'H', 'H', 'I', 'I', 'I', 'I', 'J', 'J', 'J', 'J', 'K', 'K', 'K', 'K', 'L',
455  'L', 'L', 'L', 'M', 'M', 'M', 'M', 'N', 'N', 'N', 'N', 'O', 'O', 'O', 'O',
456  'P', 'P', 'P', 'P', 'Q', 'Q', 'Q', 'Q', 'R', 'R', 'R', 'R', 'S', 'S', 'S',
457  'S', 'T', 'T', 'T', 'T', 'U', 'U', 'U', 'U', 'V', 'V', 'V', 'V', 'W', 'W',
458  'W', 'W', 'X', 'X', 'X', 'X', 'Y', 'Y', 'Y', 'Y', 'Z', 'Z', 'Z', 'Z', 'a',
459  'a', 'a', 'a', 'b', 'b', 'b', 'b', 'c', 'c', 'c', 'c', 'd', 'd', 'd', 'd',
460  'e', 'e', 'e', 'e', 'f', 'f', 'f', 'f', 'g', 'g', 'g', 'g', 'h', 'h', 'h',
461  'h', 'i', 'i', 'i', 'i', 'j', 'j', 'j', 'j', 'k', 'k', 'k', 'k', 'l', 'l',
462  'l', 'l', 'm', 'm', 'm', 'm', 'n', 'n', 'n', 'n', 'o', 'o', 'o', 'o', 'p',
463  'p', 'p', 'p', 'q', 'q', 'q', 'q', 'r', 'r', 'r', 'r', 's', 's', 's', 's',
464  't', 't', 't', 't', 'u', 'u', 'u', 'u', 'v', 'v', 'v', 'v', 'w', 'w', 'w',
465  'w', 'x', 'x', 'x', 'x', 'y', 'y', 'y', 'y', 'z', 'z', 'z', 'z', '0', '0',
466  '0', '0', '1', '1', '1', '1', '2', '2', '2', '2', '3', '3', '3', '3', '4',
467  '4', '4', '4', '5', '5', '5', '5', '6', '6', '6', '6', '7', '7', '7', '7',
468  '8', '8', '8', '8', '9', '9', '9', '9', '+', '+', '+', '+', '/', '/', '/',
469  '/'};
470 
471 std::array<char, 256> constexpr encode_table_1 = {
472  'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
473  'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
474  'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
475  't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
476  '8', '9', '+', '/', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',
477  'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
478  'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
479  'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3',
480  '4', '5', '6', '7', '8', '9', '+', '/', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
481  'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
482  'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k',
483  'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
484  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', 'A', 'B', 'C',
485  'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
486  'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
487  'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
488  'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+',
489  '/'};
490 
491 } // namespace detail
492 
493 template <class OutputBuffer, class InputIterator>
494 inline OutputBuffer encode_into(InputIterator begin, InputIterator end) {
495  typedef std::decay_t<decltype(*begin)> input_value_type;
496  static_assert(std::is_same_v<input_value_type, char> ||
497  std::is_same_v<input_value_type, signed char> ||
498  std::is_same_v<input_value_type, unsigned char> ||
499  std::is_same_v<input_value_type, std::byte>);
500  typedef typename OutputBuffer::value_type output_value_type;
501  static_assert(std::is_same_v<output_value_type, char> ||
502  std::is_same_v<output_value_type, signed char> ||
503  std::is_same_v<output_value_type, unsigned char> ||
504  std::is_same_v<output_value_type, std::byte>);
505  const size_t binarytextsize = end - begin;
506  const size_t encodedsize = (binarytextsize / 3 + (binarytextsize % 3 > 0))
507  << 2;
508  OutputBuffer encoded(encodedsize, detail::padding_char);
509 
510  const uint8_t* bytes = reinterpret_cast<const uint8_t*>(&*begin);
511  char* currEncoding = reinterpret_cast<char*>(&encoded[0]);
512 
513  for (size_t i = binarytextsize / 3; i; --i) {
514  const uint8_t t1 = *bytes++;
515  const uint8_t t2 = *bytes++;
516  const uint8_t t3 = *bytes++;
517  *currEncoding++ = detail::encode_table_0[t1];
518  *currEncoding++ =
519  detail::encode_table_1[((t1 & 0x03) << 4) | ((t2 >> 4) & 0x0F)];
520  *currEncoding++ =
521  detail::encode_table_1[((t2 & 0x0F) << 2) | ((t3 >> 6) & 0x03)];
522  *currEncoding++ = detail::encode_table_1[t3];
523  }
524 
525  switch (binarytextsize % 3) {
526  case 0: {
527  break;
528  }
529  case 1: {
530  const uint8_t t1 = bytes[0];
531  *currEncoding++ = detail::encode_table_0[t1];
532  *currEncoding++ = detail::encode_table_1[(t1 & 0x03) << 4];
533  // *currEncoding++ = detail::padding_char;
534  // *currEncoding++ = detail::padding_char;
535  break;
536  }
537  case 2: {
538  const uint8_t t1 = bytes[0];
539  const uint8_t t2 = bytes[1];
540  *currEncoding++ = detail::encode_table_0[t1];
541  *currEncoding++ =
542  detail::encode_table_1[((t1 & 0x03) << 4) | ((t2 >> 4) & 0x0F)];
543  *currEncoding++ = detail::encode_table_1[(t2 & 0x0F) << 2];
544  // *currEncoding++ = detail::padding_char;
545  break;
546  }
547  default: {
548  throw std::runtime_error{"Invalid base64 encoded data"};
549  }
550  }
551 
552  return encoded;
553 }
554 
555 template <class OutputBuffer>
556 inline OutputBuffer encode_into(std::string_view data) {
557  return encode_into<OutputBuffer>(std::begin(data), std::end(data));
558 }
559 
560 inline std::string to_base64(std::string_view data) {
561  return encode_into<std::string>(std::begin(data), std::end(data));
562 }
563 
564 template <class OutputBuffer>
565 inline OutputBuffer decode_into(std::string_view base64Text) {
566  typedef typename OutputBuffer::value_type output_value_type;
567  static_assert(std::is_same_v<output_value_type, char> ||
568  std::is_same_v<output_value_type, signed char> ||
569  std::is_same_v<output_value_type, unsigned char> ||
570  std::is_same_v<output_value_type, std::byte>);
571  if (base64Text.empty()) {
572  return OutputBuffer();
573  }
574 
575  if ((base64Text.size() & 3) != 0) {
576  throw std::runtime_error{
577  "Invalid base64 encoded data - Size not divisible by 4"};
578  }
579 
580  const size_t numPadding =
581  std::count(base64Text.rbegin(), base64Text.rbegin() + 4, '=');
582  if (numPadding > 2) {
583  throw std::runtime_error{
584  "Invalid base64 encoded data - Found more than 2 padding signs"};
585  }
586 
587  const size_t decodedsize = (base64Text.size() * 3 >> 2) - numPadding;
588  OutputBuffer decoded(decodedsize, '.');
589 
590  const uint8_t* bytes = reinterpret_cast<const uint8_t*>(&base64Text[0]);
591  char* currDecoding = reinterpret_cast<char*>(&decoded[0]);
592 
593  for (size_t i = (base64Text.size() >> 2) - (numPadding != 0); i; --i) {
594  const uint8_t t1 = *bytes++;
595  const uint8_t t2 = *bytes++;
596  const uint8_t t3 = *bytes++;
597  const uint8_t t4 = *bytes++;
598 
599  const uint32_t d1 = detail::decode_table_0[t1];
600  const uint32_t d2 = detail::decode_table_1[t2];
601  const uint32_t d3 = detail::decode_table_2[t3];
602  const uint32_t d4 = detail::decode_table_3[t4];
603 
604  const uint32_t temp = d1 | d2 | d3 | d4;
605 
606  if (temp >= detail::bad_char) {
607  throw std::runtime_error{
608  "Invalid base64 encoded data - Invalid character"};
609  }
610 
611  // Use bit_cast instead of union and type punning to avoid
612  // undefined behaviour risk:
613  // https://en.wikipedia.org/wiki/Type_punning#Use_of_union
614  const std::array<char, 4> tempBytes =
615  detail::bit_cast<std::array<char, 4>, uint32_t>(temp);
616 
617  *currDecoding++ = tempBytes[detail::decidx0];
618  *currDecoding++ = tempBytes[detail::decidx1];
619  *currDecoding++ = tempBytes[detail::decidx2];
620  }
621 
622  switch (numPadding) {
623  case 0: {
624  break;
625  }
626  case 1: {
627  const uint8_t t1 = *bytes++;
628  const uint8_t t2 = *bytes++;
629  const uint8_t t3 = *bytes++;
630 
631  const uint32_t d1 = detail::decode_table_0[t1];
632  const uint32_t d2 = detail::decode_table_1[t2];
633  const uint32_t d3 = detail::decode_table_2[t3];
634 
635  const uint32_t temp = d1 | d2 | d3;
636 
637  if (temp >= detail::bad_char) {
638  throw std::runtime_error{
639  "Invalid base64 encoded data - Invalid character"};
640  }
641 
642  // Use bit_cast instead of union and type punning to avoid
643  // undefined behaviour risk:
644  // https://en.wikipedia.org/wiki/Type_punning#Use_of_union
645  const std::array<char, 4> tempBytes =
646  detail::bit_cast<std::array<char, 4>, uint32_t>(temp);
647  *currDecoding++ = tempBytes[detail::decidx0];
648  *currDecoding++ = tempBytes[detail::decidx1];
649  break;
650  }
651  case 2: {
652  const uint8_t t1 = *bytes++;
653  const uint8_t t2 = *bytes++;
654 
655  const uint32_t d1 = detail::decode_table_0[t1];
656  const uint32_t d2 = detail::decode_table_1[t2];
657 
658  const uint32_t temp = d1 | d2;
659 
660  if (temp >= detail::bad_char) {
661  throw std::runtime_error{
662  "Invalid base64 encoded data - Invalid character"};
663  }
664 
665  const std::array<char, 4> tempBytes =
666  detail::bit_cast<std::array<char, 4>, uint32_t>(temp);
667  *currDecoding++ = tempBytes[detail::decidx0];
668  break;
669  }
670  default: {
671  throw std::runtime_error{
672  "Invalid base64 encoded data - Invalid padding number"};
673  }
674  }
675 
676  return decoded;
677 }
678 
679 template <class OutputBuffer, class InputIterator>
680 inline OutputBuffer decode_into(InputIterator begin, InputIterator end) {
681  typedef std::decay_t<decltype(*begin)> input_value_type;
682  static_assert(std::is_same_v<input_value_type, char> ||
683  std::is_same_v<input_value_type, signed char> ||
684  std::is_same_v<input_value_type, unsigned char> ||
685  std::is_same_v<input_value_type, std::byte>);
686  std::string_view data(reinterpret_cast<const char*>(&*begin), end - begin);
687  return decode_into<OutputBuffer>(data);
688 }
689 
690 inline std::string from_base64(std::string_view data) {
691  return decode_into<std::string>(data);
692 }
693 
694 } // namespace base64
695 
696 #endif // BASE64_HPP_
base64::detail::encode_table_1
constexpr std::array< char, 256 > encode_table_1
Definition: base64.hpp:471
base64::decode_into
OutputBuffer decode_into(std::string_view base64Text)
Definition: base64.hpp:565
base64::to_base64
std::string to_base64(std::string_view data)
Definition: base64.hpp:560
base64::detail::bit_cast
std::enable_if_t< sizeof(To)==sizeof(From) &&std::is_trivially_copyable_v< From > &&std::is_trivially_copyable_v< To >, To > bit_cast(const From &src) noexcept
Definition: base64.hpp:29
base64
Definition: base64.hpp:17
base64::from_base64
std::string from_base64(std::string_view data)
Definition: base64.hpp:690
base64::detail::encode_table_0
constexpr std::array< char, 256 > encode_table_0
Definition: base64.hpp:451
base64::detail::bad_char
constexpr uint32_t bad_char
Definition: base64.hpp:41
base64::encode_into
OutputBuffer encode_into(InputIterator begin, InputIterator end)
Definition: base64.hpp:494
base64::detail::padding_char
constexpr char padding_char
Definition: base64.hpp:40