KickJava   Java API By Example, From Geeks To Geeks.

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


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.OutputStream JavaDoc;
22 import java.io.PrintStream JavaDoc;
23
24 /**
25  * This class implements a Base64 Character encoder as specified in RFC1113.
26  * Unlike some other encoding schemes there is nothing in this encoding
27  * that indicates where a buffer starts or ends.
28  *
29  * This means that the encoded text will simply start with the first line
30  * of encoded text and end with the last line of encoded text.
31  *
32  * @author <a HREF="mailto:deweese@apache.org">Thomas DeWeese</a>
33  * @author <a HREF="mailto:vincent.hardy@eng.sun.com">Vincent Hardy</a>
34  * @author Chuck McManis
35  * @version $Id: Base64EncoderStream.java,v 1.6 2005/03/27 08:58:36 cam Exp $
36  */

37 public class Base64EncoderStream extends OutputStream JavaDoc {
38
39     /** This array maps the 6 bit values to their characters */
40     private final static byte pem_array[] = {
41     // 0 1 2 3 4 5 6 7
42
'A','B','C','D','E','F','G','H', // 0
43
'I','J','K','L','M','N','O','P', // 1
44
'Q','R','S','T','U','V','W','X', // 2
45
'Y','Z','a','b','c','d','e','f', // 3
46
'g','h','i','j','k','l','m','n', // 4
47
'o','p','q','r','s','t','u','v', // 5
48
'w','x','y','z','0','1','2','3', // 6
49
'4','5','6','7','8','9','+','/' // 7
50
};
51
52     byte [] atom = new byte[3];
53     int atomLen = 0;
54     byte [] encodeBuf = new byte[4];
55     int lineLen = 0;
56
57     PrintStream JavaDoc out;
58     boolean closeOutOnClose;
59
60     public Base64EncoderStream(OutputStream JavaDoc out) {
61         this.out = new PrintStream JavaDoc(out);
62         closeOutOnClose = true;
63     }
64
65     public Base64EncoderStream(OutputStream JavaDoc out, boolean closeOutOnClose) {
66         this.out = new PrintStream JavaDoc(out);
67         this.closeOutOnClose = closeOutOnClose;
68     }
69
70     public void close () throws IOException JavaDoc {
71         if (out != null) {
72             encodeAtom();
73             out.flush();
74             if (closeOutOnClose)
75                 out.close();
76             out=null;
77         }
78     }
79
80     /**
81      * This can't really flush out output since that may generate
82      * '=' chars which would indicate the end of the stream.
83      * Instead we flush out. You can only be sure all output is
84      * writen by closing this stream.
85      */

86     public void flush() throws IOException JavaDoc {
87         out.flush();
88     }
89
90     public void write(int b) throws IOException JavaDoc {
91         atom[atomLen++] = (byte)b;
92         if (atomLen == 3)
93             encodeAtom();
94     }
95
96     public void write(byte []data) throws IOException JavaDoc {
97         encodeFromArray(data, 0, data.length);
98     }
99
100     public void write(byte [] data, int off, int len) throws IOException JavaDoc {
101         encodeFromArray(data, off, len);
102     }
103
104     /**
105      * enocodeAtom - Take three bytes of input and encode it as 4
106      * printable characters. Note that if the length in len is less
107      * than three is encodes either one or two '=' signs to indicate
108      * padding characters.
109      */

110     void encodeAtom() throws IOException JavaDoc {
111         byte a, b, c;
112
113         switch (atomLen) {
114         case 0: return;
115         case 1:
116             a = atom[0];
117             encodeBuf[0] = pem_array[((a >>> 2) & 0x3F)];
118             encodeBuf[1] = pem_array[((a << 4) & 0x30)];
119             encodeBuf[2] = encodeBuf[3] = '=';
120             break;
121         case 2:
122             a = atom[0];
123             b = atom[1];
124             encodeBuf[0] = pem_array[((a >>> 2) & 0x3F)];
125             encodeBuf[1] = pem_array[(((a << 4) & 0x30) | ((b >>> 4) & 0x0F))];
126             encodeBuf[2] = pem_array[((b << 2) & 0x3C)];
127             encodeBuf[3] = '=';
128             break;
129         default:
130             a = atom[0];
131             b = atom[1];
132             c = atom[2];
133             encodeBuf[0] = pem_array[((a >>> 2) & 0x3F)];
134             encodeBuf[1] = pem_array[(((a << 4) & 0x30) | ((b >>> 4) & 0x0F))];
135             encodeBuf[2] = pem_array[(((b << 2) & 0x3C) | ((c >>> 6) & 0x03))];
136             encodeBuf[3] = pem_array[c & 0x3F];
137         }
138         if (lineLen == 64) {
139             out.println();
140             lineLen = 0;
141         }
142         out.write(encodeBuf);
143
144         lineLen += 4;
145         atomLen = 0;
146     }
147
148     /**
149      * enocodeAtom - Take three bytes of input and encode it as 4
150      * printable characters. Note that if the length in len is less
151      * than three is encodes either one or two '=' signs to indicate
152      * padding characters.
153      */

154     void encodeFromArray(byte[] data, int offset, int len)
155         throws IOException JavaDoc{
156         byte a, b, c;
157         if (len == 0)
158             return;
159
160         // System.out.println("atomLen: " + atomLen +
161
// " len: " + len +
162
// " offset: " + offset);
163

164         if (atomLen != 0) {
165             switch(atomLen) {
166             case 1:
167                 atom[1] = data[offset++]; len--; atomLen++;
168                 if (len == 0) return;
169                 atom[2] = data[offset++]; len--; atomLen++;
170                 break;
171             case 2:
172                 atom[2] = data[offset++]; len--; atomLen++;
173                 break;
174             default:
175             }
176             encodeAtom();
177         }
178
179         while (len >=3) {
180             a = data[offset++];
181             b = data[offset++];
182             c = data[offset++];
183             
184             encodeBuf[0] = pem_array[((a >>> 2) & 0x3F)];
185             encodeBuf[1] = pem_array[(((a << 4) & 0x30) | ((b >>> 4) & 0x0F))];
186             encodeBuf[2] = pem_array[(((b << 2) & 0x3C) | ((c >>> 6) & 0x03))];
187             encodeBuf[3] = pem_array[c & 0x3F];
188             out.write(encodeBuf);
189
190             lineLen += 4;
191             if (lineLen == 64) {
192                 out.println();
193                 lineLen = 0;
194             }
195
196             len -=3;
197         }
198
199         switch (len) {
200         case 1:
201             atom[0] = data[offset];
202             break;
203         case 2:
204             atom[0] = data[offset];
205             atom[1] = data[offset+1];
206             break;
207         default:
208         }
209         atomLen = len;
210     }
211
212     
213     
214 }
215
Popular Tags