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


xmlrpcpp
Author(s): Chris Morley, Konstantin Pilipchuk, Morgan Quigley
autogenerated on Mon Jun 10 2019 14:48:08