KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > mail > imap > protocol > BASE64MailboxDecoder


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the "License"). You may not use this file except
5  * in compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * glassfish/bootstrap/legal/CDDLv1.0.txt or
9  * https://glassfish.dev.java.net/public/CDDLv1.0.html.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * HEADER in each file and include the License file at
15  * glassfish/bootstrap/legal/CDDLv1.0.txt. If applicable,
16  * add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your
18  * own identifying information: Portions Copyright [yyyy]
19  * [name of copyright owner]
20  */

21
22 /*
23  * @(#)BASE64MailboxDecoder.java 1.6 05/08/29
24  *
25  * Copyright 1996-2005 Sun Microsystems, Inc. All Rights Reserved.
26  */

27
28 package com.sun.mail.imap.protocol;
29
30 import java.text.StringCharacterIterator JavaDoc;
31 import java.text.CharacterIterator JavaDoc;
32
33 /**
34  * See the BASE64MailboxEncoder for a description of the RFC2060 and how
35  * mailbox names should be encoded. This class will do the correct decoding
36  * for mailbox names.
37  *
38  * @version 1.6, 05/08/29
39  * @author Christopher Cotton
40  */

41
42 public class BASE64MailboxDecoder {
43     
44     public static String JavaDoc decode(String JavaDoc original) {
45     if (original == null || original.length() == 0)
46         return original;
47
48     boolean changedString = false;
49     int copyTo = 0;
50     // it will always be less than the original
51
char[] chars = new char[original.length()];
52     StringCharacterIterator JavaDoc iter = new StringCharacterIterator JavaDoc(original);
53     
54     for(char c = iter.first(); c != CharacterIterator.DONE;
55         c = iter.next()) {
56
57         if (c == '&') {
58         changedString = true;
59         copyTo = base64decode(chars, copyTo, iter);
60         } else {
61         chars[copyTo++] = c;
62         }
63     }
64     
65     // now create our string from the char array
66
if (changedString) {
67         return new String JavaDoc(chars, 0, copyTo);
68     } else {
69         return original;
70     }
71     }
72
73
74     protected static int base64decode(char[] buffer, int offset,
75                       CharacterIterator JavaDoc iter) {
76     boolean firsttime = true;
77     int leftover = -1;
78     char testing = 0;
79
80     while(true) {
81         // get the first byte
82
byte orig_0 = (byte) iter.next();
83         if (orig_0 == -1) break; // no more chars
84
if (orig_0 == '-') {
85         if (firsttime) {
86             // means we got the string "&-" which is turned into a "&"
87
buffer[offset++] = '&';
88         }
89         // we are done now
90
break;
91         }
92         firsttime = false;
93         
94         // next byte
95
byte orig_1 = (byte) iter.next();
96         if (orig_1 == -1 || orig_1 == '-')
97         break; // no more chars, invalid base64
98

99         byte a, b, current;
100         a = pem_convert_array[orig_0 & 0xff];
101         b = pem_convert_array[orig_1 & 0xff];
102         // The first decoded byte
103
current = (byte)(((a << 2) & 0xfc) | ((b >>> 4) & 3));
104
105         // use the leftover to create a Unicode Character (2 bytes)
106
if (leftover != -1) {
107         buffer[offset++] = (char)(leftover << 8 | (current & 0xff));
108         leftover = -1;
109         } else {
110         leftover = current & 0xff;
111         }
112         
113         byte orig_2 = (byte) iter.next();
114         if (orig_2 == '=') { // End of this BASE64 encoding
115
continue;
116         } else if (orig_2 == -1 || orig_2 == '-') {
117             break; // no more chars
118
}
119                 
120         // second decoded byte
121
a = b;
122         b = pem_convert_array[orig_2 & 0xff];
123         current = (byte)(((a << 4) & 0xf0) | ((b >>> 2) & 0xf));
124
125         // use the leftover to create a Unicode Character (2 bytes)
126
if (leftover != -1) {
127         buffer[offset++] = (char)(leftover << 8 | (current & 0xff));
128         leftover = -1;
129         } else {
130         leftover = current & 0xff;
131         }
132
133         byte orig_3 = (byte) iter.next();
134         if (orig_3 == '=') { // End of this BASE64 encoding
135
continue;
136         } else if (orig_3 == -1 || orig_3 == '-') {
137             break; // no more chars
138
}
139         
140         // The third decoded byte
141
a = b;
142         b = pem_convert_array[orig_3 & 0xff];
143         current = (byte)(((a << 6) & 0xc0) | (b & 0x3f));
144         
145         // use the leftover to create a Unicode Character (2 bytes)
146
if (leftover != -1) {
147         testing = (char)((int)leftover << 8 | ((int) current & 0xff));
148         buffer[offset++] = (char)(leftover << 8 | (current & 0xff));
149         leftover = -1;
150         } else {
151         leftover = current & 0xff;
152         }
153     }
154     
155     return offset;
156     }
157
158     /**
159      * This character array provides the character to value map
160      * based on RFC1521, but with the modification from RFC2060
161      * which changes the '/' to a ','.
162      */

163
164     protected final static char pem_array[] = {
165     'A','B','C','D','E','F','G','H', // 0
166
'I','J','K','L','M','N','O','P', // 1
167
'Q','R','S','T','U','V','W','X', // 2
168
'Y','Z','a','b','c','d','e','f', // 3
169
'g','h','i','j','k','l','m','n', // 4
170
'o','p','q','r','s','t','u','v', // 5
171
'w','x','y','z','0','1','2','3', // 6
172
'4','5','6','7','8','9','+',',' // 7
173
};
174
175     protected final static byte pem_convert_array[] = new byte[256];
176
177     static {
178     for (int i = 0; i < 255; i++)
179         pem_convert_array[i] = -1;
180     for(int i = 0; i < pem_array.length; i++)
181         pem_convert_array[pem_array[i]] = (byte) i;
182     }
183 }
184
Popular Tags