MySQL 8.0.40
Source Code Documentation
base64.h
Go to the documentation of this file.
1/*
2 Copyright (c) 2018, 2024, Oracle and/or its affiliates.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License, version 2.0,
6 as published by the Free Software Foundation.
7
8 This program is designed to work with certain software (including
9 but not limited to OpenSSL) that is licensed under separate terms,
10 as designated in a particular file or component or in included license
11 documentation. The authors of MySQL hereby grant you an additional
12 permission to link the program and your derivative works with the
13 separately licensed software that they have either included with
14 the program or referenced in the documentation.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24*/
25
26#ifndef MYSQLROUTER_HTTP_BASE64_INCLUDED
27#define MYSQLROUTER_HTTP_BASE64_INCLUDED
28
30
31#include <algorithm> // min
32#include <array>
33#include <cstdint>
34#include <stdexcept>
35#include <string>
36#include <utility> // index_sequence
37#include <vector>
38
39enum class Base64Endianess { LITTLE, BIG };
40
41/**
42 * Generic Base64 codec.
43 *
44 * Base64 comes in many flavours:
45 *
46 * - RFC4648 used by HTTP
47 * - crypt
48 * - bcrypt
49 * - pbkdf2 in MCF
50 * - UUencode
51 *
52 * they differ by
53 *
54 * - alphabet
55 * - endianness
56 * - padding
57 *
58 * Base64Impl provides generic encode and decode methods which are parametrized
59 * by Endianness, Padding.
60 *
61 * Parametrization with templates allows to provide:
62 *
63 * - one implementation for all combinations
64 * - without extra runtime overhead as dead code is removed by the compiler
65 *
66 * Endianness
67 * =========
68 *
69 * Little Endian
70 * -------------
71 *
72 * using Alphabet=Crypt
73 *
74 * octet(hex): 55
75 * uint32: ........ ........ 01010101 (LSB)
76 * uint32: ...... ...... ....01 010101 (LSB)
77 * sextet(hex): 1 15
78 * Alphabet: / J
79 *
80 * Out: J/
81 *
82 *
83 * Big Endian
84 * ----------
85 *
86 * using Alphabet=Crypt
87 *
88 * octet(hex): 55
89 * uint32: 01010101 ........ ........ (LSB)
90 * uint32: 010101 01.... ...... ...... (LSB)
91 * sextet(hex): 15 10
92 * Alphabet: J E
93 *
94 * Out: JE
95 *
96 * Padding
97 * =======
98 *
99 * If padding is defined mandatory,
100 *
101 * - at encode() each group of 4 sextets is filled by with the padding
102 * character.
103 * - at decode() input must have padding.
104 *
105 * If padding is not mandatory,
106 *
107 * - at encode() no padding is added.
108 * - at decode() padding is accepted, but not required.
109 */
110
111/*
112 * TODO: look into
113 *
114 * - http://0x80.pl/notesen/2015-12-27-base64-encoding.html
115 * - http://0x80.pl/notesen/2016-01-12-sse-base64-encoding.html
116 * - http://0x80.pl/notesen/2016-01-17-sse-base64-decoding.html
117 * - http://alfredklomp.com/programming/sse-base64/
118 * - https://github.com/lemire/fastbase64
119 */
121 public:
122 /**
123 * type of all alphabet.
124 */
125 using alphabet_type = std::array<char, 64>;
126
127 /**
128 * type of all inverse mappings of alphabets.
129 *
130 * - -1 invalid
131 * - 0-63 position into alphabet
132 */
133 using inverse_alphabet_type = std::array<int8_t, 256>;
134
135 template <Base64Endianess endianess, bool PaddingMandatory, char PaddingChar>
136 static std::vector<uint8_t> decode(
137 const std::string &encoded,
138 const inverse_alphabet_type &inverse_alphabet) {
139 std::vector<uint8_t> out((encoded.size() + 3) / 4 * 3);
140
141 constexpr unsigned int shift_pos_0 =
142 endianess == Base64Endianess::BIG ? 16 : 0;
143 constexpr unsigned int shift_pos_1 =
144 endianess == Base64Endianess::BIG ? 8 : 8;
145 constexpr unsigned int shift_pos_2 =
146 endianess == Base64Endianess::BIG ? 0 : 16;
147
148 auto out_it = out.begin();
149 auto data_it = encoded.cbegin();
150 const auto data_end_it = encoded.cend();
151 while (const size_t data_left = std::distance(data_it, data_end_it)) {
152 if (data_left < 2) {
153 throw std::runtime_error("invalid sequence");
154 }
155
156 if (PaddingMandatory && (data_left < 4)) {
157 throw std::runtime_error("missing padding");
158 }
159
160 uint32_t v = 0;
161 bool is_padding = false;
162 const size_t max_rounds = std::min(size_t{4}, data_left);
163 uint32_t sextets = 0;
164 for (size_t cnt = 0; cnt < max_rounds; ++cnt) {
165 const uint8_t b64 = *(data_it++);
166 if (is_padding && b64 != PaddingChar) {
167 throw std::runtime_error("invalid char, expected padding");
168 }
169 const int8_t c = (inverse_alphabet[b64]);
170
171 if (c == -1) {
172 if (data_left <= 4 && cnt >= 2 && b64 == PaddingChar) {
173 // padding is ok at the end
174 is_padding = true;
175 } else {
176 throw std::runtime_error(std::string("invalid char"));
177 }
178 }
179
180 // add new 6 bits
181 if (!is_padding) {
182 if (endianess == Base64Endianess::BIG) {
183 v |= c << (6 * (3 - cnt));
184 } else {
185 v |= c << (6 * cnt);
186 }
187 sextets++;
188 }
189 }
190
191 // 3 * 6bit b64 = 18bits translates to 16bit (2 bits extra)
192 // 2 * 6bit b64 = 12bits translates to 8bit (4 bits extra)
193 //
194 // They must be 0b0 to ensure only one b64 value
195 // maps to one 8bit version and the other way around.
196 //
197 // Example
198 // ------
199 //
200 // WWU= -> Ye -> WWU=
201 //
202 // 0x14
203 // ...... ...... 010100
204 // ........ ........ xx
205 //
206 // WWW= -> Ye -> WWU=
207 //
208 // 0x16
209 // ...... ...... 010110
210 // ........ ........ xx
211 //
212 switch (sextets) {
213 case 2:
214 *(out_it++) = static_cast<uint8_t>(v >> shift_pos_0);
215
216 if (0 != static_cast<uint8_t>(v >> shift_pos_1)) {
217 throw std::runtime_error("unused bits");
218 }
219 break;
220 case 3:
221 *(out_it++) = static_cast<uint8_t>(v >> shift_pos_0);
222 *(out_it++) = static_cast<uint8_t>(v >> shift_pos_1);
223
224 if (0 != static_cast<uint8_t>(v >> shift_pos_2)) {
225 throw std::runtime_error("unused bits");
226 }
227 break;
228 case 4:
229 *(out_it++) = static_cast<uint8_t>(v >> shift_pos_0);
230 *(out_it++) = static_cast<uint8_t>(v >> shift_pos_1);
231 *(out_it++) = static_cast<uint8_t>(v >> shift_pos_2);
232 break;
233 }
234 }
235
236 out.resize(std::distance(out.begin(), out_it));
237
238 return out;
239 }
240
241 template <Base64Endianess endianess, bool PaddingMandatory, char PaddingChar>
242 static std::string encode(const std::vector<uint8_t> &data,
243 const alphabet_type &alphabet) {
244 std::string out;
245 // ensure we have enough space
246 out.resize((data.size() + 2) / 3 * 4);
247
248 constexpr unsigned int shift_pos_0 =
249 endianess == Base64Endianess::BIG ? 16 : 0;
250 constexpr unsigned int shift_pos_1 =
251 endianess == Base64Endianess::BIG ? 8 : 8;
252 constexpr unsigned int shift_pos_2 =
253 endianess == Base64Endianess::BIG ? 0 : 16;
254
255 auto out_it = out.begin();
256 auto data_it = data.begin();
257 const auto data_end_it = data.end();
258 while (const size_t data_left = std::distance(data_it, data_end_it)) {
259 // consume 3 bytes, if we have them
260 uint32_t v = 0;
261
262 size_t padding_pos = 4; // no padding
263 switch (data_left) {
264 case 1:
265 v |= (*(data_it++)) << shift_pos_0;
266 padding_pos = 2; // out-byte 2 and 3 are padding
267 break;
268 case 2:
269 v |= (*(data_it++)) << shift_pos_0;
270 v |= (*(data_it++)) << shift_pos_1;
271 padding_pos = 3; // out-byte 3 is padding
272 break;
273 default:
274 v |= (*(data_it++)) << shift_pos_0;
275 v |= (*(data_it++)) << shift_pos_1;
276 v |= (*(data_it++)) << shift_pos_2;
277 break;
278 }
279
280 // and base64-encode them
281 size_t cnt;
282 for (cnt = 0; cnt < 4; ++cnt) {
283 if (cnt >= padding_pos) {
284 break;
285 }
286
287 size_t pos;
288 if (endianess == Base64Endianess::BIG) {
289 // take the upper 6 bit and shift left each round
290 pos = (v & (0x3f << (3 * 6))) >> 3 * 6;
291 v <<= 6;
292 } else {
293 // take the lower 6 bit and shift right each round
294 pos = v & 0x3f;
295 v >>= 6;
296 }
297 *(out_it++) = alphabet.at(pos);
298 }
299
300 if (PaddingMandatory) {
301 // apply padding if needed
302 for (; cnt < 4; ++cnt) {
303 *(out_it++) = PaddingChar;
304 }
305 }
306 }
307 out.resize(std::distance(out.begin(), out_it));
308
309 return out;
310 }
311};
312
313namespace Base64Alphabet {
314
315/**
316 * type of all alphabet.
317 */
319
320/**
321 * type of all inverse mappings of alphabets.
322 *
323 * - -1 invalid
324 * - 0-63 position into alphabet
325 */
327
328namespace detail {
329/**
330 * find position of char in alphabet.
331 *
332 * @returns position in alphabet
333 * @retval -1 if not found
334 */
335constexpr int8_t find_pos_of_char(const alphabet_type &v, uint8_t character,
336 size_t v_ndx = 0) {
337 // ensure that -1 and 255 don't overlap
338 static_assert(alphabet_type().size() <= 128,
339 "alphabet MUST less <= 128 chars");
340 return (v_ndx >= v.size() ? -1
341 : (v[v_ndx] == static_cast<char>(character))
342 ? static_cast<uint8_t>(v_ndx)
343 : find_pos_of_char(v, character, v_ndx + 1));
344}
345
346// hand-roll std::make_index_sequence<256> as SunCC 12.6 runs into:
347//
348// Error: Templates nested too deeply (recursively?).
349//
350// for std::make_index_sequence<n> with n > 255
351//
352// see: https://community.oracle.com/thread/4070120
353//
354// There exists a workaround:
355//
356// > The compiler has an undocumented "Q option" (or "Wizard option") that
357// > lets you increase the allowed depth:
358// >
359// > -Qoption ccfe -tmpldepth=N
360// > -W0,-tmpldepth=N
361//
362// but here we go the hand-rolled version of what std::make_index_sequence<256>
363// would have generated instead.
364
365using ndx_256 = std::index_sequence<
366 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
367 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
368 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
369 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77,
370 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96,
371 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
372 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
373 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142,
374 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157,
375 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172,
376 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187,
377 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202,
378 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217,
379 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232,
380 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247,
381 248, 249, 250, 251, 252, 253, 254, 255>;
382
383/**
384 * build inverse-alphabet.
385 *
386 * calls find_pos_by_char() for each element of ndx_256
387 *
388 * based on C++11 parameter pack.
389 */
390template <std::size_t... I>
392 std::index_sequence<I...>) {
393 return {{find_pos_of_char(v, I)...}};
394}
395
396/**
397 * inverse
398 */
400 return make_inverse_array(v, ndx_256{});
401}
402} // namespace detail
403
404class Base64 {
405 public:
407 {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', // 0x00
408 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', //
409 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', // 0x10
410 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', //
411 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', // 0x20
412 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', //
413 'w', 'x', 'y', 'z', '0', '1', '2', '3', // 0x30
414 '4', '5', '6', '7', '8', '9', '+', '/'}};
415
418};
419
421 public:
423 {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', // 0x00
424 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', //
425 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', // 0x10
426 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', //
427 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', // 0x20
428 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', //
429 'w', 'x', 'y', 'z', '0', '1', '2', '3', // 0x30
430 '4', '5', '6', '7', '8', '9', '-', '_'}};
431
434};
435
436/**
437 * Base64 alphabet for MCF.
438 *
439 * same as Base64 from RFC4648, but different altchars to fit the needs of MCF
440 *
441 * altchars
442 * : . and /
443 *
444 * paddingchar
445 * : =
446 *
447 * padding mandatory
448 * : no
449 */
450class Mcf {
451 public:
453 {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', // 0x00
454 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', //
455 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', // 0x10
456 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', //
457 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', // 0x20
458 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', //
459 'w', 'x', 'y', 'z', '0', '1', '2', '3', // 0x30
460 '4', '5', '6', '7', '8', '9', '.', '/'}};
461
464};
465
466class Crypt {
467 public:
469 {'.', '/', '0', '1', '2', '3', '4', '5', // 0x00
470 '6', '7', '8', '9', 'A', 'B', 'C', 'D', //
471 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', // 0x10
472 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', //
473 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', // 0x20
474 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', //
475 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', // 0x30
476 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'}};
477
480};
481
482class Bcrypt {
483 public:
485 {'.', '/', 'A', 'B', 'C', 'D', 'E', 'F', // 0x00
486 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', //
487 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', // 0x10
488 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', //
489 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', // 0x20
490 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', //
491 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', // 0x30
492 '2', '3', '4', '5', '6', '7', '8', '9'}};
493
496};
497
498class Uuencode {
499 public:
501 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, // 0x00
502 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
503 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, // 0x10
504 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
505 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, // 0x20
506 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
507 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, // 0x30
508 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
509 }};
510
513};
514} // namespace Base64Alphabet
515
516/**
517 * Base64 codec base class.
518 */
519template <class Alphabet, Base64Endianess E, bool PaddingMandatory,
520 char PaddingChar>
522 public:
523 /**
524 * decode a base64 encoded string to binary.
525 *
526 * @pre encoded only contains alphabet
527 *
528 * @throws std::runtime_error if preconditions are not met
529 * @returns binary representation
530 */
531 static std::vector<uint8_t> decode(const std::string &encoded) {
532 return Base64Impl::decode<E, PaddingMandatory, PaddingChar>(
533 encoded, Alphabet::inverse_alphabet);
534 }
535
536 /**
537 * encode binary to base64.
538 */
539 static std::string encode(const std::vector<uint8_t> &decoded) {
540 return Base64Impl::encode<E, PaddingMandatory, PaddingChar>(
541 decoded, Alphabet::alphabet);
542 }
543};
544
545/**
546 * 'base64' alphabet from RFC4648.
547 *
548 * also used by:
549 *
550 * - uuencode-base64
551 * - data URI scheme (RFC2397)
552 *
553 * alphabet
554 * : `ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/`
555 *
556 * padding mandatory
557 * : yes, with =
558 */
559using Base64 =
561
562/**
563 * 'base64url' URL and Filename-safe Base64 alphabet from RFC4648.
564 *
565 * '+' and '/' in 'base64' have special meaning in URLs and would need
566 * to be URL-encoded.
567 *
568 * alphabet
569 * : `ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_`
570 *
571 * padding mandatory
572 * : yes, with =
573 */
576
577/**
578 * Base64 alphabet for MCF's pbkdf2 methods.
579 *
580 * alphabet
581 * : `ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789./`
582 *
583 * padding mandatory
584 * : no
585 */
588
589/**
590 * Radix64 for crypt (little-endian).
591 *
592 * alphabet
593 * : `./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz`
594 *
595 * padding mandatory
596 * : no
597 */
600
601/**
602 * Radix64 for crypt (big-endian).
603 *
604 * @see Radix64Crypt
605 */
608
609/**
610 * Radix64 for bcrypt.
611 *
612 * alphabet
613 * : `./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789`
614 *
615 * padding mandatory
616 * : no
617 */
620
621/**
622 * Radix64 for traditional Uuencode.
623 *
624 * alphabet
625 * : 0x32...0x95
626 *
627 * padding mandatory
628 * : yes, with accent
629 */
632
633#endif
Definition: base64.h:420
static constexpr inverse_alphabet_type HTTP_COMMON_EXPORT inverse_alphabet
Definition: base64.h:432
static constexpr alphabet_type HTTP_COMMON_EXPORT alphabet
Definition: base64.h:422
Definition: base64.h:404
static constexpr alphabet_type HTTP_COMMON_EXPORT alphabet
Definition: base64.h:406
static constexpr inverse_alphabet_type HTTP_COMMON_EXPORT inverse_alphabet
Definition: base64.h:416
Definition: base64.h:482
static constexpr alphabet_type HTTP_COMMON_EXPORT alphabet
Definition: base64.h:484
static constexpr inverse_alphabet_type HTTP_COMMON_EXPORT inverse_alphabet
Definition: base64.h:494
Definition: base64.h:466
static constexpr alphabet_type HTTP_COMMON_EXPORT alphabet
Definition: base64.h:468
static constexpr inverse_alphabet_type HTTP_COMMON_EXPORT inverse_alphabet
Definition: base64.h:478
Base64 alphabet for MCF.
Definition: base64.h:450
static constexpr alphabet_type HTTP_COMMON_EXPORT alphabet
Definition: base64.h:452
static constexpr inverse_alphabet_type HTTP_COMMON_EXPORT inverse_alphabet
Definition: base64.h:462
Definition: base64.h:498
static constexpr alphabet_type HTTP_COMMON_EXPORT alphabet
Definition: base64.h:500
static constexpr inverse_alphabet_type HTTP_COMMON_EXPORT inverse_alphabet
Definition: base64.h:511
Base64 codec base class.
Definition: base64.h:521
static std::string encode(const std::vector< uint8_t > &decoded)
encode binary to base64.
Definition: base64.h:539
static std::vector< uint8_t > decode(const std::string &encoded)
decode a base64 encoded string to binary.
Definition: base64.h:531
Generic Base64 codec.
Definition: base64.h:120
static std::vector< uint8_t > decode(const std::string &encoded, const inverse_alphabet_type &inverse_alphabet)
Definition: base64.h:136
static std::string encode(const std::vector< uint8_t > &data, const alphabet_type &alphabet)
Definition: base64.h:242
std::array< int8_t, 256 > inverse_alphabet_type
type of all inverse mappings of alphabets.
Definition: base64.h:133
std::array< char, 64 > alphabet_type
type of all alphabet.
Definition: base64.h:125
#define HTTP_COMMON_EXPORT
Definition: http_common_export.h:40
constexpr inverse_alphabet_type inverse(const alphabet_type &v)
inverse
Definition: base64.h:399
constexpr int8_t find_pos_of_char(const alphabet_type &v, uint8_t character, size_t v_ndx=0)
find position of char in alphabet.
Definition: base64.h:335
std::index_sequence< 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 > ndx_256
Definition: base64.h:381
constexpr inverse_alphabet_type make_inverse_array(const alphabet_type &v, std::index_sequence< I... >)
build inverse-alphabet.
Definition: base64.h:391
Definition: base64.h:313
Base64Impl::inverse_alphabet_type inverse_alphabet_type
type of all inverse mappings of alphabets.
Definition: base64.h:326
Base64Impl::alphabet_type alphabet_type
type of all alphabet.
Definition: base64.h:318
Definition: ut0tuple.h:57
bool distance(const dd::Spatial_reference_system *srs, const Geometry *g1, const Geometry *g2, double *distance, bool *is_null) noexcept
Computes the distance between two geometries.
Definition: distance.cc:40
Base64Endianess
Definition: base64.h:39