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