KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > util > Base64


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  *
23  * Free Software Foundation, Inc.
24  * 59 Temple Place, Suite 330
25  * Boston, MA 02111-1307 USA
26  *
27  * @author Scott Ferguson
28  */

29
30 package com.caucho.util;
31
32 import java.io.*;
33
34 /**
35  * Base64 decoding.
36  */

37 public class Base64 {
38   static int decode[];
39
40   static {
41     decode = new int[256];
42     for (int i = 'A'; i <= 'Z'; i++)
43       decode[i] = i - 'A';
44     for (int i = 'a'; i <= 'z'; i++)
45       decode[i] = i - 'a' + 26;
46     for (int i = '0'; i <= '9'; i++)
47       decode[i] = i - '0' + 52;
48     decode['+'] = 62;
49     decode['/'] = 63;
50     
51     decode['='] = 0;
52   }
53
54   public static void encode(CharBuffer cb, long data)
55   {
56     cb.append(Base64.encode(data >> 60));
57     cb.append(Base64.encode(data >> 54));
58     cb.append(Base64.encode(data >> 48));
59     cb.append(Base64.encode(data >> 42));
60     cb.append(Base64.encode(data >> 36));
61     cb.append(Base64.encode(data >> 30));
62     cb.append(Base64.encode(data >> 24));
63     cb.append(Base64.encode(data >> 18));
64     cb.append(Base64.encode(data >> 12));
65     cb.append(Base64.encode(data >> 6));
66     cb.append(Base64.encode(data));
67   }
68
69   public static void encode24(CharBuffer cb, int data)
70   {
71     cb.append(Base64.encode(data >> 18));
72     cb.append(Base64.encode(data >> 12));
73     cb.append(Base64.encode(data >> 6));
74     cb.append(Base64.encode(data));
75   }
76
77   public static void encode(CharBuffer cb, byte []buffer,
78                             int offset, int length)
79   {
80     while (length >= 3) {
81       int data = (buffer[offset] & 0xff) << 16;
82       data += (buffer[offset + 1] & 0xff) << 8;
83       data += (buffer[offset + 2] & 0xff);
84       
85       cb.append(Base64.encode(data >> 18));
86       cb.append(Base64.encode(data >> 12));
87       cb.append(Base64.encode(data >> 6));
88       cb.append(Base64.encode(data));
89
90       offset += 3;
91       length -= 3;
92     }
93
94     if (length == 2) {
95       int b1 = buffer[offset] & 0xff;
96       int b2 = buffer[offset + 1] & 0xff;
97       
98       int data = (b1 << 16) + (b2 << 8);
99       
100       cb.append(Base64.encode(data >> 18));
101       cb.append(Base64.encode(data >> 12));
102       cb.append(Base64.encode(data >> 6));
103       cb.append('=');
104     }
105     else if (length == 1) {
106       int data = (buffer[offset] & 0xff) << 16;
107       
108       cb.append(Base64.encode(data >> 18));
109       cb.append(Base64.encode(data >> 12));
110       cb.append('=');
111       cb.append('=');
112     }
113   }
114
115   public static void oldEncode(CharBuffer cb, byte []buffer,
116                    int offset, int length)
117   {
118     while (length >= 3) {
119       int data = (buffer[offset] & 0xff) << 16;
120       data += (buffer[offset + 1] & 0xff) << 8;
121       data += (buffer[offset + 2] & 0xff);
122       
123       cb.append(Base64.encode(data >> 18));
124       cb.append(Base64.encode(data >> 12));
125       cb.append(Base64.encode(data >> 6));
126       cb.append(Base64.encode(data));
127
128       offset += 3;
129       length -= 3;
130     }
131
132     if (length == 2) {
133       int b1 = buffer[offset] & 0xff;
134       int b2 = buffer[offset + 1] & 0xff;
135       
136       int data = (b1 << 8) + (b2);
137       
138       cb.append(Base64.encode(data >> 12));
139       cb.append(Base64.encode(data >> 6));
140       cb.append(Base64.encode(data));
141       cb.append('=');
142     }
143     else if (length == 1) {
144       int data = (buffer[offset] & 0xff);
145       
146       cb.append(Base64.encode(data >> 6));
147       cb.append(Base64.encode(data));
148       cb.append('=');
149       cb.append('=');
150     }
151   }
152
153   public static char encode(long d)
154   {
155     d &= 0x3f;
156     if (d < 26)
157       return (char) (d + 'A');
158     else if (d < 52)
159       return (char) (d + 'a' - 26);
160     else if (d < 62)
161       return (char) (d + '0' - 52);
162     else if (d == 62)
163       return '+';
164     else
165       return '/';
166   }
167
168   public static int decode(int d)
169   {
170     return decode[d];
171   }
172
173   public static String JavaDoc encode(String JavaDoc value)
174   {
175     try {
176       StringWriter sw = new StringWriter();
177       encode(sw, new ByteArrayInputStream(value.getBytes()));
178       return sw.toString();
179     }
180     catch (IOException e) {
181       throw new RuntimeException JavaDoc("this should not be possible: " + e);
182     }
183   }
184
185   public static String JavaDoc encodeFromByteArray(byte[] value)
186   {
187     try {
188       StringWriter sw = new StringWriter();
189       encode(sw, new ByteArrayInputStream(value));
190       return sw.toString();
191     }
192     catch (IOException e) {
193       throw new RuntimeException JavaDoc("this should not be possible " + e);
194     }
195   }
196
197   public static String JavaDoc encodeFromByteArray(byte[] value,
198                        int offset,
199                        int length)
200   {
201     try {
202       StringWriter sw = new StringWriter();
203       encode(sw, new ByteArrayInputStream(value, offset, length));
204       return sw.toString();
205     }
206     catch (IOException e) {
207       throw new RuntimeException JavaDoc("this should not be possible " + e);
208     }
209   }
210
211   public static void encode(Writer w, InputStream i)
212     throws IOException
213   {
214     while(true) {
215       int value1 = i.read();
216       int value2 = i.read();
217       int value3 = i.read();
218
219       if (value3 >= 0) {
220     long chunk = (value1 & 0xff);
221     chunk = (chunk << 8) + (value2 & 0xff);
222     chunk = (chunk << 8) + (value3 & 0xff);
223         
224     w.write(encode(chunk >> 18));
225     w.write(encode(chunk >> 12));
226     w.write(encode(chunk >> 6));
227     w.write(encode(chunk));
228     continue;
229       }
230     
231       if (value2 >= 0) {
232     long chunk = (value1 & 0xff);
233     chunk = (chunk << 8) + (value2 & 0xff);
234     chunk <<= 8;
235     
236     w.write(encode(chunk >> 18));
237     w.write(encode(chunk >> 12));
238     w.write(encode(chunk >> 6));
239     w.write('=');
240       }
241       else if (value1 >= 0) {
242     long chunk = (value1 & 0xff);
243     chunk <<= 16;
244     
245     w.write(encode(chunk >> 18));
246     w.write(encode(chunk >> 12));
247     w.write('=');
248     w.write('=');
249       }
250       break;
251     }
252     w.flush();
253   }
254
255   public static String JavaDoc decode(String JavaDoc value)
256   {
257     try {
258       ByteArrayOutputStream baos = new ByteArrayOutputStream();
259       decode(new StringReader(value), baos);
260       return new String JavaDoc(baos.toByteArray());
261     }
262     catch (IOException e) {
263       throw new RuntimeException JavaDoc("this should not be possible: " + e);
264     }
265   }
266
267   public static byte[] decodeToByteArray(String JavaDoc value)
268   {
269     try {
270       if (value == null)
271     return new byte[0];
272       
273       ByteArrayOutputStream baos = new ByteArrayOutputStream();
274       decode(new StringReader(value), baos);
275       return baos.toByteArray();
276     }
277     catch (IOException e) {
278       throw new RuntimeException JavaDoc("this should not be possible: " + e);
279     }
280   }
281
282   public static String JavaDoc oldDecode(String JavaDoc value)
283   {
284     CharBuffer cb = new CharBuffer();
285
286     int length = value.length();
287     for (int i = 0; i + 3 < length; i += 4) {
288       int ch0 = value.charAt(i + 0) & 0xff;
289
290       // skip whitespace
291
if (ch0 == ' ' || ch0 == '\n' || ch0 == '\r') {
292         i -= 3;
293         continue;
294       }
295       
296       int ch1 = value.charAt(i + 1) & 0xff;
297       int ch2 = value.charAt(i + 2) & 0xff;
298       int ch3 = value.charAt(i + 3) & 0xff;
299
300       int chunk = ((decode[ch0] << 18) +
301            (decode[ch1] << 12) +
302            (decode[ch2] << 6) +
303            (decode[ch3]));
304
305       cb.append((char) ((chunk >> 16) & 0xff));
306
307       if (ch2 != '=')
308     cb.append((char) ((chunk >> 8) & 0xff));
309       if (ch3 != '=')
310     cb.append((char) ((chunk & 0xff)));
311     }
312
313     return cb.toString();
314   }
315
316   private static int readNonWhitespace(Reader r)
317     throws IOException
318   {
319     while(true) {
320       int ret = r.read();
321       // skip whitespace
322
if (ret == ' ' || ret == '\n' || ret == '\r')
323     continue;
324       return ret;
325     }
326   }
327
328   public static void decode(Reader r, OutputStream os)
329     throws IOException
330   {
331     while(true) {
332       int ch0 = readNonWhitespace(r);
333       int ch1 = r.read();
334       int ch2 = r.read();
335       int ch3 = r.read();
336
337       if (ch1 < 0)
338     break;
339       if (ch2 < 0)
340     ch2 = '=';
341       if (ch3 < 0)
342     ch3 = '=';
343       
344       int chunk = ((decode[ch0] << 18) +
345            (decode[ch1] << 12) +
346            (decode[ch2] << 6) +
347            (decode[ch3]));
348       
349       os.write((byte) ((chunk >> 16) & 0xff));
350       
351       if (ch2 != '=' && ch2 != -1)
352     os.write((byte) ((chunk >> 8) & 0xff));
353       if (ch3 != '=' && ch3 != -1)
354     os.write((byte) ((chunk & 0xff)));
355       else
356     break;
357     }
358     os.flush();
359   }
360 }
361
Popular Tags