KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > geronimo > util > encoders > Base64Encoder


1 /**
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18 package org.apache.geronimo.util.encoders;
19
20 import java.io.IOException JavaDoc;
21 import java.io.OutputStream JavaDoc;
22
23 public class Base64Encoder
24     implements Encoder
25 {
26     protected final byte[] encodingTable =
27         {
28             (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G',
29             (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N',
30             (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U',
31             (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z',
32             (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g',
33             (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n',
34             (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u',
35             (byte)'v',
36             (byte)'w', (byte)'x', (byte)'y', (byte)'z',
37             (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6',
38             (byte)'7', (byte)'8', (byte)'9',
39             (byte)'+', (byte)'/'
40         };
41
42     protected byte padding = (byte)'=';
43
44     /*
45      * set up the decoding table.
46      */

47     protected final byte[] decodingTable = new byte[128];
48
49     protected void initialiseDecodingTable()
50     {
51         for (int i = 0; i < encodingTable.length; i++)
52         {
53             decodingTable[encodingTable[i]] = (byte)i;
54         }
55     }
56
57     public Base64Encoder()
58     {
59         initialiseDecodingTable();
60     }
61
62     /**
63      * encode the input data producing a base 64 output stream.
64      *
65      * @return the number of bytes produced.
66      */

67     public int encode(
68         byte[] data,
69         int off,
70         int length,
71         OutputStream JavaDoc out)
72         throws IOException JavaDoc
73     {
74         int modulus = length % 3;
75         int dataLength = (length - modulus);
76         int a1, a2, a3;
77
78         for (int i = off; i < off + dataLength; i += 3)
79         {
80             a1 = data[i] & 0xff;
81             a2 = data[i + 1] & 0xff;
82             a3 = data[i + 2] & 0xff;
83
84             out.write(encodingTable[(a1 >>> 2) & 0x3f]);
85             out.write(encodingTable[((a1 << 4) | (a2 >>> 4)) & 0x3f]);
86             out.write(encodingTable[((a2 << 2) | (a3 >>> 6)) & 0x3f]);
87             out.write(encodingTable[a3 & 0x3f]);
88         }
89
90         /*
91          * process the tail end.
92          */

93         int b1, b2, b3;
94         int d1, d2;
95
96         switch (modulus)
97         {
98         case 0: /* nothing left to do */
99             break;
100         case 1:
101             d1 = data[off + dataLength] & 0xff;
102             b1 = (d1 >>> 2) & 0x3f;
103             b2 = (d1 << 4) & 0x3f;
104
105             out.write(encodingTable[b1]);
106             out.write(encodingTable[b2]);
107             out.write(padding);
108             out.write(padding);
109             break;
110         case 2:
111             d1 = data[off + dataLength] & 0xff;
112             d2 = data[off + dataLength + 1] & 0xff;
113
114             b1 = (d1 >>> 2) & 0x3f;
115             b2 = ((d1 << 4) | (d2 >>> 4)) & 0x3f;
116             b3 = (d2 << 2) & 0x3f;
117
118             out.write(encodingTable[b1]);
119             out.write(encodingTable[b2]);
120             out.write(encodingTable[b3]);
121             out.write(padding);
122             break;
123         }
124
125         return (dataLength / 3) * 4 + ((modulus == 0) ? 0 : 4);
126     }
127
128     private boolean ignore(
129         char c)
130     {
131         return (c == '\n' || c =='\r' || c == '\t' || c == ' ');
132     }
133
134     /**
135      * decode the base 64 encoded byte data writing it to the given output stream,
136      * whitespace characters will be ignored.
137      *
138      * @return the number of bytes produced.
139      */

140     public int decode(
141         byte[] data,
142         int off,
143         int length,
144         OutputStream JavaDoc out)
145         throws IOException JavaDoc
146     {
147         byte[] bytes;
148         byte b1, b2, b3, b4;
149         int outLen = 0;
150
151         int end = off + length;
152
153         while (end > 0)
154         {
155             if (!ignore((char)data[end - 1]))
156             {
157                 break;
158             }
159
160             end--;
161         }
162
163         int i = off;
164         int finish = end - 4;
165
166         while (i < finish)
167         {
168             while ((i < finish) && ignore((char)data[i]))
169             {
170                 i++;
171             }
172
173             b1 = decodingTable[data[i++]];
174
175             while ((i < finish) && ignore((char)data[i]))
176             {
177                 i++;
178             }
179
180             b2 = decodingTable[data[i++]];
181
182             while ((i < finish) && ignore((char)data[i]))
183             {
184                 i++;
185             }
186
187             b3 = decodingTable[data[i++]];
188
189             while ((i < finish) && ignore((char)data[i]))
190             {
191                 i++;
192             }
193
194             b4 = decodingTable[data[i++]];
195
196             out.write((b1 << 2) | (b2 >> 4));
197             out.write((b2 << 4) | (b3 >> 2));
198             out.write((b3 << 6) | b4);
199
200             outLen += 3;
201         }
202
203         if (data[end - 2] == padding)
204         {
205             b1 = decodingTable[data[end - 4]];
206             b2 = decodingTable[data[end - 3]];
207
208             out.write((b1 << 2) | (b2 >> 4));
209
210             outLen += 1;
211         }
212         else if (data[end - 1] == padding)
213         {
214             b1 = decodingTable[data[end - 4]];
215             b2 = decodingTable[data[end - 3]];
216             b3 = decodingTable[data[end - 2]];
217
218             out.write((b1 << 2) | (b2 >> 4));
219             out.write((b2 << 4) | (b3 >> 2));
220
221             outLen += 2;
222         }
223         else
224         {
225             b1 = decodingTable[data[end - 4]];
226             b2 = decodingTable[data[end - 3]];
227             b3 = decodingTable[data[end - 2]];
228             b4 = decodingTable[data[end - 1]];
229
230             out.write((b1 << 2) | (b2 >> 4));
231             out.write((b2 << 4) | (b3 >> 2));
232             out.write((b3 << 6) | b4);
233
234             outLen += 3;
235         }
236
237         return outLen;
238     }
239
240     /**
241      * decode the base 64 encoded String data writing it to the given output stream,
242      * whitespace characters will be ignored.
243      *
244      * @return the number of bytes produced.
245      */

246     public int decode(
247         String JavaDoc data,
248         OutputStream JavaDoc out)
249         throws IOException JavaDoc
250     {
251         byte[] bytes;
252         byte b1, b2, b3, b4;
253         int length = 0;
254
255         int end = data.length();
256
257         while (end > 0)
258         {
259             if (!ignore(data.charAt(end - 1)))
260             {
261                 break;
262             }
263
264             end--;
265         }
266
267         int i = 0;
268         int finish = end - 4;
269
270         while (i < finish)
271         {
272             while ((i < finish) && ignore(data.charAt(i)))
273             {
274                 i++;
275             }
276
277             b1 = decodingTable[data.charAt(i++)];
278
279             while ((i < finish) && ignore(data.charAt(i)))
280             {
281                 i++;
282             }
283             b2 = decodingTable[data.charAt(i++)];
284
285             while ((i < finish) && ignore(data.charAt(i)))
286             {
287                 i++;
288             }
289             b3 = decodingTable[data.charAt(i++)];
290
291             while ((i < finish) && ignore(data.charAt(i)))
292             {
293                 i++;
294             }
295             b4 = decodingTable[data.charAt(i++)];
296
297             out.write((b1 << 2) | (b2 >> 4));
298             out.write((b2 << 4) | (b3 >> 2));
299             out.write((b3 << 6) | b4);
300
301             length += 3;
302         }
303
304         if (data.charAt(end - 2) == padding)
305         {
306             b1 = decodingTable[data.charAt(end - 4)];
307             b2 = decodingTable[data.charAt(end - 3)];
308
309             out.write((b1 << 2) | (b2 >> 4));
310
311             length += 1;
312         }
313         else if (data.charAt(end - 1) == padding)
314         {
315             b1 = decodingTable[data.charAt(end - 4)];
316             b2 = decodingTable[data.charAt(end - 3)];
317             b3 = decodingTable[data.charAt(end - 2)];
318
319             out.write((b1 << 2) | (b2 >> 4));
320             out.write((b2 << 4) | (b3 >> 2));
321
322             length += 2;
323         }
324         else
325         {
326             b1 = decodingTable[data.charAt(end - 4)];
327             b2 = decodingTable[data.charAt(end - 3)];
328             b3 = decodingTable[data.charAt(end - 2)];
329             b4 = decodingTable[data.charAt(end - 1)];
330
331             out.write((b1 << 2) | (b2 >> 4));
332             out.write((b2 << 4) | (b3 >> 2));
333             out.write((b3 << 6) | b4);
334
335             length += 3;
336         }
337
338         return length;
339     }
340 }
341
Popular Tags