BOSS 8.0.0
BESIII Offline Software System
Loading...
Searching...
No Matches
base64.h
Go to the documentation of this file.
1
2
3// base64.hpp
4// Autor Konstantin Pilipchuk
5// mailto:lostd@ukr.net
6//
7//
8
9#if !defined( __BASE64_H_INCLUDED__ )
10# define __BASE64_H_INCLUDED__ 1
11
12# ifndef MAKEDEPEND
13# include <iterator>
14# endif
15
16static int _base64Chars[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
17 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
18 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
19 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
20 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' };
21
22# define _0000_0011 0x03
23# define _1111_1100 0xFC
24# define _1111_0000 0xF0
25# define _0011_0000 0x30
26# define _0011_1100 0x3C
27# define _0000_1111 0x0F
28# define _1100_0000 0xC0
29# define _0011_1111 0x3F
30
31# define _EQUAL_CHAR ( -1 )
32# define _UNKNOWN_CHAR ( -2 )
33
34# define _IOS_FAILBIT std::ios_base::failbit
35# define _IOS_EOFBIT std::ios_base::eofbit
36# define _IOS_BADBIT std::ios_base::badbit
37# define _IOS_GOODBIT std::ios_base::goodbit
38
39// TEMPLATE CLASS base64_put
40template <class _E = char, class _Tr = std::char_traits<_E>> class base64 {
41public:
42 typedef unsigned char byte_t;
43 typedef _E char_type;
44 typedef _Tr traits_type;
45
46 // base64 requires max line length <= 72 characters
47 // you can fill end of line
48 // it may be crlf, crlfsp, noline or other class like it
49
50 struct crlf {
51 template <class _OI> _OI operator()( _OI _To ) const {
52 *_To = _Tr::to_char_type( '\r' );
53 ++_To;
54 *_To = _Tr::to_char_type( '\n' );
55 ++_To;
56
57 return ( _To );
58 }
59 };
60
61 struct crlfsp {
62 template <class _OI> _OI operator()( _OI _To ) const {
63 *_To = _Tr::to_char_type( '\r' );
64 ++_To;
65 *_To = _Tr::to_char_type( '\n' );
66 ++_To;
67 *_To = _Tr::to_char_type( ' ' );
68 ++_To;
69
70 return ( _To );
71 }
72 };
73
74 struct noline {
75 template <class _OI> _OI operator()( _OI _To ) const { return ( _To ); }
76 };
77
78 struct three2four {
79 void zero() {
80 _data[0] = 0;
81 _data[1] = 0;
82 _data[2] = 0;
83 }
84
85 byte_t get_0() const { return _data[0]; }
86 byte_t get_1() const { return _data[1]; }
87 byte_t get_2() const { return _data[2]; }
88
89 void set_0( byte_t _ch ) { _data[0] = _ch; }
90
91 void set_1( byte_t _ch ) { _data[1] = _ch; }
92
93 void set_2( byte_t _ch ) { _data[2] = _ch; }
94
95 // 0000 0000 1111 1111 2222 2222
96 // xxxx xxxx xxxx xxxx xxxx xxxx
97 // 0000 0011 1111 2222 2233 3333
98
99 int b64_0() const { return ( _data[0] & _1111_1100 ) >> 2; }
100 int b64_1() const {
101 return ( ( _data[0] & _0000_0011 ) << 4 ) + ( ( _data[1] & _1111_0000 ) >> 4 );
102 }
103 int b64_2() const {
104 return ( ( _data[1] & _0000_1111 ) << 2 ) + ( ( _data[2] & _1100_0000 ) >> 6 );
105 }
106 int b64_3() const { return ( _data[2] & _0011_1111 ); }
107
108 void b64_0( int _ch ) {
109 _data[0] = ( ( _ch & _0011_1111 ) << 2 ) | ( _0000_0011 & _data[0] );
110 }
111
112 void b64_1( int _ch ) {
113 _data[0] = ( ( _ch & _0011_0000 ) >> 4 ) | ( _1111_1100 & _data[0] );
114 _data[1] = ( ( _ch & _0000_1111 ) << 4 ) | ( _0000_1111 & _data[1] );
115 }
116
117 void b64_2( int _ch ) {
118 _data[1] = ( ( _ch & _0011_1100 ) >> 2 ) | ( _1111_0000 & _data[1] );
119 _data[2] = ( ( _ch & _0000_0011 ) << 6 ) | ( _0011_1111 & _data[2] );
120 }
121
122 void b64_3( int _ch ) { _data[2] = ( _ch & _0011_1111 ) | ( _1100_0000 & _data[2] ); }
123
124 private:
125 byte_t _data[3];
126 };
127
128 template <class _II, class _OI, class _State, class _Endline>
129 _II put( _II _First, _II _Last, _OI _To, _State& _St, _Endline _Endl ) const {
130 three2four _3to4;
131 int line_octets = 0;
132
133 while ( _First != _Last )
134 {
135 _3to4.zero();
136
137 // берём по 3 символа
138 _3to4.set_0( *_First );
139 _First++;
140
141 if ( _First == _Last )
142 {
143 *_To = _Tr::to_char_type( _base64Chars[_3to4.b64_0()] );
144 ++_To;
145 *_To = _Tr::to_char_type( _base64Chars[_3to4.b64_1()] );
146 ++_To;
147 *_To = _Tr::to_char_type( '=' );
148 ++_To;
149 *_To = _Tr::to_char_type( '=' );
150 ++_To;
151 goto __end;
152 }
153
154 _3to4.set_1( *_First );
155 _First++;
156
157 if ( _First == _Last )
158 {
159 *_To = _Tr::to_char_type( _base64Chars[_3to4.b64_0()] );
160 ++_To;
161 *_To = _Tr::to_char_type( _base64Chars[_3to4.b64_1()] );
162 ++_To;
163 *_To = _Tr::to_char_type( _base64Chars[_3to4.b64_2()] );
164 ++_To;
165 *_To = _Tr::to_char_type( '=' );
166 ++_To;
167 goto __end;
168 }
169
170 _3to4.set_2( *_First );
171 _First++;
172
173 *_To = _Tr::to_char_type( _base64Chars[_3to4.b64_0()] );
174 ++_To;
175 *_To = _Tr::to_char_type( _base64Chars[_3to4.b64_1()] );
176 ++_To;
177 *_To = _Tr::to_char_type( _base64Chars[_3to4.b64_2()] );
178 ++_To;
179 *_To = _Tr::to_char_type( _base64Chars[_3to4.b64_3()] );
180 ++_To;
181
182 if ( line_octets == 17 ) // base64 позволяет длину строки не более 72 символов
183 {
184 //_To = _Endl(_To);
185 *_To = '\n';
186 ++_To;
187 line_octets = 0;
188 }
189 else ++line_octets;
190 }
191
192 __end:;
193
194 return ( _First );
195 }
196
197 template <class _II, class _OI, class _State>
198 _II get( _II _First, _II _Last, _OI _To, _State& _St ) const {
199 three2four _3to4;
200 int _Char;
201
202 while ( _First != _Last )
203 {
204
205 // Take octet
206 _3to4.zero();
207
208 // -- 0 --
209 // Search next valid char...
210 while ( ( _Char = _getCharType( *_First ) ) < 0 && _Char == _UNKNOWN_CHAR )
211 {
212 if ( ++_First == _Last )
213 {
214 _St |= _IOS_FAILBIT | _IOS_EOFBIT;
215 return _First; // unexpected EOF
216 }
217 }
218
219 if ( _Char == _EQUAL_CHAR )
220 {
221 // Error! First character in octet can't be '='
222 _St |= _IOS_FAILBIT;
223 return _First;
224 }
225 else _3to4.b64_0( _Char );
226
227 // -- 1 --
228 // Search next valid char...
229 while ( ++_First != _Last )
230 if ( ( _Char = _getCharType( *_First ) ) != _UNKNOWN_CHAR ) break;
231
232 if ( _First == _Last )
233 {
234 _St |= _IOS_FAILBIT | _IOS_EOFBIT; // unexpected EOF
235 return _First;
236 }
237
238 if ( _Char == _EQUAL_CHAR )
239 {
240 // Error! Second character in octet can't be '='
241 _St |= _IOS_FAILBIT;
242 return _First;
243 }
244 else _3to4.b64_1( _Char );
245
246 // -- 2 --
247 // Search next valid char...
248 while ( ++_First != _Last )
249 if ( ( _Char = _getCharType( *_First ) ) != _UNKNOWN_CHAR ) break;
250
251 if ( _First == _Last )
252 {
253 // Error! Unexpected EOF. Must be '=' or base64 character
254 _St |= _IOS_FAILBIT | _IOS_EOFBIT;
255 return _First;
256 }
257
258 if ( _Char == _EQUAL_CHAR )
259 {
260 // OK!
261 _3to4.b64_2( 0 );
262 _3to4.b64_3( 0 );
263
264 // chek for EOF
265 if ( ++_First == _Last )
266 {
267 // Error! Unexpected EOF. Must be '='. Ignore it.
268 //_St |= _IOS_BADBIT|_IOS_EOFBIT;
269 _St |= _IOS_EOFBIT;
270 }
271 else if ( _getCharType( *_First ) != _EQUAL_CHAR )
272 {
273 // Error! Must be '='. Ignore it.
274 //_St |= _IOS_BADBIT;
275 }
276 else ++_First; // Skip '='
277
278 // write 1 byte to output
279 *_To = (byte_t)_3to4.get_0();
280 return _First;
281 }
282 else _3to4.b64_2( _Char );
283
284 // -- 3 --
285 // Search next valid char...
286 while ( ++_First != _Last )
287 if ( ( _Char = _getCharType( *_First ) ) != _UNKNOWN_CHAR ) break;
288
289 if ( _First == _Last )
290 {
291 // Unexpected EOF. It's error. But ignore it.
292 //_St |= _IOS_FAILBIT|_IOS_EOFBIT;
293 _St |= _IOS_EOFBIT;
294
295 return _First;
296 }
297
298 if ( _Char == _EQUAL_CHAR )
299 {
300 // OK!
301 _3to4.b64_3( 0 );
302
303 // write to output 2 bytes
304 *_To = (byte_t)_3to4.get_0();
305 *_To = (byte_t)_3to4.get_1();
306
307 ++_First; // set position to next character
308
309 return _First;
310 }
311 else _3to4.b64_3( _Char );
312
313 // write to output 3 bytes
314 *_To = (byte_t)_3to4.get_0();
315 *_To = (byte_t)_3to4.get_1();
316 *_To = (byte_t)_3to4.get_2();
317
318 ++_First;
319
320 } // while(_First != _Last)
321
322 return ( _First );
323 }
324
325protected:
326 int _getCharType( int _Ch ) const {
327 if ( _base64Chars[62] == _Ch ) return 62;
328
329 if ( _base64Chars[63] == _Ch ) return 63;
330
331 if ( ( _base64Chars[0] <= _Ch ) && ( _base64Chars[25] >= _Ch ) )
332 return _Ch - _base64Chars[0];
333
334 if ( ( _base64Chars[26] <= _Ch ) && ( _base64Chars[51] >= _Ch ) )
335 return _Ch - _base64Chars[26] + 26;
336
337 if ( ( _base64Chars[52] <= _Ch ) && ( _base64Chars[61] >= _Ch ) )
338 return _Ch - _base64Chars[52] + 52;
339
340 if ( _Ch == _Tr::to_int_type( '=' ) ) return _EQUAL_CHAR;
341
342 return _UNKNOWN_CHAR;
343 }
344};
345
346#endif
#define _0000_1111
Definition base64.h:27
#define _0011_0000
Definition base64.h:25
#define _1111_1100
Definition base64.h:23
#define _0011_1111
Definition base64.h:29
#define _0000_0011
Definition base64.h:22
#define _IOS_EOFBIT
Definition base64.h:35
#define _1111_0000
Definition base64.h:24
#define _0011_1100
Definition base64.h:26
#define _EQUAL_CHAR
Definition base64.h:31
#define _UNKNOWN_CHAR
Definition base64.h:32
#define _1100_0000
Definition base64.h:28
#define _IOS_FAILBIT
Definition base64.h:34
_II put(_II _First, _II _Last, _OI _To, _State &_St, _Endline _Endl) const
Definition base64.h:129
unsigned char byte_t
Definition base64.h:42
_II get(_II _First, _II _Last, _OI _To, _State &_St) const
Definition base64.h:198
_Tr traits_type
Definition base64.h:44
_E char_type
Definition base64.h:43
int _getCharType(int _Ch) const
Definition base64.h:326
_OI operator()(_OI _To) const
Definition base64.h:51
_OI operator()(_OI _To) const
Definition base64.h:62
_OI operator()(_OI _To) const
Definition base64.h:75
byte_t get_0() const
Definition base64.h:85
void set_1(byte_t _ch)
Definition base64.h:91
byte_t get_1() const
Definition base64.h:86
void b64_3(int _ch)
Definition base64.h:122
byte_t get_2() const
Definition base64.h:87
void set_0(byte_t _ch)
Definition base64.h:89
void b64_1(int _ch)
Definition base64.h:112
int b64_3() const
Definition base64.h:106
void set_2(byte_t _ch)
Definition base64.h:93
int b64_1() const
Definition base64.h:100
int b64_2() const
Definition base64.h:103
void b64_0(int _ch)
Definition base64.h:108
int b64_0() const
Definition base64.h:99
void b64_2(int _ch)
Definition base64.h:117