32 std::istream* decorated;
34 static const int base64_index[256];
36 enum { BUFFER_SIZE = 3 * 26 };
37 char buffer[BUFFER_SIZE];
42 std::istream* decorated_);
52 virtual int underflow()
override;
55 std::uint8_t quaternion_[]);
58 const int Base64IStream::Buffer::base64_index[256] = {
59 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
60 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
61 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
62 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
63 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
64 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
65 -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
66 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
70 std::istream* decorated_) :
71 decorated(decorated_),
73 assert(decorated !=
nullptr);
81 bool Base64IStream::Buffer::readQuaternion(
82 std::uint8_t quaternion_[]) {
85 int ci_(decorated->get());
88 if(ci_ == traits_type::eof())
92 std::uint8_t c_(
static_cast<std::uint8_t
>(traits_type::to_char_type(ci_)));
97 if(c_ !=
'=' && base64_index[c_] == -1)
101 quaternion_[i_++] = c_;
107 int Base64IStream::Buffer::underflow() {
111 setg(
nullptr,
nullptr,
nullptr);
112 return traits_type::eof();
116 char const*
const end_(buffer + BUFFER_SIZE);
119 std::uint8_t quaternion_[4];
120 if(!readQuaternion(quaternion_)) {
126 if(quaternion_[3] !=
'=') {
128 std::uint32_t decoded_(
129 base64_index[quaternion_[0]] << 18
130 | base64_index[quaternion_[1]] << 12
131 | base64_index[quaternion_[2]] << 6
132 | base64_index[quaternion_[3]]);
133 *out_++ = decoded_ >> 16 & 0xff;
134 *out_++ = decoded_ >> 8 & 0xff;
135 *out_++ = decoded_ & 0xff;
139 std::uint32_t decoded_(
140 base64_index[quaternion_[0]] << 18
141 | base64_index[quaternion_[1]] << 12);
142 *out_++ = decoded_ >> 16 & 0xff;
143 if(quaternion_[2] !=
'=') {
144 decoded_ |= base64_index[quaternion_[2]] << 6;
145 *out_++ = decoded_ >> 8 & 0xff;
154 setg(buffer, buffer, out_);
158 return traits_type::to_int_type(*buffer);
160 return traits_type::eof();
164 std::istream* decorated_) :
165 buffer(new
Buffer(decorated_)) {