1 /////////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/common/base64.cpp 
   3 // Purpose:     implementation of BASE64 encoding/decoding functions 
   4 // Author:      Charles Reimers, Vadim Zeitlin 
   7 // Licence:     wxWindows licence 
   8 /////////////////////////////////////////////////////////////////////////////// 
  10 #include "wx/wxprec.h" 
  14 #include "wx/base64.h" 
  17 wxBase64Encode(char *dst
, size_t dstLen
, const void *src_
, size_t srcLen
) 
  19     wxCHECK_MSG( src_
, wxCONV_FAILED
, _T("NULL input buffer") ); 
  21     const unsigned char *src 
= wx_static_cast(const unsigned char *, src_
); 
  23     static const char b64
[] = 
  24         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 
  29     // encode blocks of 3 bytes into 4 base64 characters 
  30     for ( ; srcLen 
>= 3; srcLen 
-= 3, src 
+= 3 ) 
  35             if ( encLen 
> dstLen 
) 
  38             *dst
++ = b64
[src
[0] >> 2]; 
  39             *dst
++ = b64
[((src
[0] & 0x03) << 4) | ((src
[1] & 0xf0) >> 4)]; 
  40             *dst
++ = b64
[((src
[1] & 0x0f) << 2) | ((src
[2] & 0xc0) >> 6)]; 
  41             *dst
++ = b64
[src
[2] & 0x3f]; 
  45     // finish with the remaining characters 
  51             if ( encLen 
> dstLen 
) 
  54             // we have definitely one and maybe two bytes remaining 
  55             unsigned char next 
= srcLen 
== 2 ? src
[1] : 0; 
  56             *dst
++ = b64
[src
[0] >> 2]; 
  57             *dst
++ = b64
[((src
[0] & 0x03) << 4) | ((next 
& 0xf0) >> 4)]; 
  58             *dst
++ = srcLen 
== 2 ? b64
[((next 
& 0x0f) << 2)] : '='; 
  67 wxBase64Decode(void *dst_
, size_t dstLen
, 
  68                const char *src
, size_t srcLen
, 
  69                wxBase64DecodeMode mode
, 
  72     wxCHECK_MSG( src
, wxCONV_FAILED
, _T("NULL input buffer") ); 
  74     unsigned char *dst 
= wx_static_cast(unsigned char *, dst_
); 
  78     if ( srcLen 
== wxNO_LEN 
) 
  81     // this table contains the values, in base 64, of all valid characters and 
  82     // special values WSP or INV for white space and invalid characters 
  83     // respectively as well as a special PAD value for '=' 
  91     static const unsigned char decode
[256] = 
  93         WSP
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,WSP
,WSP
,INV
,WSP
,WSP
,INV
,INV
, 
  94         INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
, 
  95         WSP
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,076,INV
,INV
,INV
,077, 
  96         064,065,066,067,070,071,072,073,074,075,INV
,INV
,INV
,PAD
,INV
,INV
, 
  97         INV
,000,001,002,003,004,005,006,007,010,011,012,013,014,015,016, 
  98         017,020,021,022,023,024,025,026,027,030,031,INV
,INV
,INV
,INV
,INV
, 
  99         INV
,032,033,034,035,036,037,040,041,042,043,044,045,046,047,050, 
 100         051,052,053,054,055,056,057,060,061,062,063,INV
,INV
,INV
,INV
,INV
, 
 101         INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
, 
 102         INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
, 
 103         INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
, 
 104         INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
, 
 105         INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
, 
 106         INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
, 
 107         INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
, 
 108         INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
,INV
, 
 111     // we decode input by groups of 4 characters but things are complicated by 
 112     // the fact that there can be whitespace and other junk in it too so keep 
 113     // record of where exactly we're inside the current quartet in this var 
 115     unsigned char in
[4];                    // current quartet 
 116     bool end 
= false;                       // set when we find padding 
 117     size_t padLen 
= 0;                      // length lost to padding 
 119     for ( p 
= src
; srcLen
; p
++, srcLen
-- ) 
 121         const unsigned char c 
= decode
[wx_static_cast(unsigned char, *p
)]; 
 125                 if ( mode 
== wxBase64DecodeMode_SkipWS 
) 
 130                 if ( mode 
== wxBase64DecodeMode_Relaxed 
) 
 133                 // force the loop to stop and an error to be returned 
 139                 // set the flag telling us that we're past the end now 
 142                 // there can be either a single '=' at the end of a quartet or 
 143                 // "==" in positions 2 and 3 
 149                 else if ( (n 
== 2) && (--srcLen 
&& *++p 
== '=') ) 
 155                 else // invalid padding 
 157                     // force the loop terminate with an error 
 166                     // nothing is allowed after the end so provoke error return 
 177             // got entire block, decode 
 178             decLen 
+= 3 - padLen
; 
 181                 if ( decLen 
> dstLen 
) 
 182                     return wxCONV_FAILED
; 
 184                 // undo the bit shifting done during encoding 
 185                 *dst
++ = in
[0] << 2 | in
[1] >> 4; 
 186                 *dst
++ = in
[1] << 4 | in
[2] >> 2; 
 187                 *dst
++ = in
[2] << 6 | in
[3]; 
 199         return wxCONV_FAILED
; 
 205 wxMemoryBuffer 
wxBase64Decode(const char *src
, 
 207                               wxBase64DecodeMode mode
, 
 211     wxCHECK_MSG( src
, buf
, _T("NULL input buffer") ); 
 213     if ( srcLen 
== wxNO_LEN 
) 
 214         srcLen 
= strlen(src
); 
 216     size_t len 
= wxBase64DecodedSize(srcLen
); 
 217     len 
= wxBase64Decode(buf
.GetWriteBuf(len
), len
, src
, srcLen
, mode
, posErr
); 
 218     if ( len 
== wxCONV_FAILED 
) 
 226 #endif // wxUSE_BASE64