1
////////////////////////////////////////////////////////////////////////////
2
// NoteCase notes manager project <http://notecase.sf.net>
4
// This code is licensed under BSD license.See "license.txt" for more details.
6
// File: Base64 encoding/decoding
7
////////////////////////////////////////////////////////////////////////////
9
// Base64.cpp: implementation of the CBase64 class.
10
// Author: Wes Clyburn (clyburnw@enmu.edu)
12
// This code was practically stolen from:
13
// Dr. Dobb's Journal, September 1995,
14
// "Mime and Internet Mail", by Tim Kientzle
15
//////////////////////////////////////////////////////////////////////
16
// WARNING: this class DOES NOT pad with '=' as per RFC 1521
17
// to the 4byte border (when encoding).
18
//////////////////////////////////////////////////////////////////////
24
// Static Member Initializers
27
// The 7-bit alphabet used to encode binary information
28
std::string CBase64::m_sBase64Alphabet =
29
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
31
int CBase64::m_nMask[] = { 0, 1, 3, 7, 15, 31, 63, 127, 255 };
33
//////////////////////////////////////////////////////////////////////
34
// Construction/Destruction
35
//////////////////////////////////////////////////////////////////////
45
// Matt Spaulding (1999/01/22)
46
std::string CBase64::Encode(const char *szEncoding, int nSize)
48
ASSERT( szEncoding != NULL );
49
ASSERT( nSize > 0 ); //don't send empty strings (or empty files)
50
if( szEncoding == NULL || 0 == nSize )
51
return std::string("");
53
char *sOutput = new char[nSize*2+1]; //lazy/safe calculation
56
int pos=0, target=BYTES_PER_LINE, lp = 0;
59
m_szInput = szEncoding;
63
nDigit = read_bits( nNumBits, &nNumBits, lp );
66
sOutput[pos++] = m_sBase64Alphabet[ (int)nDigit ];
67
nDigit = read_bits( nNumBits, &nNumBits, lp );
71
sOutput[pos++] = '\r';
72
sOutput[pos++] = '\n';
73
target=pos+BYTES_PER_LINE; // Not including CR/LF, already handled
84
// The size of the output buffer must not be less than
85
// 3/4 the size of the input buffer. For simplicity,
86
// make them the same size.
87
int CBase64::Decode(const char *szDecoding, char * szOutput)
94
ASSERT( szDecoding != NULL );
95
ASSERT( szOutput != NULL );
96
if( szOutput == NULL )
98
if( szDecoding == NULL )
101
if( sInput.size() == 0 )
104
// Build Decode Table
107
for( i = 0; i < 256; i++ )
108
nDecode[i] = -2; // Illegal digit
109
for( i=0; i < 64; i++ )
111
nDecode[ (int) m_sBase64Alphabet[ i ] ] = i;
112
nDecode[ m_sBase64Alphabet[ i ] | 0x80 ] = i; // Ignore 8th bit
113
nDecode[ (int)'=' ] = -1;
114
nDecode[ '=' | 0x80 ] = -1; // Ignore MIME padding char
117
// Clear the output buffer
118
memset( szOutput, 0, sInput.size() + 1 );
120
m_lBitStorage = 0; //(IVO) somebody failed to initialize
121
m_nBitsRemaining =0; //(IVO)
125
int nSize = sInput.size();
126
for( lp = 0, i = 0; lp < nSize; lp++ )
131
if(c == '\r' || c == '\n')
134
nDigit = nDecode[ c & 0x7F ];
139
else if( nDigit >= 0 )
140
// i (index into output) is incremented by write_bits()
141
write_bits( nDigit & 0x3F, 6, szOutput, i );
147
unsigned int CBase64::read_bits(int nNumBits, int * pBitsRead, int& lp)
149
unsigned long lScratch;
150
while( ( m_nBitsRemaining < nNumBits ) &&
151
( lp < m_nInputSize ) )
153
int c = m_szInput[ lp++ ];
155
m_lBitStorage |= (c & 0xff);
156
m_nBitsRemaining += 8;
158
if( m_nBitsRemaining < nNumBits )
160
lScratch = m_lBitStorage << ( nNumBits - m_nBitsRemaining );
161
*pBitsRead = m_nBitsRemaining;
162
m_nBitsRemaining = 0;
166
lScratch = m_lBitStorage >> ( m_nBitsRemaining - nNumBits );
167
*pBitsRead = nNumBits;
168
m_nBitsRemaining -= nNumBits;
170
return (unsigned int)lScratch & m_nMask[nNumBits];
173
void CBase64::write_bits(unsigned int nBits,
178
unsigned int nScratch;
180
m_lBitStorage = (m_lBitStorage << nNumBits) | nBits;
181
m_nBitsRemaining += nNumBits;
182
while( m_nBitsRemaining > 7 )
184
nScratch = m_lBitStorage >> (m_nBitsRemaining - 8);
185
szOutput[ i++ ] = nScratch & 0xFF;
186
m_nBitsRemaining -= 8;
1
////////////////////////////////////////////////////////////////////////////
2
// NoteCase notes manager project <http://notecase.sf.net>
4
// This code is licensed under BSD license.See "license.txt" for more details.
6
// File: Base64 encoding/decoding
7
////////////////////////////////////////////////////////////////////////////
9
// Base64.cpp: implementation of the CBase64 class.
10
// Author: Wes Clyburn (clyburnw@enmu.edu)
12
// This code was practically stolen from:
13
// Dr. Dobb's Journal, September 1995,
14
// "Mime and Internet Mail", by Tim Kientzle
15
//////////////////////////////////////////////////////////////////////
16
// WARNING: this class DOES NOT pad with '=' as per RFC 1521
17
// to the 4byte border (when encoding).
18
//////////////////////////////////////////////////////////////////////
24
// Static Member Initializers
27
// The 7-bit alphabet used to encode binary information
28
std::string CBase64::m_sBase64Alphabet =
29
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
31
int CBase64::m_nMask[] = { 0, 1, 3, 7, 15, 31, 63, 127, 255 };
33
//////////////////////////////////////////////////////////////////////
34
// Construction/Destruction
35
//////////////////////////////////////////////////////////////////////
45
// Matt Spaulding (1999/01/22)
46
std::string CBase64::Encode(const char *szEncoding, int nSize)
48
ASSERT( szEncoding != NULL );
49
ASSERT( nSize > 0 ); //don't send empty strings (or empty files)
50
if( szEncoding == NULL || 0 == nSize )
51
return std::string("");
53
char *sOutput = new char[nSize*2+1]; //lazy/safe calculation
56
int pos=0, target=BYTES_PER_LINE, lp = 0;
59
m_szInput = szEncoding;
63
nDigit = read_bits( nNumBits, &nNumBits, lp );
66
sOutput[pos++] = m_sBase64Alphabet[ (int)nDigit ];
67
nDigit = read_bits( nNumBits, &nNumBits, lp );
71
sOutput[pos++] = '\r';
72
sOutput[pos++] = '\n';
73
target=pos+BYTES_PER_LINE; // Not including CR/LF, already handled
84
// The size of the output buffer must not be less than
85
// 3/4 the size of the input buffer. For simplicity,
86
// make them the same size.
87
int CBase64::Decode(const char *szDecoding, char * szOutput)
94
ASSERT( szDecoding != NULL );
95
ASSERT( szOutput != NULL );
96
if( szOutput == NULL )
98
if( szDecoding == NULL )
101
if( sInput.size() == 0 )
104
// Build Decode Table
107
for( i = 0; i < 256; i++ )
108
nDecode[i] = -2; // Illegal digit
109
for( i=0; i < 64; i++ )
111
nDecode[ (int) m_sBase64Alphabet[ i ] ] = i;
112
nDecode[ m_sBase64Alphabet[ i ] | 0x80 ] = i; // Ignore 8th bit
113
nDecode[ (int)'=' ] = -1;
114
nDecode[ '=' | 0x80 ] = -1; // Ignore MIME padding char
117
// Clear the output buffer
118
memset( szOutput, 0, sInput.size() + 1 );
120
m_lBitStorage = 0; //(IVO) somebody failed to initialize
121
m_nBitsRemaining =0; //(IVO)
125
int nSize = sInput.size();
126
for( lp = 0, i = 0; lp < nSize; lp++ )
131
if(c == '\r' || c == '\n')
134
nDigit = nDecode[ c & 0x7F ];
139
else if( nDigit >= 0 )
140
// i (index into output) is incremented by write_bits()
141
write_bits( nDigit & 0x3F, 6, szOutput, i );
147
unsigned int CBase64::read_bits(int nNumBits, int * pBitsRead, int& lp)
149
unsigned long lScratch;
150
while( ( m_nBitsRemaining < nNumBits ) &&
151
( lp < m_nInputSize ) )
153
int c = m_szInput[ lp++ ];
155
m_lBitStorage |= (c & 0xff);
156
m_nBitsRemaining += 8;
158
if( m_nBitsRemaining < nNumBits )
160
lScratch = m_lBitStorage << ( nNumBits - m_nBitsRemaining );
161
*pBitsRead = m_nBitsRemaining;
162
m_nBitsRemaining = 0;
166
lScratch = m_lBitStorage >> ( m_nBitsRemaining - nNumBits );
167
*pBitsRead = nNumBits;
168
m_nBitsRemaining -= nNumBits;
170
return (unsigned int)lScratch & m_nMask[nNumBits];
173
void CBase64::write_bits(unsigned int nBits,
178
unsigned int nScratch;
180
m_lBitStorage = (m_lBitStorage << nNumBits) | nBits;
181
m_nBitsRemaining += nNumBits;
182
while( m_nBitsRemaining > 7 )
184
nScratch = m_lBitStorage >> (m_nBitsRemaining - 8);
185
szOutput[ i++ ] = nScratch & 0xFF;
186
m_nBitsRemaining -= 8;