1 | // |
2 | // Base32Encoder.cpp |
3 | // |
4 | // Library: Foundation |
5 | // Package: Streams |
6 | // Module: Base32 |
7 | // |
8 | // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. |
9 | // and Contributors. |
10 | // |
11 | // SPDX-License-Identifier: BSL-1.0 |
12 | // |
13 | |
14 | |
15 | #include "Poco/Base32Encoder.h" |
16 | |
17 | |
18 | namespace Poco { |
19 | |
20 | |
21 | const unsigned char Base32EncoderBuf::OUT_ENCODING[32] = |
22 | { |
23 | 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', |
24 | 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', |
25 | 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', |
26 | 'Y', 'Z', '2', '3', '4', '5', '6', '7', |
27 | }; |
28 | |
29 | |
30 | Base32EncoderBuf::Base32EncoderBuf(std::ostream& ostr, bool padding): |
31 | _groupLength(0), |
32 | _buf(*ostr.rdbuf()), |
33 | _doPadding(padding) |
34 | { |
35 | } |
36 | |
37 | |
38 | Base32EncoderBuf::~Base32EncoderBuf() |
39 | { |
40 | try |
41 | { |
42 | close(); |
43 | } |
44 | catch (...) |
45 | { |
46 | } |
47 | } |
48 | |
49 | |
50 | |
51 | int Base32EncoderBuf::writeToDevice(char c) |
52 | { |
53 | static const int eof = std::char_traits<char>::eof(); |
54 | |
55 | _group[_groupLength++] = (unsigned char) c; |
56 | if (_groupLength == 5) |
57 | { |
58 | unsigned char idx; |
59 | idx = _group[0] >> 3; |
60 | if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof; |
61 | idx = ((_group[0] & 0x07) << 2) | (_group[1] >> 6); |
62 | if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof; |
63 | idx = ((_group[1] & 0x3E) >> 1); |
64 | if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof; |
65 | idx = ((_group[1] & 0x01) << 4) | (_group[2] >> 4); |
66 | if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof; |
67 | idx = ((_group[2] & 0x0F) << 1) | (_group[3] >> 7); |
68 | if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof; |
69 | idx = ((_group[3] & 0x7C) >> 2); |
70 | if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof; |
71 | idx = ((_group[3] & 0x03) << 3) | (_group[4] >> 5); |
72 | if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof; |
73 | idx = (_group[4] & 0x1F); |
74 | if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof; |
75 | _groupLength = 0; |
76 | } |
77 | return charToInt(c); |
78 | } |
79 | |
80 | |
81 | int Base32EncoderBuf::close() |
82 | { |
83 | static const int eof = std::char_traits<char>::eof(); |
84 | |
85 | if (sync() == eof) return eof; |
86 | if (_groupLength == 1) |
87 | { |
88 | _group[1] = 0; |
89 | unsigned char idx; |
90 | idx = _group[0] >> 3; |
91 | if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof; |
92 | idx = ((_group[0] & 0x07) << 2); |
93 | if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof; |
94 | if (_doPadding) { |
95 | if (_buf.sputc('=') == eof) return eof; |
96 | if (_buf.sputc('=') == eof) return eof; |
97 | if (_buf.sputc('=') == eof) return eof; |
98 | if (_buf.sputc('=') == eof) return eof; |
99 | if (_buf.sputc('=') == eof) return eof; |
100 | if (_buf.sputc('=') == eof) return eof; |
101 | } |
102 | } |
103 | else if (_groupLength == 2) |
104 | { |
105 | _group[2] = 0; |
106 | unsigned char idx; |
107 | idx = _group[0] >> 3; |
108 | if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof; |
109 | idx = ((_group[0] & 0x07) << 2) | (_group[1] >> 6); |
110 | if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof; |
111 | idx = ((_group[1] & 0x3E) >> 1); |
112 | if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof; |
113 | idx = ((_group[1] & 0x01) << 4); |
114 | if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof; |
115 | if (_doPadding) { |
116 | if (_buf.sputc('=') == eof) return eof; |
117 | if (_buf.sputc('=') == eof) return eof; |
118 | if (_buf.sputc('=') == eof) return eof; |
119 | if (_buf.sputc('=') == eof) return eof; |
120 | } |
121 | } |
122 | else if (_groupLength == 3) |
123 | { |
124 | _group[3] = 0; |
125 | unsigned char idx; |
126 | idx = _group[0] >> 3; |
127 | if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof; |
128 | idx = ((_group[0] & 0x07) << 2) | (_group[1] >> 6); |
129 | if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof; |
130 | idx = ((_group[1] & 0x3E) >> 1); |
131 | if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof; |
132 | idx = ((_group[1] & 0x01) << 4) | (_group[2] >> 4); |
133 | if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof; |
134 | idx = ((_group[2] & 0x0F) << 1); |
135 | if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof; |
136 | if (_doPadding) { |
137 | if (_buf.sputc('=') == eof) return eof; |
138 | if (_buf.sputc('=') == eof) return eof; |
139 | if (_buf.sputc('=') == eof) return eof; |
140 | } |
141 | } |
142 | else if (_groupLength == 4) |
143 | { |
144 | _group[4] = 0; |
145 | unsigned char idx; |
146 | idx = _group[0] >> 3; |
147 | if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof; |
148 | idx = ((_group[0] & 0x07) << 2) | (_group[1] >> 6); |
149 | if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof; |
150 | idx = ((_group[1] & 0x3E) >> 1); |
151 | if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof; |
152 | idx = ((_group[1] & 0x01) << 4) | (_group[2] >> 4); |
153 | if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof; |
154 | idx = ((_group[2] & 0x0F) << 1) | (_group[3] >> 7); |
155 | if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof; |
156 | idx = ((_group[3] & 0x7C) >> 2); |
157 | if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof; |
158 | idx = ((_group[3] & 0x03) << 3); |
159 | if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof; |
160 | if (_doPadding && _buf.sputc('=') == eof) return eof; |
161 | } |
162 | _groupLength = 0; |
163 | return _buf.pubsync(); |
164 | } |
165 | |
166 | |
167 | Base32EncoderIOS::Base32EncoderIOS(std::ostream& ostr, bool padding): |
168 | _buf(ostr, padding) |
169 | { |
170 | poco_ios_init(&_buf); |
171 | } |
172 | |
173 | |
174 | Base32EncoderIOS::~Base32EncoderIOS() |
175 | { |
176 | } |
177 | |
178 | |
179 | int Base32EncoderIOS::close() |
180 | { |
181 | return _buf.close(); |
182 | } |
183 | |
184 | |
185 | Base32EncoderBuf* Base32EncoderIOS::rdbuf() |
186 | { |
187 | return &_buf; |
188 | } |
189 | |
190 | |
191 | Base32Encoder::Base32Encoder(std::ostream& ostr, bool padding): |
192 | Base32EncoderIOS(ostr, padding), std::ostream(&_buf) |
193 | { |
194 | } |
195 | |
196 | |
197 | Base32Encoder::~Base32Encoder() |
198 | { |
199 | } |
200 | |
201 | |
202 | } // namespace Poco |
203 | |