00001
00002
00003
00004
00005
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
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
00053
00054
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
00127
00128
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
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
00225 _3to4.zero();
00226
00227
00228
00229 while((_Char = _getCharType(*_First)) < 0 && _Char == _UNKNOWN_CHAR)
00230 {
00231 if(++_First == _Last)
00232 {
00233 _St |= _IOS_FAILBIT|_IOS_EOFBIT; return _First;
00234 }
00235 }
00236
00237 if(_Char == _EQUAL_CHAR){
00238
00239 _St |= _IOS_FAILBIT;
00240 return _First;
00241 }
00242 else
00243 _3to4.b64_0(_Char);
00244
00245
00246
00247
00248 while(++_First != _Last)
00249 if((_Char = _getCharType(*_First)) != _UNKNOWN_CHAR)
00250 break;
00251
00252 if(_First == _Last) {
00253 _St |= _IOS_FAILBIT|_IOS_EOFBIT;
00254 return _First;
00255 }
00256
00257 if(_Char == _EQUAL_CHAR){
00258
00259 _St |= _IOS_FAILBIT;
00260 return _First;
00261 }
00262 else
00263 _3to4.b64_1(_Char);
00264
00265
00266
00267
00268 while(++_First != _Last)
00269 if((_Char = _getCharType(*_First)) != _UNKNOWN_CHAR)
00270 break;
00271
00272 if(_First == _Last) {
00273
00274 _St |= _IOS_FAILBIT|_IOS_EOFBIT;
00275 return _First;
00276 }
00277
00278 if(_Char == _EQUAL_CHAR){
00279
00280 _3to4.b64_2(0);
00281 _3to4.b64_3(0);
00282
00283
00284 if(++_First == _Last)
00285 {
00286
00287
00288 _St |= _IOS_EOFBIT;
00289 }
00290 else
00291 if(_getCharType(*_First) != _EQUAL_CHAR)
00292 {
00293
00294
00295 }
00296 else
00297 ++_First;
00298
00299
00300 *_To = (byte_t) _3to4.get_0();
00301 return _First;
00302 }
00303 else
00304 _3to4.b64_2(_Char);
00305
00306
00307
00308
00309 while(++_First != _Last)
00310 if((_Char = _getCharType(*_First)) != _UNKNOWN_CHAR)
00311 break;
00312
00313 if(_First == _Last) {
00314
00315
00316 _St |= _IOS_EOFBIT;
00317
00318 return _First;
00319 }
00320
00321 if(_Char == _EQUAL_CHAR)
00322 {
00323
00324 _3to4.b64_3(0);
00325
00326
00327 *_To = (byte_t) _3to4.get_0();
00328 *_To = (byte_t) _3to4.get_1();
00329
00330 ++_First;
00331
00332 return _First;
00333 }
00334 else
00335 _3to4.b64_3(_Char);
00336
00337
00338
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 }
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