~ubuntu-branches/ubuntu/maverick/notecase/maverick

« back to all changes in this revision

Viewing changes to src/lib/Base64.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Nathan Handler
  • Date: 2008-12-21 13:09:58 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20081221130958-0ri77h0x7j1dclkq
Tags: 1.9.8-0ubuntu1
New upstream release (LP: #307752)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
////////////////////////////////////////////////////////////////////////////
2
 
// NoteCase notes manager project <http://notecase.sf.net>
3
 
//
4
 
// This code is licensed under BSD license.See "license.txt" for more details.
5
 
//
6
 
// File: Base64 encoding/decoding
7
 
////////////////////////////////////////////////////////////////////////////
8
 
//
9
 
// Base64.cpp: implementation of the CBase64 class.
10
 
// Author: Wes Clyburn (clyburnw@enmu.edu)
11
 
//
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
 
//////////////////////////////////////////////////////////////////////
19
 
 
20
 
#include "Base64.h"
21
 
#include "debug.h"
22
 
#include <string.h>
23
 
 
24
 
// Static Member Initializers
25
 
//
26
 
 
27
 
// The 7-bit alphabet used to encode binary information
28
 
std::string CBase64::m_sBase64Alphabet =
29
 
 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
30
 
 
31
 
int CBase64::m_nMask[] = { 0, 1, 3, 7, 15, 31, 63, 127, 255 };
32
 
 
33
 
//////////////////////////////////////////////////////////////////////
34
 
// Construction/Destruction
35
 
//////////////////////////////////////////////////////////////////////
36
 
 
37
 
CBase64::CBase64()
38
 
{
39
 
}
40
 
 
41
 
CBase64::~CBase64()
42
 
{
43
 
}
44
 
 
45
 
// Matt Spaulding (1999/01/22)
46
 
std::string CBase64::Encode(const char *szEncoding, int nSize)
47
 
{
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("");
52
 
 
53
 
        char *sOutput = new char[nSize*2+1];  //lazy/safe calculation
54
 
        int nNumBits = 6;
55
 
        unsigned int nDigit;
56
 
        int pos=0, target=BYTES_PER_LINE, lp = 0;
57
 
        std::string result;
58
 
 
59
 
        m_szInput = szEncoding;
60
 
        m_nInputSize = nSize;
61
 
 
62
 
        m_nBitsRemaining = 0;
63
 
        nDigit = read_bits( nNumBits, &nNumBits, lp );
64
 
        while( nNumBits > 0 )
65
 
        {
66
 
                sOutput[pos++] = m_sBase64Alphabet[ (int)nDigit ];
67
 
                nDigit = read_bits( nNumBits, &nNumBits, lp );
68
 
 
69
 
                if(pos==target)
70
 
                {
71
 
                        sOutput[pos++] = '\r';
72
 
                        sOutput[pos++] = '\n';
73
 
                        target=pos+BYTES_PER_LINE;       // Not including CR/LF, already handled
74
 
                }
75
 
        }
76
 
 
77
 
        sOutput[pos]=0;
78
 
        result=sOutput;
79
 
        delete [] sOutput;
80
 
 
81
 
        return result;
82
 
}
83
 
 
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)
88
 
{
89
 
        std::string sInput;
90
 
        int c, lp =0;
91
 
        int nDigit;
92
 
        int nDecode[ 256 ];
93
 
 
94
 
        ASSERT( szDecoding != NULL );
95
 
        ASSERT( szOutput != NULL );
96
 
        if( szOutput == NULL )
97
 
                return 0;
98
 
        if( szDecoding == NULL )
99
 
                return 0;
100
 
        sInput = szDecoding;
101
 
        if( sInput.size() == 0 )
102
 
                return 0;
103
 
 
104
 
        // Build Decode Table
105
 
        //
106
 
        int i;
107
 
        for( i = 0; i < 256; i++ )
108
 
                nDecode[i] = -2; // Illegal digit
109
 
        for( i=0; i < 64; i++ )
110
 
        {
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
115
 
        }
116
 
 
117
 
        // Clear the output buffer
118
 
        memset( szOutput, 0, sInput.size() + 1 );
119
 
 
120
 
        m_lBitStorage = 0;              //(IVO) somebody failed to initialize
121
 
        m_nBitsRemaining =0;    //(IVO)
122
 
 
123
 
        // Decode the Input
124
 
        //
125
 
        int nSize = sInput.size();
126
 
        for( lp = 0, i = 0; lp < nSize; lp++ )
127
 
        {
128
 
                c = sInput[ lp ];
129
 
 
130
 
                //skip new lines
131
 
                if(c == '\r' || c == '\n')
132
 
                        continue;
133
 
 
134
 
                nDigit = nDecode[ c & 0x7F ];
135
 
                if( nDigit < -1 )
136
 
                {
137
 
                        return 0;
138
 
                }
139
 
                else if( nDigit >= 0 )
140
 
                        // i (index into output) is incremented by write_bits()
141
 
                        write_bits( nDigit & 0x3F, 6, szOutput, i );
142
 
    }
143
 
        return i;
144
 
}
145
 
 
146
 
 
147
 
unsigned int CBase64::read_bits(int nNumBits, int * pBitsRead, int& lp)
148
 
{
149
 
    unsigned long lScratch;
150
 
    while( ( m_nBitsRemaining < nNumBits ) &&
151
 
                   ( lp < m_nInputSize ) )
152
 
        {
153
 
                int c = m_szInput[ lp++ ];
154
 
        m_lBitStorage <<= 8;
155
 
        m_lBitStorage |= (c & 0xff);
156
 
                m_nBitsRemaining += 8;
157
 
    }
158
 
    if( m_nBitsRemaining < nNumBits )
159
 
        {
160
 
                lScratch = m_lBitStorage << ( nNumBits - m_nBitsRemaining );
161
 
                *pBitsRead = m_nBitsRemaining;
162
 
                m_nBitsRemaining = 0;
163
 
    }
164
 
        else
165
 
        {
166
 
                lScratch = m_lBitStorage >> ( m_nBitsRemaining - nNumBits );
167
 
                *pBitsRead = nNumBits;
168
 
                m_nBitsRemaining -= nNumBits;
169
 
    }
170
 
    return (unsigned int)lScratch & m_nMask[nNumBits];
171
 
}
172
 
 
173
 
void CBase64::write_bits(unsigned int nBits,
174
 
                                                 int nNumBits,
175
 
                                                 char *szOutput,
176
 
                                                 int& i)
177
 
{
178
 
        unsigned int nScratch;
179
 
 
180
 
        m_lBitStorage = (m_lBitStorage << nNumBits) | nBits;
181
 
        m_nBitsRemaining += nNumBits;
182
 
        while( m_nBitsRemaining > 7 )
183
 
        {
184
 
                nScratch = m_lBitStorage >> (m_nBitsRemaining - 8);
185
 
                szOutput[ i++ ] = nScratch & 0xFF;
186
 
                m_nBitsRemaining -= 8;
187
 
        }
188
 
}
 
1
////////////////////////////////////////////////////////////////////////////
 
2
// NoteCase notes manager project <http://notecase.sf.net>
 
3
//
 
4
// This code is licensed under BSD license.See "license.txt" for more details.
 
5
//
 
6
// File: Base64 encoding/decoding
 
7
////////////////////////////////////////////////////////////////////////////
 
8
//
 
9
// Base64.cpp: implementation of the CBase64 class.
 
10
// Author: Wes Clyburn (clyburnw@enmu.edu)
 
11
//
 
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
//////////////////////////////////////////////////////////////////////
 
19
 
 
20
#include "Base64.h"
 
21
#include "debug.h"
 
22
#include <string.h>
 
23
 
 
24
// Static Member Initializers
 
25
//
 
26
 
 
27
// The 7-bit alphabet used to encode binary information
 
28
std::string CBase64::m_sBase64Alphabet =
 
29
 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 
30
 
 
31
int CBase64::m_nMask[] = { 0, 1, 3, 7, 15, 31, 63, 127, 255 };
 
32
 
 
33
//////////////////////////////////////////////////////////////////////
 
34
// Construction/Destruction
 
35
//////////////////////////////////////////////////////////////////////
 
36
 
 
37
CBase64::CBase64()
 
38
{
 
39
}
 
40
 
 
41
CBase64::~CBase64()
 
42
{
 
43
}
 
44
 
 
45
// Matt Spaulding (1999/01/22)
 
46
std::string CBase64::Encode(const char *szEncoding, int nSize)
 
47
{
 
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("");
 
52
 
 
53
        char *sOutput = new char[nSize*2+1];  //lazy/safe calculation
 
54
        int nNumBits = 6;
 
55
        unsigned int nDigit;
 
56
        int pos=0, target=BYTES_PER_LINE, lp = 0;
 
57
        std::string result;
 
58
 
 
59
        m_szInput = szEncoding;
 
60
        m_nInputSize = nSize;
 
61
 
 
62
        m_nBitsRemaining = 0;
 
63
        nDigit = read_bits( nNumBits, &nNumBits, lp );
 
64
        while( nNumBits > 0 )
 
65
        {
 
66
                sOutput[pos++] = m_sBase64Alphabet[ (int)nDigit ];
 
67
                nDigit = read_bits( nNumBits, &nNumBits, lp );
 
68
 
 
69
                if(pos==target)
 
70
                {
 
71
                        sOutput[pos++] = '\r';
 
72
                        sOutput[pos++] = '\n';
 
73
                        target=pos+BYTES_PER_LINE;       // Not including CR/LF, already handled
 
74
                }
 
75
        }
 
76
 
 
77
        sOutput[pos]=0;
 
78
        result=sOutput;
 
79
        delete [] sOutput;
 
80
 
 
81
        return result;
 
82
}
 
83
 
 
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)
 
88
{
 
89
        std::string sInput;
 
90
        int c, lp =0;
 
91
        int nDigit;
 
92
        int nDecode[ 256 ];
 
93
 
 
94
        ASSERT( szDecoding != NULL );
 
95
        ASSERT( szOutput != NULL );
 
96
        if( szOutput == NULL )
 
97
                return 0;
 
98
        if( szDecoding == NULL )
 
99
                return 0;
 
100
        sInput = szDecoding;
 
101
        if( sInput.size() == 0 )
 
102
                return 0;
 
103
 
 
104
        // Build Decode Table
 
105
        //
 
106
        int i;
 
107
        for( i = 0; i < 256; i++ )
 
108
                nDecode[i] = -2; // Illegal digit
 
109
        for( i=0; i < 64; i++ )
 
110
        {
 
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
 
115
        }
 
116
 
 
117
        // Clear the output buffer
 
118
        memset( szOutput, 0, sInput.size() + 1 );
 
119
 
 
120
        m_lBitStorage = 0;              //(IVO) somebody failed to initialize
 
121
        m_nBitsRemaining =0;    //(IVO)
 
122
 
 
123
        // Decode the Input
 
124
        //
 
125
        int nSize = sInput.size();
 
126
        for( lp = 0, i = 0; lp < nSize; lp++ )
 
127
        {
 
128
                c = sInput[ lp ];
 
129
 
 
130
                //skip new lines
 
131
                if(c == '\r' || c == '\n')
 
132
                        continue;
 
133
 
 
134
                nDigit = nDecode[ c & 0x7F ];
 
135
                if( nDigit < -1 )
 
136
                {
 
137
                        return 0;
 
138
                }
 
139
                else if( nDigit >= 0 )
 
140
                        // i (index into output) is incremented by write_bits()
 
141
                        write_bits( nDigit & 0x3F, 6, szOutput, i );
 
142
    }
 
143
        return i;
 
144
}
 
145
 
 
146
 
 
147
unsigned int CBase64::read_bits(int nNumBits, int * pBitsRead, int& lp)
 
148
{
 
149
    unsigned long lScratch;
 
150
    while( ( m_nBitsRemaining < nNumBits ) &&
 
151
                   ( lp < m_nInputSize ) )
 
152
        {
 
153
                int c = m_szInput[ lp++ ];
 
154
        m_lBitStorage <<= 8;
 
155
        m_lBitStorage |= (c & 0xff);
 
156
                m_nBitsRemaining += 8;
 
157
    }
 
158
    if( m_nBitsRemaining < nNumBits )
 
159
        {
 
160
                lScratch = m_lBitStorage << ( nNumBits - m_nBitsRemaining );
 
161
                *pBitsRead = m_nBitsRemaining;
 
162
                m_nBitsRemaining = 0;
 
163
    }
 
164
        else
 
165
        {
 
166
                lScratch = m_lBitStorage >> ( m_nBitsRemaining - nNumBits );
 
167
                *pBitsRead = nNumBits;
 
168
                m_nBitsRemaining -= nNumBits;
 
169
    }
 
170
    return (unsigned int)lScratch & m_nMask[nNumBits];
 
171
}
 
172
 
 
173
void CBase64::write_bits(unsigned int nBits,
 
174
                                                 int nNumBits,
 
175
                                                 char *szOutput,
 
176
                                                 int& i)
 
177
{
 
178
        unsigned int nScratch;
 
179
 
 
180
        m_lBitStorage = (m_lBitStorage << nNumBits) | nBits;
 
181
        m_nBitsRemaining += nNumBits;
 
182
        while( m_nBitsRemaining > 7 )
 
183
        {
 
184
                nScratch = m_lBitStorage >> (m_nBitsRemaining - 8);
 
185
                szOutput[ i++ ] = nScratch & 0xFF;
 
186
                m_nBitsRemaining -= 8;
 
187
        }
 
188
}