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