base64.h
Go to the documentation of this file.
00001 
00002 
00003 //  base64.hpp 
00004 //  Autor Konstantin Pilipchuk
00005 //  mailto:lostd@ukr.net
00006 //
00007 //
00008 
00009 #if !defined(__BASE64_H_INCLUDED__)
00010 #define __BASE64_H_INCLUDED__ 1
00011 
00012 #ifndef MAKEDEPEND
00013 # include <iterator>
00014 #endif
00015 
00016 static
00017 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',
00018                                      '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',
00019                                  '0','1','2','3','4','5','6','7','8','9',
00020                                  '+','/' };
00021 
00022 
00023 #define _0000_0011 0x03
00024 #define _1111_1100 0xFC
00025 #define _1111_0000 0xF0
00026 #define _0011_0000 0x30
00027 #define _0011_1100 0x3C
00028 #define _0000_1111 0x0F
00029 #define _1100_0000 0xC0
00030 #define _0011_1111 0x3F
00031 
00032 #define _EQUAL_CHAR   (-1)
00033 #define _UNKNOWN_CHAR (-2)
00034 
00035 #define _IOS_FAILBIT   std::ios_base::failbit
00036 #define _IOS_EOFBIT    std::ios_base::eofbit
00037 #define _IOS_BADBIT    std::ios_base::badbit
00038 #define _IOS_GOODBIT   std::ios_base::goodbit
00039 
00040 // TEMPLATE CLASS base64_put
00041 template<class _E = char, class _Tr = std::char_traits<_E> >
00042 class base64
00043 {
00044 public:
00045 
00046         typedef unsigned char byte_t;
00047         typedef _E            char_type;
00048         typedef _Tr           traits_type; 
00049 
00050         // base64 requires max line length <= 72 characters
00051         // you can fill end of line
00052         // it may be crlf, crlfsp, noline or other class like it
00053 
00054 
00055         struct crlf
00056         {
00057                 template<class _OI>
00058                         _OI operator()(_OI _To) const{
00059                         *_To = _Tr::to_char_type('\r'); ++_To;
00060                         *_To = _Tr::to_char_type('\n'); ++_To;
00061 
00062                         return (_To);
00063                 }
00064         };
00065 
00066 
00067         struct crlfsp
00068         {
00069                 template<class _OI>
00070                         _OI operator()(_OI _To) const{
00071                         *_To = _Tr::to_char_type('\r'); ++_To;
00072                         *_To = _Tr::to_char_type('\n'); ++_To;
00073                         *_To = _Tr::to_char_type(' '); ++_To;
00074 
00075                         return (_To);
00076                 }
00077         };
00078 
00079         struct noline
00080         {
00081                 template<class _OI>
00082                         _OI operator()(_OI _To) const{
00083                         return (_To);
00084                 }
00085         };
00086 
00087         struct three2four
00088         {
00089                 void zero()
00090                 {
00091                         _data[0] = 0;
00092                         _data[1] = 0;
00093                         _data[2] = 0;
00094                 }
00095 
00096                 byte_t get_0()  const
00097                 {
00098                         return _data[0];
00099                 }
00100                 byte_t get_1()  const
00101                 {
00102                         return _data[1];
00103                 }
00104                 byte_t get_2()  const
00105                 {
00106                         return _data[2];
00107                 }
00108 
00109                 void set_0(byte_t _ch)
00110                 {
00111                         _data[0] = _ch;
00112                 }
00113 
00114                 void set_1(byte_t _ch)
00115                 {
00116                         _data[1] = _ch;
00117                 }
00118 
00119                 void set_2(byte_t _ch)
00120                 {
00121                         _data[2] = _ch;
00122                 }
00123 
00124                 // 0000 0000  1111 1111  2222 2222
00125                 // xxxx xxxx  xxxx xxxx  xxxx xxxx
00126                 // 0000 0011  1111 2222  2233 3333
00127 
00128                 int b64_0()     const   {return (_data[0] & _1111_1100) >> 2;}
00129                 int b64_1()     const   {return ((_data[0] & _0000_0011) << 4) + ((_data[1] & _1111_0000)>>4);}
00130                 int b64_2()     const   {return ((_data[1] & _0000_1111) << 2) + ((_data[2] & _1100_0000)>>6);}
00131                 int b64_3()     const   {return (_data[2] & _0011_1111);}
00132 
00133                 void b64_0(int _ch)     {_data[0] = ((_ch & _0011_1111) << 2) | (_0000_0011 & _data[0]);}
00134 
00135                 void b64_1(int _ch)     {
00136                         _data[0] = ((_ch & _0011_0000) >> 4) | (_1111_1100 & _data[0]);
00137                         _data[1] = ((_ch & _0000_1111) << 4) | (_0000_1111 & _data[1]); }
00138 
00139                 void b64_2(int _ch)     {
00140                         _data[1] = ((_ch & _0011_1100) >> 2) | (_1111_0000 & _data[1]);
00141                         _data[2] = ((_ch & _0000_0011) << 6) | (_0011_1111 & _data[2]); }
00142 
00143                 void b64_3(int _ch){
00144                         _data[2] = (_ch & _0011_1111) | (_1100_0000 & _data[2]);}
00145 
00146         private:
00147                 byte_t _data[3];
00148 
00149         };
00150 
00151 
00152 
00153 
00154         template<class _II, class _OI, class _State, class _Endline>
00155         _II put(_II _First, _II _Last, _OI _To, _State&, _Endline)  const
00156         {
00157                 three2four _3to4;
00158                 int line_octets = 0;
00159 
00160                 while(_First != _Last)
00161                 {
00162                         _3to4.zero();
00163 
00164                         _3to4.set_0(*_First);
00165                         _First++;
00166 
00167                         if(_First == _Last)
00168                         {
00169                                 *_To = _Tr::to_char_type(_base64Chars[_3to4.b64_0()]); ++_To;
00170                                 *_To = _Tr::to_char_type(_base64Chars[_3to4.b64_1()]); ++_To;
00171                                 *_To = _Tr::to_char_type('='); ++_To;
00172                                 *_To = _Tr::to_char_type('='); ++_To;
00173                                 goto __end;
00174                         }
00175 
00176                         _3to4.set_1(*_First);
00177                         _First++;
00178 
00179                         if(_First == _Last)
00180                         {
00181                                 *_To = _Tr::to_char_type(_base64Chars[_3to4.b64_0()]); ++_To;
00182                                 *_To = _Tr::to_char_type(_base64Chars[_3to4.b64_1()]); ++_To;
00183                                 *_To = _Tr::to_char_type(_base64Chars[_3to4.b64_2()]); ++_To;
00184                                 *_To = _Tr::to_char_type('='); ++_To;
00185                                 goto __end;
00186                         }
00187 
00188                         _3to4.set_2(*_First);
00189                         _First++;
00190 
00191                         *_To = _Tr::to_char_type(_base64Chars[_3to4.b64_0()]); ++_To;
00192                         *_To = _Tr::to_char_type(_base64Chars[_3to4.b64_1()]); ++_To;
00193                         *_To = _Tr::to_char_type(_base64Chars[_3to4.b64_2()]); ++_To;
00194                         *_To = _Tr::to_char_type(_base64Chars[_3to4.b64_3()]); ++_To;
00195 
00196                         if(line_octets == 17)
00197                         {
00198                                 //_To = _Endl(_To);
00199                                 *_To = '\n'; ++_To;
00200                                 line_octets = 0;
00201                         }
00202                         else
00203                                 ++line_octets;
00204                 }
00205 
00206                 __end: ;
00207 
00208                 return (_First);
00209 
00210         }
00211 
00212 
00213         template<class _II, class _OI, class _State>
00214                 _II get(_II _First, _II _Last, _OI _To, _State& _St) const
00215         {
00216                 three2four _3to4;
00217                 int _Char;
00218 
00219                 while(_First != _Last)
00220                 {
00221 
00222                         // Take octet
00223                         _3to4.zero();
00224 
00225                         // -- 0 --
00226                         // Search next valid char... 
00227                         while((_Char =  _getCharType(*_First)) < 0 && _Char == _UNKNOWN_CHAR)
00228                         {
00229                                 if(++_First == _Last)
00230                                 {
00231                                         _St |= _IOS_FAILBIT|_IOS_EOFBIT; return _First; // unexpected EOF
00232                                 }
00233                         }
00234 
00235                         if(_Char == _EQUAL_CHAR){
00236                                 // Error! First character in octet can't be '='
00237                                 _St |= _IOS_FAILBIT; 
00238                                 return _First; 
00239                         }
00240                         else
00241                                 _3to4.b64_0(_Char);
00242 
00243 
00244                         // -- 1 --
00245                         // Search next valid char... 
00246                         while(++_First != _Last)
00247                                 if((_Char = _getCharType(*_First)) != _UNKNOWN_CHAR)
00248                                         break;
00249 
00250                         if(_First == _Last)     {
00251                                 _St |= _IOS_FAILBIT|_IOS_EOFBIT; // unexpected EOF 
00252                                 return _First;
00253                         }
00254 
00255                         if(_Char == _EQUAL_CHAR){
00256                                 // Error! Second character in octet can't be '='
00257                                 _St |= _IOS_FAILBIT; 
00258                                 return _First; 
00259                         }
00260                         else
00261                                 _3to4.b64_1(_Char);
00262 
00263 
00264                         // -- 2 --
00265                         // Search next valid char... 
00266                         while(++_First != _Last)
00267                                 if((_Char = _getCharType(*_First)) != _UNKNOWN_CHAR)
00268                                         break;
00269 
00270                         if(_First == _Last)     {
00271                                 // Error! Unexpected EOF. Must be '=' or base64 character
00272                                 _St |= _IOS_FAILBIT|_IOS_EOFBIT; 
00273                                 return _First; 
00274                         }
00275 
00276                         if(_Char == _EQUAL_CHAR){
00277                                 // OK!
00278                                 _3to4.b64_2(0); 
00279                                 _3to4.b64_3(0); 
00280 
00281                                 // chek for EOF
00282                                 if(++_First == _Last)
00283                                 {
00284                                         // Error! Unexpected EOF. Must be '='. Ignore it.
00285                                         //_St |= _IOS_BADBIT|_IOS_EOFBIT;
00286                                         _St |= _IOS_EOFBIT;
00287                                 }
00288                                 else 
00289                                         if(_getCharType(*_First) != _EQUAL_CHAR)
00290                                         {
00291                                                 // Error! Must be '='. Ignore it.
00292                                                 //_St |= _IOS_BADBIT;
00293                                         }
00294                                 else
00295                                         ++_First; // Skip '='
00296 
00297                                 // write 1 byte to output
00298                                 *_To = (byte_t) _3to4.get_0();
00299                                 return _First;
00300                         }
00301                         else
00302                                 _3to4.b64_2(_Char);
00303 
00304 
00305                         // -- 3 --
00306                         // Search next valid char... 
00307                         while(++_First != _Last)
00308                                 if((_Char = _getCharType(*_First)) != _UNKNOWN_CHAR)
00309                                         break;
00310 
00311                         if(_First == _Last)     {
00312                                 // Unexpected EOF. It's error. But ignore it.
00313                                 //_St |= _IOS_FAILBIT|_IOS_EOFBIT; 
00314                                         _St |= _IOS_EOFBIT; 
00315                                 
00316                                 return _First; 
00317                         }
00318 
00319                         if(_Char == _EQUAL_CHAR)
00320                         {
00321                                 // OK!
00322                                 _3to4.b64_3(0); 
00323 
00324                                 // write to output 2 bytes
00325                                 *_To = (byte_t) _3to4.get_0();
00326                                 *_To = (byte_t) _3to4.get_1();
00327 
00328                                 ++_First; // set position to next character
00329 
00330                                 return _First;
00331                         }
00332                         else
00333                                 _3to4.b64_3(_Char);
00334 
00335 
00336                         // write to output 3 bytes
00337                         *_To = (byte_t) _3to4.get_0();
00338                         *_To = (byte_t) _3to4.get_1();
00339                         *_To = (byte_t) _3to4.get_2();
00340 
00341                         ++_First;
00342                         
00343 
00344                 } // while(_First != _Last)
00345 
00346                 return (_First);
00347         }
00348 
00349 protected:
00350         
00351         int _getCharType(int _Ch) const
00352         {
00353                 if(_base64Chars[62] == _Ch)
00354                         return 62;
00355 
00356                 if(_base64Chars[63] == _Ch)
00357                         return 63;
00358 
00359                 if((_base64Chars[0] <= _Ch) && (_base64Chars[25] >= _Ch))
00360                         return _Ch - _base64Chars[0];
00361 
00362                 if((_base64Chars[26] <= _Ch) && (_base64Chars[51] >= _Ch))
00363                         return _Ch - _base64Chars[26] + 26;
00364 
00365                 if((_base64Chars[52] <= _Ch) && (_base64Chars[61] >= _Ch))
00366                         return _Ch - _base64Chars[52] + 52;
00367 
00368                 if(_Ch == _Tr::to_int_type('='))
00369                         return _EQUAL_CHAR;
00370 
00371                 return _UNKNOWN_CHAR;
00372         }
00373 
00374 
00375 };
00376 
00377 
00378 #endif


xmlrpcpp
Author(s): Chris Morley and Konstantin Pilipchuk, slight modifications and ROS wrapping by Morgan Quigley
autogenerated on Sat Dec 28 2013 17:42:59