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


xmlrpcpp
Author(s): Chris Morley, Konstantin Pilipchuk, Morgan Quigley
autogenerated on Thu Jun 6 2019 21:10:00