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& _St, _Endline _Endl) const
00156 {
00157 three2four _3to4;
00158 int line_octets = 0;
00159
00160 while(_First != _Last)
00161 {
00162 _3to4.zero();
00163
00164
00165 _3to4.set_0(*_First);
00166 _First++;
00167
00168 if(_First == _Last)
00169 {
00170 *_To = _Tr::to_char_type(_base64Chars[_3to4.b64_0()]); ++_To;
00171 *_To = _Tr::to_char_type(_base64Chars[_3to4.b64_1()]); ++_To;
00172 *_To = _Tr::to_char_type('='); ++_To;
00173 *_To = _Tr::to_char_type('='); ++_To;
00174 goto __end;
00175 }
00176
00177 _3to4.set_1(*_First);
00178 _First++;
00179
00180 if(_First == _Last)
00181 {
00182 *_To = _Tr::to_char_type(_base64Chars[_3to4.b64_0()]); ++_To;
00183 *_To = _Tr::to_char_type(_base64Chars[_3to4.b64_1()]); ++_To;
00184 *_To = _Tr::to_char_type(_base64Chars[_3to4.b64_2()]); ++_To;
00185 *_To = _Tr::to_char_type('='); ++_To;
00186 goto __end;
00187 }
00188
00189 _3to4.set_2(*_First);
00190 _First++;
00191
00192 *_To = _Tr::to_char_type(_base64Chars[_3to4.b64_0()]); ++_To;
00193 *_To = _Tr::to_char_type(_base64Chars[_3to4.b64_1()]); ++_To;
00194 *_To = _Tr::to_char_type(_base64Chars[_3to4.b64_2()]); ++_To;
00195 *_To = _Tr::to_char_type(_base64Chars[_3to4.b64_3()]); ++_To;
00196
00197 if(line_octets == 17)
00198 {
00199
00200 *_To = '\n'; ++_To;
00201 line_octets = 0;
00202 }
00203 else
00204 ++line_octets;
00205 }
00206
00207 __end: ;
00208
00209 return (_First);
00210
00211 }
00212
00213
00214 template<class _II, class _OI, class _State>
00215 _II get(_II _First, _II _Last, _OI _To, _State& _St) const
00216 {
00217 three2four _3to4;
00218 int _Char;
00219
00220 while(_First != _Last)
00221 {
00222
00223
00224 _3to4.zero();
00225
00226
00227
00228 while((_Char = _getCharType(*_First)) < 0 && _Char == _UNKNOWN_CHAR)
00229 {
00230 if(++_First == _Last)
00231 {
00232 _St |= _IOS_FAILBIT|_IOS_EOFBIT; return _First;
00233 }
00234 }
00235
00236 if(_Char == _EQUAL_CHAR){
00237
00238 _St |= _IOS_FAILBIT;
00239 return _First;
00240 }
00241 else
00242 _3to4.b64_0(_Char);
00243
00244
00245
00246
00247 while(++_First != _Last)
00248 if((_Char = _getCharType(*_First)) != _UNKNOWN_CHAR)
00249 break;
00250
00251 if(_First == _Last) {
00252 _St |= _IOS_FAILBIT|_IOS_EOFBIT;
00253 return _First;
00254 }
00255
00256 if(_Char == _EQUAL_CHAR){
00257
00258 _St |= _IOS_FAILBIT;
00259 return _First;
00260 }
00261 else
00262 _3to4.b64_1(_Char);
00263
00264
00265
00266
00267 while(++_First != _Last)
00268 if((_Char = _getCharType(*_First)) != _UNKNOWN_CHAR)
00269 break;
00270
00271 if(_First == _Last) {
00272
00273 _St |= _IOS_FAILBIT|_IOS_EOFBIT;
00274 return _First;
00275 }
00276
00277 if(_Char == _EQUAL_CHAR){
00278
00279 _3to4.b64_2(0);
00280 _3to4.b64_3(0);
00281
00282
00283 if(++_First == _Last)
00284 {
00285
00286
00287 _St |= _IOS_EOFBIT;
00288 }
00289 else
00290 if(_getCharType(*_First) != _EQUAL_CHAR)
00291 {
00292
00293
00294 }
00295 else
00296 ++_First;
00297
00298
00299 *_To = (byte_t) _3to4.get_0();
00300 return _First;
00301 }
00302 else
00303 _3to4.b64_2(_Char);
00304
00305
00306
00307
00308 while(++_First != _Last)
00309 if((_Char = _getCharType(*_First)) != _UNKNOWN_CHAR)
00310 break;
00311
00312 if(_First == _Last) {
00313
00314
00315 _St |= _IOS_EOFBIT;
00316
00317 return _First;
00318 }
00319
00320 if(_Char == _EQUAL_CHAR)
00321 {
00322
00323 _3to4.b64_3(0);
00324
00325
00326 *_To = (byte_t) _3to4.get_0();
00327 *_To = (byte_t) _3to4.get_1();
00328
00329 ++_First;
00330
00331 return _First;
00332 }
00333 else
00334 _3to4.b64_3(_Char);
00335
00336
00337
00338 *_To = (byte_t) _3to4.get_0();
00339 *_To = (byte_t) _3to4.get_1();
00340 *_To = (byte_t) _3to4.get_2();
00341
00342 ++_First;
00343
00344
00345 }
00346
00347 return (_First);
00348 }
00349
00350 protected:
00351
00352 int _getCharType(int _Ch) const
00353 {
00354 if(_base64Chars[62] == _Ch)
00355 return 62;
00356
00357 if(_base64Chars[63] == _Ch)
00358 return 63;
00359
00360 if((_base64Chars[0] <= _Ch) && (_base64Chars[25] >= _Ch))
00361 return _Ch - _base64Chars[0];
00362
00363 if((_base64Chars[26] <= _Ch) && (_base64Chars[51] >= _Ch))
00364 return _Ch - _base64Chars[26] + 26;
00365
00366 if((_base64Chars[52] <= _Ch) && (_base64Chars[61] >= _Ch))
00367 return _Ch - _base64Chars[52] + 52;
00368
00369 if(_Ch == _Tr::to_int_type('='))
00370 return _EQUAL_CHAR;
00371
00372 return _UNKNOWN_CHAR;
00373 }
00374
00375
00376 };
00377
00378
00379 #endif