Mercurial > malikania
annotate tools/map/base64.hpp @ 215:268b66d72ec0 default tip @
misc: remove Javascript bindings, closes #2402
author | David Demelier <markand@malikania.fr> |
---|---|
date | Thu, 10 Oct 2019 13:52:57 +0200 |
parents | 975dffc6567a |
children |
rev | line source |
---|---|
86
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
1 /* |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
2 * base64.hpp -- base64 encoding and decoding |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
3 * |
158
4b292c20124c
Misc: update copyrights
David Demelier <markand@malikania.fr>
parents:
86
diff
changeset
|
4 * Copyright (c) 2013-2018 David Demelier <markand@malikania.fr> |
86
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
5 * |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
6 * Permission to use, copy, modify, and/or distribute this software for any |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
7 * purpose with or without fee is hereby granted, provided that the above |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
8 * copyright notice and this permission notice appear in all copies. |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
9 * |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
17 */ |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
18 |
185
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
19 #ifndef MALIKANIA_MAP_BASE64_HPP |
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
20 #define MALIKANIA_MAP_BASE64_HPP |
86
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
21 |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
22 /** |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
23 * \file base64.hpp |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
24 * \brief Base64 encoding and decoding. |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
25 * \author David Demelier <markand@malikania.fr> |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
26 * \version 2.0.0-dev |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
27 */ |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
28 |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
29 /** |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
30 * \page Base64 Base64 |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
31 * \brief Base64 encoding and decoding. |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
32 * |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
33 * The %base64 library let you encode and decode %base64 data from std::string |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
34 * and iterators. |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
35 * |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
36 * ## Encoding |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
37 * |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
38 * You can encode like this: |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
39 * |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
40 * ````cpp |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
41 * std::string b64 = base64::encode("Hello world!"); |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
42 * ```` |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
43 * |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
44 * ## Decoding |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
45 * |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
46 * And you can decode like this: |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
47 * |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
48 * ```` |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
49 * try { |
185
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
50 * std::string text = base64::decode(msg); |
86
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
51 * } catch (const std::exception &ex) { |
185
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
52 * std::cerr << ex.what() << std::endl; |
86
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
53 * } |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
54 * ```` |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
55 */ |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
56 |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
57 #include <cassert> |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
58 #include <cctype> |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
59 #include <stdexcept> |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
60 #include <string> |
185
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
61 #include <string_view> |
86
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
62 |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
63 /** |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
64 * \brief main %base64 namespace. |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
65 */ |
185
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
66 namespace mlk::base64 { |
86
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
67 |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
68 /** |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
69 * Check if the character is a %base64 character, A-Za-z0-9 and +/. |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
70 * |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
71 * \param ch the character to test |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
72 * \return true if valid |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
73 */ |
185
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
74 inline auto is_base64(char ch) noexcept -> bool |
86
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
75 { |
185
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
76 return std::isalnum(ch) != 0 || ch == '+' || ch == '/'; |
86
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
77 } |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
78 |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
79 /** |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
80 * Check if the given character is a valid character in %base64 string, |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
81 * including '='. |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
82 * |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
83 * \param ch the character |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
84 * \return true if the character is valid |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
85 */ |
185
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
86 inline auto is_valid(char ch) noexcept -> bool |
86
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
87 { |
185
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
88 return is_base64(ch) || ch == '='; |
86
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
89 } |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
90 |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
91 /** |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
92 * Get the %base64 character from the 6-bits value. |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
93 * |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
94 * \pre value must be valid (< 64) |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
95 * \param value the value |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
96 * \return the %base64 character for value |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
97 */ |
185
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
98 inline auto lookup(unsigned char value) noexcept -> char |
86
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
99 { |
185
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
100 static std::string_view table("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"); |
86
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
101 |
185
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
102 assert(value < 64); |
86
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
103 |
185
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
104 return table[value]; |
86
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
105 } |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
106 |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
107 /** |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
108 * Get the integer value from the %base64 character. |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
109 * |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
110 * \pre is_base64(ch) |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
111 * \param ch the %base64 character |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
112 * \return the integer value for the %base64 character ch |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
113 * ```` |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
114 * auto b64 = base64::rlookup('D') // 3 |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
115 * ```` |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
116 */ |
185
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
117 inline auto rlookup(char ch) noexcept -> unsigned char |
86
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
118 { |
185
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
119 assert(is_base64(ch)); |
86
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
120 |
185
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
121 if (ch >= '0' && ch <= '9') |
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
122 return static_cast<unsigned char>(ch + 4); |
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
123 if (ch >= 'A' && ch <= 'Z') |
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
124 return static_cast<unsigned char>(ch - 65); |
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
125 if (ch >= 'a' && ch <= 'z') |
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
126 return static_cast<unsigned char>(ch - 71); |
86
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
127 |
185
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
128 return (ch == '+') ? 62U : 63U; |
86
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
129 } |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
130 |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
131 /** |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
132 * Encode the input to the output. |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
133 * |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
134 * Requirements: |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
135 * - **InputIt** must be [InputIterator](http://en.cppreference.com/w/cpp/concept/InputIterator) |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
136 * - **OutputIt** must be [OutputIterator](http://en.cppreference.com/w/cpp/concept/OutputIterator) |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
137 * |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
138 * \param input the beginning |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
139 * \param end the end of the data |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
140 * \param output the output destination |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
141 * \return output |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
142 */ |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
143 template <typename InputIt, typename OutputIt> |
185
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
144 auto encode(InputIt input, InputIt end, OutputIt output) -> OutputIt |
86
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
145 { |
185
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
146 while (input != end) { |
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
147 char inputbuf[3] = { 0, 0, 0 }; |
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
148 int count; |
86
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
149 |
185
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
150 for (count = 0; count < 3 && input != end; ++count) |
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
151 inputbuf[count] = *input++; |
86
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
152 |
185
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
153 *output++ = lookup(inputbuf[0] >> 2 & 0x3f); |
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
154 *output++ = lookup((inputbuf[0] << 4 & 0x3f) | (inputbuf[1] >> 4 & 0x0f)); |
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
155 *output++ = (count < 2) ? '=' : lookup((inputbuf[1] << 2 & 0x3c) | (inputbuf[2] >> 6 & 0x03)); |
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
156 *output++ = (count < 3) ? '=' : lookup(inputbuf[2] & 0x3f); |
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
157 } |
86
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
158 |
185
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
159 return output; |
86
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
160 } |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
161 |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
162 /** |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
163 * Decode the input to the output. |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
164 * |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
165 * Requirements: |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
166 * - **InputIt** must be [InputIterator](http://en.cppreference.com/w/cpp/concept/InputIterator) |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
167 * - **OutputIt** must be [OutputIterator](http://en.cppreference.com/w/cpp/concept/OutputIterator) |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
168 * |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
169 * \param input the beginning |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
170 * \param end the end of the data |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
171 * \param output the output destination |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
172 * \return output |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
173 * \throw std::invalid_argument on bad %base64 string |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
174 */ |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
175 template <typename InputIt, typename OutputIt> |
185
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
176 auto decode(InputIt input, InputIt end, OutputIt output) -> OutputIt |
86
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
177 { |
185
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
178 while (input != end) { |
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
179 char inputbuf[4] = { -1, -1, -1, -1 }; |
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
180 int count; |
86
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
181 |
185
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
182 for (count = 0; count < 4 && input != end; ++count) { |
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
183 // Check if the character is valid and get its value. |
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
184 if ((*input == '=' && count <= 1) || !is_valid(*input)) |
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
185 throw std::invalid_argument("invalid base64 string"); |
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
186 if (is_base64(*input)) |
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
187 inputbuf[count] = static_cast<char>(rlookup(*input)); |
86
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
188 |
185
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
189 input++; |
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
190 } |
86
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
191 |
185
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
192 if (count != 4) |
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
193 throw std::invalid_argument("truncated string"); |
86
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
194 |
185
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
195 *output++ = static_cast<char>(((inputbuf[0] << 2) & 0xfc) | ((inputbuf[1] >> 4) & 0x03)); |
86
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
196 |
185
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
197 if (inputbuf[2] != -1) |
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
198 *output++ = static_cast<char>(((inputbuf[1] << 4) & 0xf0) | ((inputbuf[2] >> 2) & 0x0f)); |
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
199 if (inputbuf[3] != -1) { |
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
200 // "XY=Z" is not allowed. |
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
201 if (inputbuf[2] == -1) |
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
202 throw std::invalid_argument("invalid base64 string"); |
86
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
203 |
185
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
204 *output++ = static_cast<char>(((inputbuf[2] << 6) & 0xc0) | (inputbuf[3] & 0x3f)); |
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
205 } |
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
206 } |
86
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
207 |
185
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
208 return output; |
86
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
209 } |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
210 |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
211 /** |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
212 * Encode a string. |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
213 * |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
214 * \param input the input string |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
215 * \return the %base64 formatted string |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
216 */ |
185
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
217 inline auto encode(std::string_view input) -> std::string |
86
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
218 { |
185
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
219 std::string result; |
86
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
220 |
185
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
221 encode(input.begin(), input.end(), std::back_inserter(result)); |
86
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
222 |
185
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
223 return result; |
86
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
224 } |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
225 |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
226 /** |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
227 * Decode a string. |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
228 * |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
229 * \param input the %base64 formatted string |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
230 * \return the original string |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
231 * \throw std::invalid_argument on bad %base64 string |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
232 */ |
185
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
233 inline auto decode(std::string_view input) -> std::string |
86
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
234 { |
185
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
235 std::string result; |
86
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
236 |
185
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
237 decode(input.begin(), input.end(), std::back_inserter(result)); |
86
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
238 |
185
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
239 return result; |
86
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
240 } |
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
241 |
185
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
242 } // !mlk::base64 |
86
cbdd3302998c
Tools: implement basic mlk-map, closes #620
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
243 |
185
975dffc6567a
Tests: use ptree directly in mlk-map, closes #704 @1h
David Demelier <markand@malikania.fr>
parents:
158
diff
changeset
|
244 #endif // !MALIKANIA_MAP_BASE64_HPP |