]> git.proxmox.com Git - ceph.git/blob - ceph/src/Beast/include/beast/core/detail/base64.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / Beast / include / beast / core / detail / base64.hpp
1 //
2 // Copyright (c) 2013-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
8 #ifndef BEAST_DETAIL_BASE64_HPP
9 #define BEAST_DETAIL_BASE64_HPP
10
11 #include <cctype>
12 #include <string>
13
14 namespace beast {
15 namespace detail {
16
17 /*
18 Portions from http://www.adp-gmbh.ch/cpp/common/base64.html
19 Copyright notice:
20
21 base64.cpp and base64.h
22
23 Copyright (C) 2004-2008 René Nyffenegger
24
25 This source code is provided 'as-is', without any express or implied
26 warranty. In no event will the author be held liable for any damages
27 arising from the use of this software.
28
29 Permission is granted to anyone to use this software for any purpose,
30 including commercial applications, and to alter it and redistribute it
31 freely, subject to the following restrictions:
32
33 1. The origin of this source code must not be misrepresented; you must not
34 claim that you wrote the original source code. If you use this source code
35 in a product, an acknowledgment in the product documentation would be
36 appreciated but is not required.
37
38 2. Altered source versions must be plainly marked as such, and must not be
39 misrepresented as being the original source code.
40
41 3. This notice may not be removed or altered from any source distribution.
42
43 René Nyffenegger rene.nyffenegger@adp-gmbh.ch
44
45 */
46
47 template<class = void>
48 std::string const&
49 base64_alphabet()
50 {
51 static std::string const alphabet =
52 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
53 "abcdefghijklmnopqrstuvwxyz"
54 "0123456789+/";
55 return alphabet;
56 }
57
58 inline
59 bool
60 is_base64(unsigned char c)
61 {
62 return (std::isalnum(c) || (c == '+') || (c == '/'));
63 }
64
65 template<class = void>
66 std::string
67 base64_encode (std::uint8_t const* data,
68 std::size_t in_len)
69 {
70 unsigned char c3[3], c4[4];
71 int i = 0;
72 int j = 0;
73
74 std::string ret;
75 ret.reserve (3 + in_len * 8 / 6);
76
77 char const* alphabet (base64_alphabet().data());
78
79 while(in_len--)
80 {
81 c3[i++] = *(data++);
82 if(i == 3)
83 {
84 c4[0] = (c3[0] & 0xfc) >> 2;
85 c4[1] = ((c3[0] & 0x03) << 4) + ((c3[1] & 0xf0) >> 4);
86 c4[2] = ((c3[1] & 0x0f) << 2) + ((c3[2] & 0xc0) >> 6);
87 c4[3] = c3[2] & 0x3f;
88 for(i = 0; (i < 4); i++)
89 ret += alphabet[c4[i]];
90 i = 0;
91 }
92 }
93
94 if(i)
95 {
96 for(j = i; j < 3; j++)
97 c3[j] = '\0';
98
99 c4[0] = (c3[0] & 0xfc) >> 2;
100 c4[1] = ((c3[0] & 0x03) << 4) + ((c3[1] & 0xf0) >> 4);
101 c4[2] = ((c3[1] & 0x0f) << 2) + ((c3[2] & 0xc0) >> 6);
102 c4[3] = c3[2] & 0x3f;
103
104 for(j = 0; (j < i + 1); j++)
105 ret += alphabet[c4[j]];
106
107 while((i++ < 3))
108 ret += '=';
109 }
110
111 return ret;
112
113 }
114
115 template<class = void>
116 std::string
117 base64_encode (std::string const& s)
118 {
119 return base64_encode (reinterpret_cast <
120 std::uint8_t const*> (s.data()), s.size());
121 }
122
123 template<class = void>
124 std::string
125 base64_decode(std::string const& data)
126 {
127 auto in_len = data.size();
128 unsigned char c3[3], c4[4];
129 int i = 0;
130 int j = 0;
131 int in_ = 0;
132
133 std::string ret;
134 ret.reserve (in_len * 6 / 8); // ???
135
136 while(in_len-- && (data[in_] != '=') &&
137 is_base64(data[in_]))
138 {
139 c4[i++] = data[in_]; in_++;
140 if(i == 4) {
141 for(i = 0; i < 4; i++)
142 c4[i] = static_cast<unsigned char>(
143 base64_alphabet().find(c4[i]));
144
145 c3[0] = (c4[0] << 2) + ((c4[1] & 0x30) >> 4);
146 c3[1] = ((c4[1] & 0xf) << 4) + ((c4[2] & 0x3c) >> 2);
147 c3[2] = ((c4[2] & 0x3) << 6) + c4[3];
148
149 for(i = 0; (i < 3); i++)
150 ret += c3[i];
151 i = 0;
152 }
153 }
154
155 if(i)
156 {
157 for(j = i; j < 4; j++)
158 c4[j] = 0;
159
160 for(j = 0; j < 4; j++)
161 c4[j] = static_cast<unsigned char>(
162 base64_alphabet().find(c4[j]));
163
164 c3[0] = (c4[0] << 2) + ((c4[1] & 0x30) >> 4);
165 c3[1] = ((c4[1] & 0xf) << 4) + ((c4[2] & 0x3c) >> 2);
166 c3[2] = ((c4[2] & 0x3) << 6) + c4[3];
167
168 for(j = 0; (j < i - 1); j++)
169 ret += c3[j];
170 }
171
172 return ret;
173 }
174
175 } // detail
176 } // beast
177
178 #endif