~ubuntu-branches/debian/sid/libdc0/sid

« back to all changes in this revision

Viewing changes to dclib/core/cbase64.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Pasi Savilaakso
  • Date: 2004-06-05 23:01:37 UTC
  • Revision ID: james.westby@ubuntu.com-20040605230137-2ty5g6rcfyguk4et
Tags: upstream-0.3.2
Import upstream version 0.3.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
                          cbase64.cpp  -  description
 
3
                             -------------------
 
4
    begin                : Tue Jul 09 2002
 
5
    copyright            : (C) 2002-2003 by Mathias K�ster
 
6
    email                : mathen@users.berlios.de
 
7
 ***************************************************************************/
 
8
 
 
9
/***************************************************************************
 
10
 *                                                                         *
 
11
 *   This program is free software; you can redistribute it and/or modify  *
 
12
 *   it under the terms of the GNU General Public License as published by  *
 
13
 *   the Free Software Foundation; either version 2 of the License, or     *
 
14
 *   (at your option) any later version.                                   *
 
15
 *                                                                         *
 
16
 ***************************************************************************/
 
17
 
 
18
#include <stdio.h>
 
19
#include <stdlib.h>
 
20
 
 
21
#include <dclib/core/cbytearray.h>
 
22
 
 
23
#include "cbase64.h"
 
24
 
 
25
// original from mutt
 
26
 
 
27
static int Index_64[128] = {
 
28
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
 
29
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
 
30
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, 63,-1,-1,-1,
 
31
52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1,-1,-1,-1,
 
32
-1, 0, 1, 2,  3, 4, 5, 6,  7, 8, 9,10, 11,12,13,14,
 
33
15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1,
 
34
-1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
 
35
41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1,
 
36
};
 
37
 
 
38
static char B64Chars[64] = {
 
39
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
 
40
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
 
41
'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
 
42
't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
 
43
'8', '9', '+', ','
 
44
};
 
45
 
 
46
#define base64val(c) Index_64[(unsigned int)(c)]
 
47
#define base64chars(c) B64Chars[(unsigned int)(c&0x3F)]
 
48
 
 
49
/** */
 
50
CBase64::CBase64()
 
51
{
 
52
}
 
53
 
 
54
/** */
 
55
CBase64::~CBase64()
 
56
{
 
57
}
 
58
 
 
59
#define BAD     -1
 
60
 
 
61
/** */
 
62
CString CBase64::Encode( CString string )
 
63
{
 
64
        CString outs = "";
 
65
        CByteArray in,out;
 
66
 
 
67
        in.Append(string.Data(),string.Length()+1);
 
68
 
 
69
        Encode(&out,&in);
 
70
 
 
71
        outs.Set((const char*)out.Data(),out.Size());
 
72
 
 
73
        return outs;
 
74
}
 
75
 
 
76
/* raw bytes to null-terminated base 64 string */
 
77
void CBase64::Encode(  CByteArray * dst, CByteArray * src )
 
78
{
 
79
        unsigned char c;
 
80
        unsigned char *current = src->Data();
 
81
        size_t len = src->Size();
 
82
 
 
83
        while (len >= 3)
 
84
        {
 
85
                c = base64chars(current[0] >> 2);
 
86
                dst->Append( &c, 1);
 
87
                c = base64chars(((current[0] & 0x03) << 4) | (current[1] >> 4));
 
88
                dst->Append( &c, 1);
 
89
                c = base64chars(((current[1] & 0x0f) << 2) | (current[2] >> 6));
 
90
                dst->Append( &c, 1);
 
91
                c = base64chars(current[2] & 0x3f);
 
92
                dst->Append( &c, 1);
 
93
                len     -= 3;
 
94
                current += 3;
 
95
        }
 
96
 
 
97
        /* clean up remainder */
 
98
        if (len > 0)
 
99
        {
 
100
                c = base64chars(current[0] >> 2);
 
101
                dst->Append(&c,1);
 
102
                if ( len > 1 )
 
103
                {
 
104
                        c = base64chars(((current[0] & 0x03) << 4) | (current[1] >> 4));
 
105
                        dst->Append(&c,1);
 
106
                        c = base64chars((current[1] & 0x0f) << 2);
 
107
                        dst->Append(&c,1);
 
108
                        c = '=';
 
109
                        dst->Append(&c,1);
 
110
                }
 
111
                else
 
112
                {
 
113
                        c = base64chars((current[0] & 0x03) << 4);
 
114
                        dst->Append(&c,1);
 
115
                        c = '=';
 
116
                        dst->Append(&c,1);
 
117
                        c = '=';
 
118
                        dst->Append(&c,1);
 
119
                }
 
120
        }
 
121
}
 
122
 
 
123
/** */
 
124
int CBase64::Decode( CByteArray * dst, CString * string )
 
125
{
 
126
        CByteArray in;
 
127
 
 
128
        in.Append(string->Data(),string->Length());
 
129
 
 
130
        return Decode(dst,&in);
 
131
}
 
132
 
 
133
/* Convert '\0'-terminated base 64 string to raw bytes.
 
134
 * Returns length of returned buffer, or -1 on error */
 
135
int CBase64::Decode( CByteArray * dst, CByteArray * src )
 
136
{
 
137
        unsigned char *current,*result;
 
138
        unsigned char c;
 
139
        int ch;
 
140
        unsigned long i=0,j=0;
 
141
 
 
142
        if ( (!dst) || (!src) )
 
143
                return -1;
 
144
 
 
145
        if ( (src->Size() % 4) != 0 )
 
146
                return -1;
 
147
 
 
148
        dst->SetSize(0);
 
149
 
 
150
        current = src->Data();
 
151
        result  = dst->Data();
 
152
 
 
153
        for(i=0;i<src->Size();i++)
 
154
        {
 
155
                ch = (current[i]&0x7F);
 
156
 
 
157
                if (ch == '=') break;
 
158
 
 
159
                if (ch == ' ') ch = '+'; 
 
160
 
 
161
                ch = Index_64[ch];
 
162
 
 
163
                if (ch < 0) return -1;
 
164
 
 
165
                switch(i % 4)
 
166
                {
 
167
                        case 0:
 
168
                                c = (unsigned char)((ch << 2) & 0xFF);
 
169
                                dst->Append(&c,1);
 
170
                                break;
 
171
                        case 1:
 
172
                                dst->Data()[j] |= ((ch >> 4) & 0xFF);
 
173
                                j++;
 
174
                                if(current[i+1]!='=')
 
175
                                {
 
176
                                        c = (unsigned char)((ch << 4) & 0xFF);
 
177
                                        dst->Append(&c,1);
 
178
                                }
 
179
                                break;
 
180
                        case 2:
 
181
                                dst->Data()[j] |= ((ch >> 2) & 0x0f);
 
182
                                j++;
 
183
                                if(current[i+1]!='=')
 
184
                                {
 
185
                                        c = (unsigned char)((ch << 6) & 0xFF);
 
186
                                        dst->Append(&c,1);
 
187
                                }
 
188
                                break;
 
189
                        case 3:
 
190
                                dst->Data()[j] |= ch;
 
191
                                j++;
 
192
                                break;
 
193
                }
 
194
        }
 
195
 
 
196
        return j;
 
197
}