KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > soap > encoding > soapenc > Base64


1 /*
2  * (C) Copyright IBM Corp. 1999 All rights reserved.
3  *
4  * US Government Users Restricted Rights Use, duplication or
5  * disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
6  *
7  * The program is provided "as is" without any warranty express or
8  * implied, including the warranty of non-infringement and the implied
9  * warranties of merchantibility and fitness for a particular purpose.
10  * IBM will not be liable for any damages suffered by you as a result
11  * of using the Program. In no event will IBM be liable for any
12  * special, indirect or consequential damages or lost profits even if
13  * IBM has been advised of the possibility of their occurrence. IBM
14  * will not be liable for any third party claims against you.
15  */

16
17 package org.apache.soap.encoding.soapenc;
18
19 import java.io.IOException JavaDoc;
20 import java.io.OutputStream JavaDoc;
21 import java.io.Writer JavaDoc;
22
23 /**
24  *
25  * @author TAMURA Kent <kent@trl.ibm.co.jp>
26  */

27 public class Base64 {
28     private static final char[] S_BASE64CHAR = {
29         'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
30         'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
31         'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
32         'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
33         'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
34         'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
35         '8', '9', '+', '/'
36     };
37     private static final char S_BASE64PAD = '=';
38     private static final byte[] S_DECODETABLE = new byte[128];
39     static {
40         for (int i = 0; i < S_DECODETABLE.length; i ++)
41             S_DECODETABLE[i] = Byte.MAX_VALUE; // 127
42
for (int i = 0; i < S_BASE64CHAR.length; i ++) // 0 to 63
43
S_DECODETABLE[S_BASE64CHAR[i]] = (byte)i;
44     }
45
46     private static int decode0(char[] ibuf, byte[] obuf, int wp) {
47         int outlen = 3;
48         if (ibuf[3] == S_BASE64PAD) outlen = 2;
49         if (ibuf[2] == S_BASE64PAD) outlen = 1;
50         int b0 = S_DECODETABLE[ibuf[0]];
51         int b1 = S_DECODETABLE[ibuf[1]];
52         int b2 = S_DECODETABLE[ibuf[2]];
53         int b3 = S_DECODETABLE[ibuf[3]];
54         switch (outlen) {
55           case 1:
56             obuf[wp] = (byte)(b0 << 2 & 0xfc | b1 >> 4 & 0x3);
57             return 1;
58           case 2:
59             obuf[wp++] = (byte)(b0 << 2 & 0xfc | b1 >> 4 & 0x3);
60             obuf[wp] = (byte)(b1 << 4 & 0xf0 | b2 >> 2 & 0xf);
61             return 2;
62           case 3:
63             obuf[wp++] = (byte)(b0 << 2 & 0xfc | b1 >> 4 & 0x3);
64             obuf[wp++] = (byte)(b1 << 4 & 0xf0 | b2 >> 2 & 0xf);
65             obuf[wp] = (byte)(b2 << 6 & 0xc0 | b3 & 0x3f);
66             return 3;
67           default:
68             throw new RuntimeException JavaDoc("Internal Errror");
69         }
70     }
71
72     /**
73      * Decode the base64 data.
74      * @param data The base64 encoded data to be decoded
75      * @param off The offset within the encoded data at which to start decoding
76      * @param len The length of data to decode
77      * @return The decoded data
78      */

79     public static byte[] decode(char[] data, int off, int len) {
80         char[] ibuf = new char[4];
81         int ibufcount = 0;
82         byte[] obuf = new byte[len/4*3+3];
83         int obufcount = 0;
84         for (int i = off; i < off+len; i ++) {
85             char ch = data[i];
86             if (ch == S_BASE64PAD
87                 || ch < S_DECODETABLE.length && S_DECODETABLE[ch] != Byte.MAX_VALUE) {
88                 ibuf[ibufcount++] = ch;
89                 if (ibufcount == ibuf.length) {
90                     ibufcount = 0;
91                     obufcount += decode0(ibuf, obuf, obufcount);
92                 }
93             }
94         }
95         if (obufcount == obuf.length)
96             return obuf;
97         byte[] ret = new byte[obufcount];
98         System.arraycopy(obuf, 0, ret, 0, obufcount);
99         return ret;
100     }
101
102     /**
103      * Decode the base64 data.
104      * @param data The base64 encoded data to be decoded
105      * @return The decoded data
106      */

107     public static byte[] decode(String JavaDoc data) {
108         char[] ibuf = new char[4];
109         int ibufcount = 0;
110         byte[] obuf = new byte[data.length()/4*3+3];
111         int obufcount = 0;
112         for (int i = 0; i < data.length(); i ++) {
113             char ch = data.charAt(i);
114             if (ch == S_BASE64PAD
115                 || ch < S_DECODETABLE.length && S_DECODETABLE[ch] != Byte.MAX_VALUE) {
116                 ibuf[ibufcount++] = ch;
117                 if (ibufcount == ibuf.length) {
118                     ibufcount = 0;
119                     obufcount += decode0(ibuf, obuf, obufcount);
120                 }
121             }
122         }
123         if (obufcount == obuf.length)
124             return obuf;
125         byte[] ret = new byte[obufcount];
126         System.arraycopy(obuf, 0, ret, 0, obufcount);
127         return ret;
128     }
129
130     /**
131      * Decode the base64 data.
132      * @param data The base64 encoded data to be decoded
133      * @param off The offset within the encoded data at which to start decoding
134      * @param len The length of data to decode
135      * @param ostream The OutputStream to which the decoded data should be
136      * written
137      */

138     public static void decode(char[] data, int off, int len, OutputStream JavaDoc ostream) throws IOException JavaDoc {
139         char[] ibuf = new char[4];
140         int ibufcount = 0;
141         byte[] obuf = new byte[3];
142         for (int i = off; i < off+len; i ++) {
143             char ch = data[i];
144             if (ch == S_BASE64PAD
145                 || ch < S_DECODETABLE.length && S_DECODETABLE[ch] != Byte.MAX_VALUE) {
146                 ibuf[ibufcount++] = ch;
147                 if (ibufcount == ibuf.length) {
148                     ibufcount = 0;
149                     int obufcount = decode0(ibuf, obuf, 0);
150                     ostream.write(obuf, 0, obufcount);
151                 }
152             }
153         }
154     }
155
156     /**
157      * Decode the base64 data.
158      * @param data The base64 encoded data to be decoded
159      * @param ostream The OutputStream to which the decoded data should be
160      * written
161      */

162     public static void decode(String JavaDoc data, OutputStream JavaDoc ostream) throws IOException JavaDoc {
163         char[] ibuf = new char[4];
164         int ibufcount = 0;
165         byte[] obuf = new byte[3];
166         for (int i = 0; i < data.length(); i ++) {
167             char ch = data.charAt(i);
168             if (ch == S_BASE64PAD
169                 || ch < S_DECODETABLE.length && S_DECODETABLE[ch] != Byte.MAX_VALUE) {
170                 ibuf[ibufcount++] = ch;
171                 if (ibufcount == ibuf.length) {
172                     ibufcount = 0;
173                     int obufcount = decode0(ibuf, obuf, 0);
174                     ostream.write(obuf, 0, obufcount);
175                 }
176             }
177         }
178     }
179
180     /**
181      * Returns base64 representation of specified byte array.
182      * @param data The data to be encoded
183      * @return The base64 encoded data
184      */

185     public static String JavaDoc encode(byte[] data) {
186         return encode(data, 0, data.length);
187     }
188
189     /**
190      * Returns base64 representation of specified byte array.
191      * @param data The data to be encoded
192      * @param off The offset within the data at which to start encoding
193      * @param len The length of the data to encode
194      * @return The base64 encoded data
195      */

196     public static String JavaDoc encode(byte[] data, int off, int len) {
197         if (len <= 0) return "";
198         char[] out = new char[len/3*4+4];
199         int rindex = off;
200         int windex = 0;
201         int rest = len;
202         while (rest >= 3) {
203             int i = ((data[rindex]&0xff)<<16)
204                 +((data[rindex+1]&0xff)<<8)
205                 +(data[rindex+2]&0xff);
206             out[windex++] = S_BASE64CHAR[i>>18];
207             out[windex++] = S_BASE64CHAR[(i>>12)&0x3f];
208             out[windex++] = S_BASE64CHAR[(i>>6)&0x3f];
209             out[windex++] = S_BASE64CHAR[i&0x3f];
210             rindex += 3;
211             rest -= 3;
212         }
213         if (rest == 1) {
214             int i = data[rindex]&0xff;
215             out[windex++] = S_BASE64CHAR[i>>2];
216             out[windex++] = S_BASE64CHAR[(i<<4)&0x3f];
217             out[windex++] = S_BASE64PAD;
218             out[windex++] = S_BASE64PAD;
219         } else if (rest == 2) {
220             int i = ((data[rindex]&0xff)<<8)+(data[rindex+1]&0xff);
221             out[windex++] = S_BASE64CHAR[i>>10];
222             out[windex++] = S_BASE64CHAR[(i>>4)&0x3f];
223             out[windex++] = S_BASE64CHAR[(i<<2)&0x3f];
224             out[windex++] = S_BASE64PAD;
225         }
226         return new String JavaDoc(out, 0, windex);
227     }
228
229     /**
230      * Outputs base64 representation of the specified byte array to a byte stream.
231      * @param data The data to be encoded
232      * @param off The offset within the data at which to start encoding
233      * @param len The length of the data to encode
234      * @param ostream The OutputStream to which the encoded data should be
235      * written
236      */

237     public static void encode(byte[] data, int off, int len, OutputStream JavaDoc ostream) throws IOException JavaDoc {
238         if (len <= 0) return;
239         byte[] out = new byte[4];
240         int rindex = off;
241         int rest = len;
242         while (rest >= 3) {
243             int i = ((data[rindex]&0xff)<<16)
244                 +((data[rindex+1]&0xff)<<8)
245                 +(data[rindex+2]&0xff);
246             out[0] = (byte)S_BASE64CHAR[i>>18];
247             out[1] = (byte)S_BASE64CHAR[(i>>12)&0x3f];
248             out[2] = (byte)S_BASE64CHAR[(i>>6)&0x3f];
249             out[3] = (byte)S_BASE64CHAR[i&0x3f];
250             ostream.write(out, 0, 4);
251             rindex += 3;
252             rest -= 3;
253         }
254         if (rest == 1) {
255             int i = data[rindex]&0xff;
256             out[0] = (byte)S_BASE64CHAR[i>>2];
257             out[1] = (byte)S_BASE64CHAR[(i<<4)&0x3f];
258             out[2] = (byte)S_BASE64PAD;
259             out[3] = (byte)S_BASE64PAD;
260             ostream.write(out, 0, 4);
261         } else if (rest == 2) {
262             int i = ((data[rindex]&0xff)<<8)+(data[rindex+1]&0xff);
263             out[0] = (byte)S_BASE64CHAR[i>>10];
264             out[1] = (byte)S_BASE64CHAR[(i>>4)&0x3f];
265             out[2] = (byte)S_BASE64CHAR[(i<<2)&0x3f];
266             out[3] = (byte)S_BASE64PAD;
267             ostream.write(out, 0, 4);
268         }
269     }
270
271     /**
272      * Outputs base64 representation of the specified byte array to a character stream.
273      * @param data The data to be encoded
274      * @param off The offset within the data at which to start encoding
275      * @param len The length of the data to encode
276      * @param writer The Writer to which the encoded data should be
277      * written
278      */

279     public static void encode(byte[] data, int off, int len, Writer JavaDoc writer) throws IOException JavaDoc {
280         if (len <= 0) return;
281         char[] out = new char[4];
282         int rindex = off;
283         int rest = len;
284         int output = 0;
285         while (rest >= 3) {
286             int i = ((data[rindex]&0xff)<<16)
287                 +((data[rindex+1]&0xff)<<8)
288                 +(data[rindex+2]&0xff);
289             out[0] = S_BASE64CHAR[i>>18];
290             out[1] = S_BASE64CHAR[(i>>12)&0x3f];
291             out[2] = S_BASE64CHAR[(i>>6)&0x3f];
292             out[3] = S_BASE64CHAR[i&0x3f];
293             writer.write(out, 0, 4);
294             rindex += 3;
295             rest -= 3;
296             output += 4;
297             if (output % 76 == 0)
298                 writer.write("\n");
299         }
300         if (rest == 1) {
301             int i = data[rindex]&0xff;
302             out[0] = S_BASE64CHAR[i>>2];
303             out[1] = S_BASE64CHAR[(i<<4)&0x3f];
304             out[2] = S_BASE64PAD;
305             out[3] = S_BASE64PAD;
306             writer.write(out, 0, 4);
307         } else if (rest == 2) {
308             int i = ((data[rindex]&0xff)<<8)+(data[rindex+1]&0xff);
309             out[0] = S_BASE64CHAR[i>>10];
310             out[1] = S_BASE64CHAR[(i>>4)&0x3f];
311             out[2] = S_BASE64CHAR[(i<<2)&0x3f];
312             out[3] = S_BASE64PAD;
313             writer.write(out, 0, 4);
314         }
315     }
316 }
317
Popular Tags