1 /* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13 * express or implied.
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
17 */
18 #ifndef BASE64_CODEC_H_INCLUDED
19 #include "base64_codec.h"
20 #endif
21
22
PVBase64Codec()23 OSCL_EXPORT_REF PVBase64Codec::PVBase64Codec()
24 {
25 int32 i;
26 //encoder table
27 {
28 for (i = 0; i < 9; i++)
29 {
30 etable[i] = OSCL_STATIC_CAST(uint8, 'A' + i);
31 etable[i+9] = OSCL_STATIC_CAST(uint8, 'J' + i);
32 etable[26+i] = OSCL_STATIC_CAST(uint8, 'a' + i);
33 etable[26+i+9] = OSCL_STATIC_CAST(uint8, 'j' + i);
34 }
35 for (i = 0; i < 8; i++)
36 {
37 etable[i+18] = OSCL_STATIC_CAST(uint8, 'S' + i);
38 etable[26+i+18] = OSCL_STATIC_CAST(uint8, 's' + i);
39 }
40 for (i = 0; i < 10; i++)
41 {
42 etable[52+i] = OSCL_STATIC_CAST(uint8, '0' + i);
43 }
44 etable[62] = '+';
45 etable[63] = '/';
46 }
47
48 //deocder table
49 for (i = 0; i < 255; i++)
50 {
51 dtable[i] = 0x80;
52 }
53 for (i = 'A'; i <= 'I'; i++)
54 {
55 dtable[i] = OSCL_STATIC_CAST(uint8, 0 + (i - 'A'));
56 }
57 for (i = 'J'; i <= 'R'; i++)
58 {
59 dtable[i] = OSCL_STATIC_CAST(uint8, 9 + (i - 'J'));
60 }
61 for (i = 'S'; i <= 'Z'; i++)
62 {
63 dtable[i] = OSCL_STATIC_CAST(uint8, 18 + (i - 'S'));
64 }
65 for (i = 'a'; i <= 'i'; i++)
66 {
67 dtable[i] = OSCL_STATIC_CAST(uint8, 26 + (i - 'a'));
68 }
69 for (i = 'j'; i <= 'r'; i++)
70 {
71 dtable[i] = OSCL_STATIC_CAST(uint8, 35 + (i - 'j'));
72 }
73 for (i = 's'; i <= 'z'; i++)
74 {
75 dtable[i] = OSCL_STATIC_CAST(uint8, 44 + (i - 's'));
76 }
77 for (i = '0'; i <= '9'; i++)
78 {
79 dtable[i] = OSCL_STATIC_CAST(uint8, 52 + (i - '0'));
80 }
81 dtable[(uint16)'+'] = 62;
82 dtable[(uint16)'/'] = 63;
83 dtable[(uint16)'='] = 0;
84 }
85
Decode(uint8 * aInBuf,uint32 aInBufLen,uint8 * aOutBuf,uint32 & aOutBufLen,uint32 aMaxOutBufLen)86 bool PVBase64Codec::Decode(uint8* aInBuf, uint32 aInBufLen,
87 uint8* aOutBuf, uint32& aOutBufLen, uint32 aMaxOutBufLen)
88 {
89 oscl_memset(aOutBuf, 0, aMaxOutBufLen);
90 aOutBufLen = 0;
91
92 uint32 read_count = 0;
93 uint32 write_count = 0;
94 while (read_count < aInBufLen)
95 {
96 uint8 a[4], b[4], o[3];
97
98 int i;
99 for (i = 0; i < 4; i++)
100 {
101 uint8 c = *(aInBuf++);
102 read_count++;
103
104 if (read_count > aInBufLen)
105 {
106 //Input incomplete
107 return false;
108 }
109 if (dtable[(uint16)c]&0x80)
110 {
111 //Illegal character in
112 //return false;
113 i--;
114 continue;
115 }
116 a[i] = (uint8)c;
117 b[i] = (uint8)dtable[(uint16)c];
118 }
119 o[0] = OSCL_STATIC_CAST(uint8, (b[0] << 2) | (b[1] >> 4));
120 o[1] = OSCL_STATIC_CAST(uint8, (b[1] << 4) | (b[2] >> 2));
121 o[2] = OSCL_STATIC_CAST(uint8, (b[2] << 6) | b[3]);
122 i = a[2] == '=' ? 1 : (a[3] == '=' ? 2 : 3);
123 oscl_memcpy(aOutBuf, o, i);
124 aOutBuf += i;
125 write_count += i;
126 if (write_count > aMaxOutBufLen)
127 {
128 return false;
129 }
130 if (i < 3)
131 {
132 break;
133 }
134 }
135 aOutBufLen = write_count;
136 return true;
137 }
138
Encode(uint8 * aInBuf,uint32 aInBufLen,uint8 * aOutBuf,uint32 & aOutBufLen,uint32 aMaxOutBufLen)139 OSCL_EXPORT_REF bool PVBase64Codec::Encode(uint8* aInBuf, uint32 aInBufLen,
140 uint8* aOutBuf, uint32& aOutBufLen, uint32 aMaxOutBufLen)
141 {
142 int i;
143 uint32 read_count = 0;
144 uint32 write_count = 0;
145 while (read_count < aInBufLen)
146 {
147 uint8 igroup[3], ogroup[4];
148 igroup[0] = igroup[1] = igroup[2] = 0;
149 int n;
150 for (n = 0; n < 3; n++)
151 {
152 uint8 c = *(aInBuf++);
153 read_count++;
154 if (read_count > aInBufLen)
155 {
156 //Input incomplete
157 //return false;
158 break;
159 }
160 igroup[n] = (uint8) c;
161 }
162 if (n > 0)
163 {
164 ogroup[0] = etable [igroup[0] >> 2];
165 ogroup[1] = etable [((igroup[0] & 3) << 4) | (igroup[1] >> 4)];
166 ogroup[2] = etable [((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)];
167 ogroup[3] = etable [igroup[2] & 0x3F];
168 /* Replace characters in output stream with �=� pad
169 characters if fewer than three characters were read from
170 the end of the input stream. */
171 if (n < 3)
172 {
173 ogroup[3] = '=';
174 if (n < 2)
175 {
176 ogroup[2] = '=';
177 }
178 }
179 for (i = 0; i < 4; i++)
180 {
181 aOutBuf[write_count] = ogroup[i];
182 write_count++;
183 if (write_count > aMaxOutBufLen)
184 {
185 return false;
186 }
187 }
188 }
189 }
190 aOutBufLen = write_count;
191 return true;
192 }
193
194
195