]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/beast/core/detail/base64.ipp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / boost / beast / core / detail / base64.ipp
1 //
2 // Copyright (c) 2016-2019 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 Rene 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 Rene Nyffenegger rene.nyffenegger@adp-gmbh.ch
37 */
38
39 #ifndef BOOST_BEAST_DETAIL_BASE64_IPP
40 #define BOOST_BEAST_DETAIL_BASE64_IPP
41
42 #include <boost/beast/core/detail/base64.hpp>
43 #include <boost/beast/core/string.hpp>
44 #include <cctype>
45 #include <string>
46 #include <utility>
47
48 namespace boost {
49 namespace beast {
50 namespace detail {
51
52 namespace base64 {
53
54 char const*
55 get_alphabet()
56 {
57 static char constexpr tab[] = {
58 "ABCDEFGHIJKLMNOP"
59 "QRSTUVWXYZabcdef"
60 "ghijklmnopqrstuv"
61 "wxyz0123456789+/"
62 };
63 return &tab[0];
64 }
65
66 signed char const*
67 get_inverse()
68 {
69 static signed char constexpr tab[] = {
70 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0-15
71 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 16-31
72 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, // 32-47
73 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, // 48-63
74 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, // 64-79
75 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, // 80-95
76 -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, // 96-111
77 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, // 112-127
78 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 128-143
79 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 144-159
80 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 160-175
81 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 176-191
82 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 192-207
83 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 208-223
84 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 224-239
85 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 // 240-255
86 };
87 return &tab[0];
88 }
89
90 /** Encode a series of octets as a padded, base64 string.
91
92 The resulting string will not be null terminated.
93
94 @par Requires
95
96 The memory pointed to by `out` points to valid memory
97 of at least `encoded_size(len)` bytes.
98
99 @return The number of characters written to `out`. This
100 will exclude any null termination.
101 */
102 std::size_t
103 encode(void* dest, void const* src, std::size_t len)
104 {
105 char* out = static_cast<char*>(dest);
106 char const* in = static_cast<char const*>(src);
107 auto const tab = base64::get_alphabet();
108
109 for(auto n = len / 3; n--;)
110 {
111 *out++ = tab[ (in[0] & 0xfc) >> 2];
112 *out++ = tab[((in[0] & 0x03) << 4) + ((in[1] & 0xf0) >> 4)];
113 *out++ = tab[((in[2] & 0xc0) >> 6) + ((in[1] & 0x0f) << 2)];
114 *out++ = tab[ in[2] & 0x3f];
115 in += 3;
116 }
117
118 switch(len % 3)
119 {
120 case 2:
121 *out++ = tab[ (in[0] & 0xfc) >> 2];
122 *out++ = tab[((in[0] & 0x03) << 4) + ((in[1] & 0xf0) >> 4)];
123 *out++ = tab[ (in[1] & 0x0f) << 2];
124 *out++ = '=';
125 break;
126
127 case 1:
128 *out++ = tab[ (in[0] & 0xfc) >> 2];
129 *out++ = tab[((in[0] & 0x03) << 4)];
130 *out++ = '=';
131 *out++ = '=';
132 break;
133
134 case 0:
135 break;
136 }
137
138 return out - static_cast<char*>(dest);
139 }
140
141 /** Decode a padded base64 string into a series of octets.
142
143 @par Requires
144
145 The memory pointed to by `out` points to valid memory
146 of at least `decoded_size(len)` bytes.
147
148 @return The number of octets written to `out`, and
149 the number of characters read from the input string,
150 expressed as a pair.
151 */
152 std::pair<std::size_t, std::size_t>
153 decode(void* dest, char const* src, std::size_t len)
154 {
155 char* out = static_cast<char*>(dest);
156 auto in = reinterpret_cast<unsigned char const*>(src);
157 unsigned char c3[3], c4[4];
158 int i = 0;
159 int j = 0;
160
161 auto const inverse = base64::get_inverse();
162
163 while(len-- && *in != '=')
164 {
165 auto const v = inverse[*in];
166 if(v == -1)
167 break;
168 ++in;
169 c4[i] = v;
170 if(++i == 4)
171 {
172 c3[0] = (c4[0] << 2) + ((c4[1] & 0x30) >> 4);
173 c3[1] = ((c4[1] & 0xf) << 4) + ((c4[2] & 0x3c) >> 2);
174 c3[2] = ((c4[2] & 0x3) << 6) + c4[3];
175
176 for(i = 0; i < 3; i++)
177 *out++ = c3[i];
178 i = 0;
179 }
180 }
181
182 if(i)
183 {
184 c3[0] = ( c4[0] << 2) + ((c4[1] & 0x30) >> 4);
185 c3[1] = ((c4[1] & 0xf) << 4) + ((c4[2] & 0x3c) >> 2);
186 c3[2] = ((c4[2] & 0x3) << 6) + c4[3];
187
188 for(j = 0; j < i - 1; j++)
189 *out++ = c3[j];
190 }
191
192 return {out - static_cast<char*>(dest),
193 in - reinterpret_cast<unsigned char const*>(src)};
194 }
195
196 } // base64
197
198 } // detail
199 } // beast
200 } // boost
201
202 #endif