45#include <bsoncxx/config/prelude.hpp>
51BSONCXX_INLINE_NAMESPACE_BEGIN
54#define BSONCXX_B64_ASSERT(Cond) \
55 if (!(Cond)) std::abort()
57const char Base64[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
58const char Pad64 =
'=';
122BSONCXX_INLINE
int ntop(std::uint8_t
const *src, std::size_t srclength,
char *target,
123 std::size_t targsize) {
124 std::size_t datalength = 0;
125 std::uint8_t input[3];
126 std::uint8_t output[4];
129 while (2 < srclength) {
135 output[0] = input[0] >> 2;
136 output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
137 output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
138 output[3] = input[2] & 0x3f;
139 BSONCXX_B64_ASSERT(output[0] < 64);
140 BSONCXX_B64_ASSERT(output[1] < 64);
141 BSONCXX_B64_ASSERT(output[2] < 64);
142 BSONCXX_B64_ASSERT(output[3] < 64);
144 if (datalength + 4 > targsize) {
147 target[datalength++] = Base64[output[0]];
148 target[datalength++] = Base64[output[1]];
149 target[datalength++] = Base64[output[2]];
150 target[datalength++] = Base64[output[3]];
154 if (0 != srclength) {
156 input[0] = input[1] = input[2] =
'\0';
158 for (i = 0; i < srclength; i++) {
161 output[0] = input[0] >> 2;
162 output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
163 output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
164 BSONCXX_B64_ASSERT(output[0] < 64);
165 BSONCXX_B64_ASSERT(output[1] < 64);
166 BSONCXX_B64_ASSERT(output[2] < 64);
168 if (datalength + 4 > targsize) {
171 target[datalength++] = Base64[output[0]];
172 target[datalength++] = Base64[output[1]];
174 if (srclength == 1) {
175 target[datalength++] = Pad64;
177 target[datalength++] = Base64[output[2]];
179 target[datalength++] = Pad64;
182 if (datalength >= targsize) {
185 target[datalength] =
'\0';
186 return (
int)datalength;
190BSONCXX_INLINE_NAMESPACE_END
193#include <bsoncxx/config/postlude.hpp>