1 // Base64.cpp: implementation of the CBase64 class.
\r
3 //////////////////////////////////////////////////////////////////////
\r
10 static char THIS_FILE[]=__FILE__;
\r
11 #define new DEBUG_NEW
\r
14 //////////////////////////////////////////////////////////////////////
\r
16 //////////////////////////////////////////////////////////////////////
\r
17 // Static Member Initializers
\r
20 // The 7-bit alphabet used to encode binary information
\r
21 const char m_sBase64Alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
\r
23 const int f_nMask[] = { 0, 1, 3, 7, 15, 31, 63, 127, 255 };
\r
28 m_nBitsRemaining = 0;
\r
37 CStringA CBase64::Encode( IN const char* szEncoding, IN int nSize )
\r
39 CStringA sOutput = "";
\r
44 ASSERT( szEncoding != NULL );
\r
45 if( szEncoding == NULL )
\r
47 m_szInput = szEncoding;
\r
48 m_nInputSize = nSize;
\r
50 m_nBitsRemaining = 0;
\r
51 nDigit = read_bits( nNumBits, &nNumBits, lp );
\r
52 while( nNumBits > 0 )
\r
54 sOutput += m_sBase64Alphabet[ (int)nDigit ];
\r
55 nDigit = read_bits( nNumBits, &nNumBits, lp );
\r
57 // Pad with '=' as per RFC 1521
\r
58 while( sOutput.GetLength() % 4 != 0 )
\r
65 // The size of the output buffer must not be less than
\r
66 // 3/4 the size of the input buffer. For simplicity,
\r
67 // make them the same size.
\r
68 // return : ½âÂëºóÊý¾Ý³¤¶È
\r
69 int CBase64::Decode ( IN const char* szDecoding, char* szOutput )
\r
76 ASSERT( szDecoding != NULL );
\r
77 ASSERT( szOutput != NULL );
\r
78 if( szOutput == NULL )
\r
80 if( szDecoding == NULL )
\r
82 sInput = szDecoding;
\r
83 if( sInput.GetLength() == 0 )
\r
86 // Build Decode Table
\r
89 for( i = 0; i < 256; i++ )
\r
90 nDecode[i] = -2; // Illegal digit
\r
91 for( i=0; i < 64; i++ )
\r
93 nDecode[ m_sBase64Alphabet[ i ] ] = i;
\r
94 nDecode[ m_sBase64Alphabet[ i ] | 0x80 ] = i; // Ignore 8th bit
\r
95 nDecode[ '=' ] = -1;
\r
96 nDecode[ '=' | 0x80 ] = -1; // Ignore MIME padding char
\r
99 // Clear the output buffer
\r
100 memset( szOutput, 0, sInput.GetLength() + 1 );
\r
102 // Decode the Input
\r
104 for( lp = 0, i = 0; lp < sInput.GetLength(); lp++ )
\r
107 nDigit = nDecode[ c & 0x7F ];
\r
112 else if( nDigit >= 0 )
\r
113 // i (index into output) is incremented by write_bits()
\r
114 write_bits( nDigit & 0x3F, 6, szOutput, i );
\r
119 UINT CBase64::read_bits(int nNumBits, int * pBitsRead, int& lp)
\r
122 while( ( m_nBitsRemaining < nNumBits ) &&
\r
123 ( lp < m_nInputSize ) )
\r
125 int c = m_szInput[ lp++ ];
\r
126 m_lBitStorage <<= 8;
\r
127 m_lBitStorage |= (c & 0xff);
\r
128 m_nBitsRemaining += 8;
\r
130 if( m_nBitsRemaining < nNumBits )
\r
132 lScratch = m_lBitStorage << ( nNumBits - m_nBitsRemaining );
\r
133 *pBitsRead = m_nBitsRemaining;
\r
134 m_nBitsRemaining = 0;
\r
138 lScratch = m_lBitStorage >> ( m_nBitsRemaining - nNumBits );
\r
139 *pBitsRead = nNumBits;
\r
140 m_nBitsRemaining -= nNumBits;
\r
142 return (UINT)lScratch & f_nMask[nNumBits];
\r
146 void CBase64::write_bits(UINT nBits,
\r
153 m_lBitStorage = (m_lBitStorage << nNumBits) | nBits;
\r
154 m_nBitsRemaining += nNumBits;
\r
155 while( m_nBitsRemaining > 7 )
\r
157 nScratch = m_lBitStorage >> (m_nBitsRemaining - 8);
\r
158 szOutput[ i++ ] = nScratch & 0xFF;
\r
159 m_nBitsRemaining -= 8;
\r