KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ozoneDB > util > MimeBase64Decoder


1 /*
2  *
3  * The contents of this file are subject to the Netscape Public
4  * License Version 1.1 (the "License"); you may not use this file
5  * except in compliance with the License. You may obtain a copy of
6  * the License at http://www.mozilla.org/NPL/
7  *
8  * Software distributed under the License is distributed on an "AS
9  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
10  * implied. See the License for the specific language governing
11  * rights and limitations under the License.
12  *
13  * The Original Code is mozilla.org code.
14  *
15  * The Initial Developer of the Original Code is Netscape
16  * Communications Corporation. Portions created by Netscape are
17  * Copyright (C) 1999 Netscape Communications Corporation. All
18  * Rights Reserved.
19  *
20  * Contributor(s):
21  */

22
23
24 package org.ozoneDB.util;
25
26
27 import java.io.ByteArrayOutputStream JavaDoc;
28
29
30 /**
31  * Base 64 text to byte decoded. To produce the binary array from
32  * base 64 encoding call {@link #translate} for each sequence of
33  * characters and {@link #getByteArray} to mark closure of the
34  * character stream and retrieve the binary contents.
35  *
36  * @author Based on code from the Mozilla Directory SDK
37  */

38 public final class MimeBase64Decoder {
39     
40     
41     private ByteArrayOutputStream JavaDoc out = new ByteArrayOutputStream JavaDoc();
42     
43     private byte[] token = new byte[4];
44     private byte[] bytes = new byte[3];
45     private int token_length = 0;
46     
47     private final static byte NUL = 127;
48     private final static byte EOF = 126;
49     
50     private final static byte[] map =
51             
52             {NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, 62, NUL, NUL, NUL, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, NUL, NUL, NUL, EOF, NUL, NUL, NUL, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, NUL, NUL, NUL, NUL, NUL, NUL, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL};
53     // 000-007
54
// 010-017
55
// 020-027
56
// 030-037
57
// 040-047 !"#$%&'
58
// 050-057 ()*+,-./
59
// 060-067 01234567
60
// 070-077 89:;<=>?
61

62     // 100-107 @ABCDEFG
63
// 110-117 HIJKLMNO
64
// 120-127 PQRSTUVW
65
// 130-137 XYZ[\]^_
66
// 140-147 `abcdefg
67
// 150-157 hijklmno
68
// 160-167 pqrstuvw
69
// 170-177 xyz{|}~
70

71     // 200-207
72
// 210-217
73
// 220-227
74
// 230-237
75
// 240-247
76
// 250-257
77
// 260-267
78
// 270-277
79

80     // 300-307
81
// 310-317
82
// 320-327
83
// 330-337
84
// 340-347
85
// 350-357
86
// 360-367
87
// 370-377
88

89     
90     // Fast routine that assumes full 4-char tokens with no '=' in them.
91
//
92
private void decode_token() {
93         int num = token[0] << 18 | token[1] << 12 | token[2] << 6 | token[3];
94         
95         bytes[0] = (byte)(0xFF & num >> 16);
96         bytes[1] = (byte)(0xFF & num >> 8);
97         bytes[2] = (byte)(0xFF & num);
98         
99         out.write( bytes, 0, 3 );
100     }
101     
102     
103     // Hairier routine that deals with the final token, which can have fewer
104
// than four characters, and that might be padded with '='.
105
//
106
private final void decode_final_token() {
107         
108         byte b0 = token[0];
109         byte b1 = token[1];
110         byte b2 = token[2];
111         byte b3 = token[3];
112         
113         int eq_count = 0;
114         
115         if (b0 == EOF) {
116             b0 = 0;
117             eq_count++;
118         }
119         if (b1 == EOF) {
120             b1 = 0;
121             eq_count++;
122         }
123         if (b2 == EOF) {
124             b2 = 0;
125             eq_count++;
126         }
127         if (b3 == EOF) {
128             b3 = 0;
129             eq_count++;
130         }
131         
132         int num = b0 << 18 | b1 << 12 | b2 << 6 | b3;
133         
134         // eq_count will be 0, 1, or 2.
135
// No "=" padding means 4 bytes mapped to 3, the normal case,
136
// not handled in this routine.
137
// "xxx=" means 3 bytes mapped to 2.
138
// "xx==" means 2 bytes mapped to 1.
139
// "x===" can't happen, because "x" would then be encoding
140
// only 6 bits, not 8, the minimum possible.
141

142         out.write( (byte)(num >> 16) );
143         if (eq_count <= 1) {
144             out.write( (byte)(num >> 8 & 0xFF) );
145             if (eq_count == 0) {
146                 out.write( (byte)(num & 0xFF) );
147             }
148         }
149     }
150     
151     
152     public final void translate( char[] ch ) {
153         translate( ch, 0, ch.length );
154     }
155     
156     
157     public final void translate( char[] ch, int offset, int length ) {
158         
159         if (token == null) {
160             return;
161         }
162         
163         for (int i = offset; i < offset + length; i++) {
164             byte t = map[ch[i] & 0xff];
165             
166             if (t == EOF) {
167                 eof();
168             } else {
169                 if (t != NUL) {
170                     token[token_length++] = t;
171                 }
172             }
173             if (token_length == 4) {
174                 decode_token();
175                 token_length = 0;
176             }
177         }
178     }
179     
180     
181     private void eof() {
182         if (token != null && token_length != 0) {
183             while (token_length < 4) {
184                 token[token_length++] = EOF;
185             }
186             decode_final_token();
187         }
188         token_length = 0;
189         token = new byte[4];
190         bytes = new byte[3];
191     }
192     
193     
194     public byte[] getByteArray() {
195         eof();
196         return out.toByteArray();
197     }
198 }
199
Popular Tags