KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > jcorporate > expresso > core > misc > CookieBase64


1 /* ====================================================================
2  * The Jcorporate Apache Style Software License, Version 1.2 05-07-2002
3  *
4  * Copyright (c) 1995-2002 Jcorporate Ltd. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in
15  * the documentation and/or other materials provided with the
16  * distribution.
17  *
18  * 3. The end-user documentation included with the redistribution,
19  * if any, must include the following acknowledgment:
20  * "This product includes software developed by Jcorporate Ltd.
21  * (http://www.jcorporate.com/)."
22  * Alternately, this acknowledgment may appear in the software itself,
23  * if and wherever such third-party acknowledgments normally appear.
24  *
25  * 4. "Jcorporate" and product names such as "Expresso" must
26  * not be used to endorse or promote products derived from this
27  * software without prior written permission. For written permission,
28  * please contact info@jcorporate.com.
29  *
30  * 5. Products derived from this software may not be called "Expresso",
31  * or other Jcorporate product names; nor may "Expresso" or other
32  * Jcorporate product names appear in their name, without prior
33  * written permission of Jcorporate Ltd.
34  *
35  * 6. No product derived from this software may compete in the same
36  * market space, i.e. framework, without prior written permission
37  * of Jcorporate Ltd. For written permission, please contact
38  * partners@jcorporate.com.
39  *
40  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
41  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
42  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
43  * DISCLAIMED. IN NO EVENT SHALL JCORPORATE LTD OR ITS CONTRIBUTORS
44  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
45  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
46  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
47  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
48  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
49  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
50  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51  * SUCH DAMAGE.
52  * ====================================================================
53  *
54  * This software consists of voluntary contributions made by many
55  * individuals on behalf of the Jcorporate Ltd. Contributions back
56  * to the project(s) are encouraged when you make modifications.
57  * Please send them to support@jcorporate.com. For more information
58  * on Jcorporate Ltd. and its products, please see
59  * <http://www.jcorporate.com/>.
60  *
61  * Portions of this software are based upon other open source
62  * products and are subject to their respective licenses.
63  */

64
65 package com.jcorporate.expresso.core.misc;
66
67
68 /**
69  * Proprietary Base64-like encoding class that makes sure there are no special
70  * characters that are "illegal" to cookies.
71  *
72  * @author Michael Rimov
73  */

74 public class CookieBase64 {
75     public CookieBase64() {
76     }
77
78     static final private int bytesPerLine = 80; // number of bytes per line
79

80     /* This array maps the characters to their 6 bit values */
81     private final static char[] vec = {
82         'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', // 0
83
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', // 1
84
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', // 2
85
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', // 3
86
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', // 4
87
'o', 'p', 'q', 'r', 's', 't', 'u', 'v', // 5
88
'w', 'x', 'y', 'z', '0', '1', '2', '3', // 6
89
'4', '5', '6', '7', '8', '9', ',', '.' // 7
90
};
91     private final static byte padding = (byte) '=';
92
93     /**
94      * @param inByte
95      * @return
96      */

97     static private byte convertToNumber(byte inByte) {
98         if (inByte >= 'A' && inByte <= 'Z') {
99             return (byte) (inByte - 'A');
100         }
101         if (inByte >= 'a' && inByte <= 'z') {
102             return (byte) (inByte - 'a' + 26);
103         }
104         if (inByte >= '0' && inByte <= '9') {
105             return (byte) (inByte - '0' + 52);
106         }
107         if (inByte == ',') {
108             return (62);
109         }
110         if (inByte == '.') {
111             return (63);
112         }
113
114         return (-1);
115     } /* convertToNumber(byte) */
116
117     /**
118      * decode - Decodes a Base64 encoded string back into its original
119      * binary format. If the data is not a proper base64 encoded string,
120      * it might throw an ArrayIndexOutOfBoundsException.
121      *
122      * @param data the data to decode
123      * @return
124      */

125     static private byte[] decode(String JavaDoc data)
126             throws IllegalArgumentException JavaDoc {
127
128         //Check for NULL
129
if (data == null) {
130             throw new IllegalArgumentException JavaDoc("Base64.decode: data must not be null");
131         }
132         //Check to see if data is proper length
133
if (data.length() % 4 != 0) {
134             throw new IllegalArgumentException JavaDoc("Base64.decode: data it not of proper length");
135         }
136
137         byte[] inputBuffer = data.getBytes();
138         int validInputCount = 0;
139         byte[] inBuffer = new byte[inputBuffer.length];
140         int dataLength = inputBuffer.length;
141
142         //We use the same input and output buffer since
143
// the value will be the same
144
//
145
//Preprocess -- Strip the LF's et al
146
//
147
int i;
148
149         for (i = 0; i < dataLength; i++) {
150             byte temp = convertToNumber(inputBuffer[i]);
151
152             if (temp >= 0) {
153                 inBuffer[i] = temp;
154                 validInputCount++;
155             }
156         }
157
158         byte[] outBuffer = new byte[dataLength];
159         int startOut = 0;
160         int startIn = 0;
161
162         while (validInputCount > startIn) {
163             int dataLen = validInputCount;
164
165             if (dataLen - startIn > 3) {
166                 outBuffer[startOut] = (byte) ((inBuffer[startIn] << 2) +
167                         (inBuffer[startIn + 1] >>> 4));
168                 outBuffer[startOut + 1] = (byte) ((inBuffer[startIn + 1] << 4) +
169                         (inBuffer[startIn + 2] >>> 2));
170                 outBuffer[startOut + 2] = (byte) ((inBuffer[startIn + 2] << 6) +
171                         (inBuffer[startIn + 3]));
172                 startOut += 3;
173                 startIn += 4;
174             } else if (dataLen - startIn > 2) {
175                 outBuffer[startOut] = (byte) ((inBuffer[startIn] << 2) +
176                         (inBuffer[startIn + 1] >>> 4));
177                 outBuffer[startOut + 1] = (byte) ((inBuffer[startIn + 1] << 4) +
178                         (inBuffer[startIn + 2] >>> 2));
179                 startOut += 2;
180                 startIn += 3;
181             } else if (dataLen - startIn > 1) {
182                 outBuffer[startOut] = (byte) ((inBuffer[startIn] << 2) +
183                         (inBuffer[startIn + 1] >>> 4));
184                 startOut += 1;
185                 startIn += 2;
186             } else {
187                 throw new IllegalStateException JavaDoc("com.jcorporate.expresso.core.misc." +
188                         "Base64.Decode: Corrupt Input Data");
189             }
190         }
191
192         //Copy the final bytes over to a real output array
193
byte[] finalOutput = new byte[startOut];
194
195         for (i = 0; i < startOut; i++) {
196             finalOutput[i] = outBuffer[i];
197         }
198
199         inBuffer = null;
200         outBuffer = null;
201
202         return finalOutput;
203     } /* decode(String) */
204
205
206     /**
207      * <B>Note: this function does not process stricly compliant Base64
208      * code. To process strictly compliant Base64 encoded strings, use encode
209      * and decode functions with padding</B>
210      * <p/>
211      * Decodes a Base64 encoded string back into its original binary format.
212      * The only difference from decode is that this function will bad the
213      * end with as many ='s as necessary to make things work properly.
214      *
215      * @param data the Base64 encoded string
216      * @return the byte array of the original data.
217      * @throws IllegalArgumentException if the input data is null or zero bytes.
218      */

219     static public byte[] decodeNoPadding(String JavaDoc data)
220             throws IllegalArgumentException JavaDoc {
221         String JavaDoc myName = "Base64.decodeNoPadding";
222
223         if (data == null) {
224             throw new IllegalArgumentException JavaDoc(myName + " parameter 'data'" +
225                     " must not be null");
226         }
227         if (data.length() == 0) {
228             throw new IllegalArgumentException JavaDoc(myName + " parameter 'data'" +
229                     " must not be greater than zero length");
230         }
231         //Append as many zeros as necessary to make things work.
232
for (; data.length() % 4 != 0; data = data + "=") {
233             ;
234         }
235
236         return decode(data);
237     } /* decodeNoPadding(String) */
238
239
240     /**
241      * encode - Encodes a binary byte array into an Ascii String (including 80
242      * column line wrap.
243      *
244      * @param inBuffer[] the data to encode
245      * @return
246      */

247     static private String JavaDoc encode(byte[] inBuffer)
248             throws IllegalArgumentException JavaDoc {
249         if (inBuffer.length == 0) {
250             throw new IllegalArgumentException JavaDoc("Base64.encode: " +
251                     "inBuffer must be > zero bytes in length");
252         }
253
254         int dataSize = inBuffer.length;
255         int startIn = 0;
256         int startOut = 0;
257
258         //Create an output buffer that's twice the size of the input buffer
259
//that way we have enough room for sure
260
byte[] outBuffer;
261
262         if (dataSize < 4) {
263             outBuffer = new byte[4];
264         } else {
265             outBuffer = new byte[dataSize * 2];
266         }
267         //Iteratate
268
while (startIn < dataSize) {
269             int dataLen = inBuffer.length;
270             byte a;
271             byte b;
272             byte c;
273
274             //Check for linewrap
275
if ((startOut % bytesPerLine) + 4 > bytesPerLine) {
276                 outBuffer[startOut] = (byte) '\r';
277                 outBuffer[startOut + 1] = (byte) '\n';
278                 startOut += 2;
279             }
280             if (dataLen - startIn > 2) {
281                 a = inBuffer[startIn];
282                 b = inBuffer[startIn + 1];
283                 c = inBuffer[startIn + 2];
284                 outBuffer[startOut] = (byte) vec[(a >>> 2) & 0x3F];
285                 outBuffer[startOut + 1] = (byte) vec[((a << 4) & 0x30) +
286                         ((b >>> 4) & 0xf)];
287                 outBuffer[startOut + 2] = (byte) vec[((b << 2) & 0x3c) +
288                         ((c >>> 6) & 0x3)];
289                 outBuffer[startOut + 3] = (byte) vec[c & 0x3F];
290                 startOut += 4;
291                 startIn += 3;
292             } else if (dataLen - startIn == 1) {
293                 a = inBuffer[startIn];
294                 b = 0;
295                 c = 0;
296                 outBuffer[startOut] = (byte) vec[(a >>> 2) & 0x3F];
297                 outBuffer[startOut + 1] = (byte) vec[((a << 4) & 0x30) +
298                         ((b >>> 4) & 0xf)];
299                 outBuffer[startOut + 2] = padding;
300                 outBuffer[startOut + 3] = padding;
301                 startOut += 4;
302                 startIn += 2;
303             } else if (dataLen - startIn == 2) {
304                 a = inBuffer[startIn];
305                 b = inBuffer[startIn + 1];
306                 c = 0;
307                 outBuffer[startOut] = (byte) vec[(a >>> 2) & 0x3F];
308                 outBuffer[startOut + 1] = (byte) vec[((a << 4) & 0x30) +
309                         ((b >>> 4) & 0xf)];
310                 outBuffer[startOut + 2] = (byte) vec[((b << 2) & 0x3c) +
311                         ((c >>> 6) & 0x3)];
312                 outBuffer[startOut + 3] = padding;
313                 startOut += 4;
314                 startIn += 2;
315             }
316         }
317
318         return new String JavaDoc(outBuffer, 0, startOut);
319     } /* encode(byte) */
320
321
322     /* */
323     /* */
324     /* Encoding Part */
325     /* */
326     /* */
327     /**
328      * <B>Note: this function does not process stricly compliant Base64
329      * code. To process strictly compliant Base64 encoded strings, use encode
330      * and decode functions with padding</B>
331      * <p/>
332      * Encodes a binary bite array into Base64 coding. The difference between
333      * this and the other encode function, is that this function strips all
334      * padding from the final result before returning
335      *
336      * @param inBuffer[] the byte array to encode.
337      * @return a string that is the Base64 equiv of the input data without
338      * padding characters
339      * @throws IllegalArgumentException if the input data is null or zero bytes.
340      */

341     static public String JavaDoc encodeNoPadding(byte[] inBuffer)
342             throws IllegalArgumentException JavaDoc {
343         String JavaDoc stringWithPadding = encode(inBuffer);
344         int equalsPlacement = stringWithPadding.indexOf((int) '=');
345
346         return (equalsPlacement != -1)
347                 ? (stringWithPadding.substring(0, equalsPlacement))
348                 : (stringWithPadding);
349     } /* encodeNoPaggding(byte) */
350
351
352 }
Popular Tags