]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/beast/core/detail/base64.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / beast / core / detail / base64.hpp
1 //
2 // Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // Official repository: https://github.com/boostorg/beast
8 //
9
10 /*
11 Portions from http://www.adp-gmbh.ch/cpp/common/base64.html
12 Copyright notice:
13
14 base64.cpp and base64.h
15
16 Copyright (C) 2004-2008 René Nyffenegger
17
18 This source code is provided 'as-is', without any express or implied
19 warranty. In no event will the author be held liable for any damages
20 arising from the use of this software.
21
22 Permission is granted to anyone to use this software for any purpose,
23 including commercial applications, and to alter it and redistribute it
24 freely, subject to the following restrictions:
25
26 1. The origin of this source code must not be misrepresented; you must not
27 claim that you wrote the original source code. If you use this source code
28 in a product, an acknowledgment in the product documentation would be
29 appreciated but is not required.
30
31 2. Altered source versions must be plainly marked as such, and must not be
32 misrepresented as being the original source code.
33
34 3. This notice may not be removed or altered from any source distribution.
35
36 René Nyffenegger rene.nyffenegger@adp-gmbh.ch
37
38 */
39
40 #ifndef BOOST_BEAST_DETAIL_BASE64_HPP
41 #define BOOST_BEAST_DETAIL_BASE64_HPP
42
43 #include <cctype>
44 #include <string>
45 #include <utility>
46
47 namespace boost {
48 namespace beast {
49 namespace detail {
50
51 namespace base64 {
52
53 inline
54 char const*
55 get_alphabet()
56 {
57 static char constexpr tab[] = {
58 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
59 };
60 return &tab[0];
61 }
62
63 inline
64 signed char const*
65 get_inverse()
66 {
67 static signed char constexpr tab[] = {
68 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0-15
69 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 16-31
70 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, // 32-47
71 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, // 48-63
72 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, // 64-79
73 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, // 80-95
74 -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, // 96-111
75 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, // 112-127
76 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 128-143
77 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 144-159
78 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 160-175
79 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 176-191
80 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 192-207
81 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 208-223
82 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 224-239
83 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 // 240-255
84 };
85 return &tab[0];
86 }
87
88
89 /// Returns max chars needed to encode a base64 string
90 inline
91 std::size_t constexpr
92 encoded_size(std::size_t n)
93 {
94 return 4 * ((n + 2) / 3);
95 }
96
97 /// Returns max bytes needed to decode a base64 string
98 inline
99 std::size_t constexpr
100 decoded_size(std::size_t n)
101 {
102 return n / 4 * 3; // requires n&3==0, smaller
103 //return 3 * n / 4;
104 }
105
106 /** Encode a series of octets as a padded, base64 string.
107
108 The resulting string will not be null terminated.
109
110 @par Requires
111
112 The memory pointed to by `out` points to valid memory
113 of at least `encoded_size(len)` bytes.
114
115 @return The number of characters written to `out`. This
116 will exclude any null termination.
117 */
118 template<class = void>
119 std::size_t
120 encode(void* dest, void const* src, std::size_t len)
121 {
122 char* out = static_cast<char*>(dest);
123 char const* in = static_cast<char const*>(src);
124 auto const tab = base64::get_alphabet();
125
126 for(auto n = len / 3; n--;)
127 {
128 *out++ = tab[ (in[0] & 0xfc) >> 2];
129 *out++ = tab[((in[0] & 0x03) << 4) + ((in[1] & 0xf0) >> 4)];
130 *out++ = tab[((in[2] & 0xc0) >> 6) + ((in[1] & 0x0f) << 2)];
131 *out++ = tab[ in[2] & 0x3f];
132 in += 3;
133 }
134
135 switch(len % 3)
136 {
137 case 2:
138 *out++ = tab[ (in[0] & 0xfc) >> 2];
139 *out++ = tab[((in[0] & 0x03) << 4) + ((in[1] & 0xf0) >> 4)];
140 *out++ = tab[ (in[1] & 0x0f) << 2];
141 *out++ = '=';
142 break;
143
144 case 1:
145 *out++ = tab[ (in[0] & 0xfc) >> 2];
146 *out++ = tab[((in[0] & 0x03) << 4)];
147 *out++ = '=';
148 *out++ = '=';
149 break;
150
151 case 0:
152 break;
153 }
154
155 return out - static_cast<char*>(dest);
156 }
157
158 /** Decode a padded base64 string into a series of octets.
159
160 @par Requires
161
162 The memory pointed to by `out` points to valid memory
163 of at least `decoded_size(len)` bytes.
164
165 @return The number of octets written to `out`, and
166 the number of characters read from the input string,
167 expressed as a pair.
168 */
169 template<class = void>
170 std::pair<std::size_t, std::size_t>
171 decode(void* dest, char const* src, std::size_t len)
172 {
173 char* out = static_cast<char*>(dest);
174 auto in = reinterpret_cast<unsigned char const*>(src);
175 unsigned char c3[3], c4[4];
176 int i = 0;
177 int j = 0;
178
179 auto const inverse = base64::get_inverse();
180
181 while(len-- && *in != '=')
182 {
183 auto const v = inverse[*in];
184 if(v == -1)
185 break;
186 ++in;
187 c4[i] = v;
188 if(++i == 4)
189 {
190 c3[0] = (c4[0] << 2) + ((c4[1] & 0x30) >> 4);
191 c3[1] = ((c4[1] & 0xf) << 4) + ((c4[2] & 0x3c) >> 2);
192 c3[2] = ((c4[2] & 0x3) << 6) + c4[3];
193
194 for(i = 0; i < 3; i++)
195 *out++ = c3[i];
196 i = 0;
197 }
198 }
199
200 if(i)
201 {
202 c3[0] = ( c4[0] << 2) + ((c4[1] & 0x30) >> 4);
203 c3[1] = ((c4[1] & 0xf) << 4) + ((c4[2] & 0x3c) >> 2);
204 c3[2] = ((c4[2] & 0x3) << 6) + c4[3];
205
206 for(j = 0; j < i - 1; j++)
207 *out++ = c3[j];
208 }
209
210 return {out - static_cast<char*>(dest),
211 in - reinterpret_cast<unsigned char const*>(src)};
212 }
213
214 } // base64
215
216 template<class = void>
217 std::string
218 base64_encode (std::uint8_t const* data,
219 std::size_t len)
220 {
221 std::string dest;
222 dest.resize(base64::encoded_size(len));
223 dest.resize(base64::encode(&dest[0], data, len));
224 return dest;
225 }
226
227 inline
228 std::string
229 base64_encode(std::string const& s)
230 {
231 return base64_encode (reinterpret_cast <
232 std::uint8_t const*> (s.data()), s.size());
233 }
234
235 template<class = void>
236 std::string
237 base64_decode(std::string const& data)
238 {
239 std::string dest;
240 dest.resize(base64::decoded_size(data.size()));
241 auto const result = base64::decode(
242 &dest[0], data.data(), data.size());
243 dest.resize(result.first);
244 return dest;
245 }
246
247 } // detail
248 } // beast
249 } // boost
250
251 #endif