KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > batik > util > Base64DecodeStream


1 /*
2
3    Copyright 2001-2003 The Apache Software Foundation
4
5    Licensed under the Apache License, Version 2.0 (the "License");
6    you may not use this file except in compliance with the License.
7    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.batik.util;
19
20 import java.io.IOException JavaDoc;
21 import java.io.InputStream JavaDoc;
22
23 /**
24  * This class implements a Base64 Character decoder as specified in RFC1113.
25  * Unlike some other encoding schemes there is nothing in this encoding that
26  * tells the decoder where a buffer starts or stops, so to use it you will need
27  * to isolate your encoded data into a single chunk and then feed them
28  * this decoder. The simplest way to do that is to read all of the encoded
29  * data into a string and then use:
30  * <pre>
31  * byte data[];
32  * InputStream is = new ByteArrayInputStream(data);
33  * is = new Base64DecodeStream(is);
34  * </pre>
35  *
36  * On errors, this class throws a IOException with the following detail
37  * strings:
38  * <pre>
39  * "Base64DecodeStream: Bad Padding byte (2)."
40  * "Base64DecodeStream: Bad Padding byte (1)."
41  * </pre>
42  *
43  * @author <a HREF="mailto:thomas.deweese@kodak.com">Thomas DeWeese</a>
44  * @author <a HREF="mailto:vincent.hardy@eng.sun.com">Vincent Hardy</a>
45  * @author Chuck McManis
46  * @version $Id: Base64DecodeStream.java,v 1.7 2005/03/27 08:58:36 cam Exp $
47  */

48
49 public class Base64DecodeStream extends InputStream JavaDoc {
50
51     InputStream JavaDoc src;
52
53     public Base64DecodeStream(InputStream JavaDoc src) {
54     this.src = src;
55     }
56
57     private final static byte pem_array[] = new byte[256];
58     static {
59         for (int i=0; i<pem_array.length; i++)
60             pem_array[i] = -1;
61
62         int idx = 0;
63         for (char c='A'; c<='Z'; c++) {
64             pem_array[c] = (byte)idx++;
65         }
66         for (char c='a'; c<='z'; c++) {
67             pem_array[c] = (byte)idx++;
68         }
69     
70         for (char c='0'; c<='9'; c++) {
71             pem_array[c] = (byte)idx++;
72         }
73
74         pem_array['+'] = (byte)idx++;
75         pem_array['/'] = (byte)idx++;
76     }
77
78     public boolean markSupported() { return false; }
79
80     public void close()
81         throws IOException JavaDoc {
82         EOF = true;
83     }
84
85     public int available()
86         throws IOException JavaDoc {
87         return 3-out_offset;
88     }
89
90     byte decode_buffer[] = new byte[4];
91     byte out_buffer[] = new byte[3];
92     int out_offset = 3;
93     boolean EOF = false;
94
95     public int read() throws IOException JavaDoc {
96
97         if (out_offset == 3) {
98             if (EOF || getNextAtom()) {
99                 EOF = true;
100                 return -1;
101             }
102         }
103
104         return ((int)out_buffer[out_offset++])&0xFF;
105     }
106
107     public int read(byte []out, int offset, int len)
108         throws IOException JavaDoc {
109
110         int idx = 0;
111         while (idx < len) {
112             if (out_offset == 3) {
113                 if (EOF || getNextAtom()) {
114                     EOF = true;
115                     if (idx == 0) return -1;
116                     else return idx;
117                 }
118             }
119
120             out[offset+idx] = out_buffer[out_offset++];
121
122             idx++;
123         }
124         return idx;
125     }
126
127     final boolean getNextAtom() throws IOException JavaDoc {
128         int count, a, b, c, d;
129
130         int off = 0;
131         while(off != 4) {
132             count = src.read(decode_buffer, off, 4-off);
133             if (count == -1)
134                 return true;
135
136             int in=off, out=off;
137             while(in < off+count) {
138                 if ((decode_buffer[in] != '\n') &&
139                     (decode_buffer[in] != '\r') &&
140                     (decode_buffer[in] != ' '))
141                     decode_buffer[out++] = decode_buffer[in];
142                 in++;
143             }
144
145             off = out;
146         }
147
148         a = pem_array[((int)decode_buffer[0])&0xFF];
149         b = pem_array[((int)decode_buffer[1])&0xFF];
150         c = pem_array[((int)decode_buffer[2])&0xFF];
151         d = pem_array[((int)decode_buffer[3])&0xFF];
152     
153         out_buffer[0] = (byte)((a<<2) | (b>>>4));
154         out_buffer[1] = (byte)((b<<4) | (c>>>2));
155         out_buffer[2] = (byte)((c<<6) | d );
156
157         if (decode_buffer[3] != '=') {
158             // All three bytes are good.
159
out_offset=0;
160         } else if (decode_buffer[2] == '=') {
161             // Only one byte of output.
162
out_buffer[2] = out_buffer[0];
163             out_offset = 2;
164             EOF=true;
165         } else {
166             // Only two bytes of output.
167
out_buffer[2] = out_buffer[1];
168             out_buffer[1] = out_buffer[0];
169             out_offset = 1;
170             EOF=true;
171         }
172             
173         return false;
174     }
175 }
176
Popular Tags