KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > infozone > tools > 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.infozone.tools;
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
42     private ByteArrayOutputStream JavaDoc out = new ByteArrayOutputStream JavaDoc();
43
44     private byte token[] = new byte[4]; // input buffer
45
private byte bytes[] = new byte[3]; // output buffer
46
private int token_length = 0; // input buffer length
47

48     static private final byte NUL = 127; // must be out of range 0-64
49
static private final byte EOF = 126; // must be out of range 0-64
50

51     static private final byte map[] = {
52       NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, // 000-007
53
NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, // 010-017
54
NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, // 020-027
55
NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, // 030-037
56
NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, // 040-047 !"#$%&'
57
NUL, NUL, NUL, 62, NUL, NUL, NUL, 63, // 050-057 ()*+,-./
58
52, 53, 54, 55, 56, 57, 58, 59, // 060-067 01234567
59
60, 61, NUL, NUL, NUL, EOF, NUL, NUL, // 070-077 89:;<=>?
60

61       NUL, 0, 1, 2, 3, 4, 5, 6, // 100-107 @ABCDEFG
62
7, 8, 9, 10, 11, 12, 13, 14, // 110-117 HIJKLMNO
63
15, 16, 17, 18, 19, 20, 21, 22, // 120-127 PQRSTUVW
64
23, 24, 25, NUL, NUL, NUL, NUL, NUL, // 130-137 XYZ[\]^_
65
NUL, 26, 27, 28, 29, 30, 31, 32, // 140-147 `abcdefg
66
33, 34, 35, 36, 37, 38, 39, 40, // 150-157 hijklmno
67
41, 42, 43, 44, 45, 46, 47, 48, // 160-167 pqrstuvw
68
49, 50, 51, NUL, NUL, NUL, NUL, NUL, // 170-177 xyz{|}~
69

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

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

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