KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > columba > ristretto > coder > Base64EncoderInputStream


1 /* ***** BEGIN LICENSE BLOCK *****
2  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3  *
4  * The contents of this file are subject to the Mozilla Public License Version
5  * 1.1 (the "License"); you may not use this file except in compliance with
6  * the License. You may obtain a copy of the License at
7  * http://www.mozilla.org/MPL/
8  *
9  * Software distributed under the License is distributed on an "AS IS" basis,
10  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11  * for the specific language governing rights and limitations under the
12  * License.
13  *
14  * The Original Code is Ristretto Mail API.
15  *
16  * The Initial Developers of the Original Code are
17  * Timo Stich and Frederik Dietz.
18  * Portions created by the Initial Developers are Copyright (C) 2004
19  * All Rights Reserved.
20  *
21  * Contributor(s):
22  *
23  * Alternatively, the contents of this file may be used under the terms of
24  * either the GNU General Public License Version 2 or later (the "GPL"), or
25  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26  * in which case the provisions of the GPL or the LGPL are applicable instead
27  * of those above. If you wish to allow use of your version of this file only
28  * under the terms of either the GPL or the LGPL, and not to allow others to
29  * use your version of this file under the terms of the MPL, indicate your
30  * decision by deleting the provisions above and replace them with the notice
31  * and other provisions required by the GPL or the LGPL. If you do not delete
32  * the provisions above, a recipient may use your version of this file under
33  * the terms of any one of the MPL, the GPL or the LGPL.
34  *
35  * ***** END LICENSE BLOCK ***** */

36 package org.columba.ristretto.coder;
37
38
39 import java.io.FilterInputStream JavaDoc;
40 import java.io.IOException JavaDoc;
41 import java.io.InputStream JavaDoc;
42
43 /**
44  * FilterInputStream that encodes a bytestream into a base64 encoded charstream.
45  *
46  * <br>
47  * <b>RFC(s):</b> 2045
48  *
49  * @author Timo Stich <tstich@users.sourceforge.net>
50  */

51 public class Base64EncoderInputStream extends FilterInputStream JavaDoc {
52
53
54     private static final byte[] table = {
55          65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
56          75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
57          85, 86, 87, 88, 89, 90, 97, 98, 99,100,
58         101,102,103,104,105,106,107,108,109,110,
59         111,112,113,114,115,116,117,118,119,120,
60         121,122, 48, 49, 50, 51, 52, 53, 54, 55,
61          56, 57, 43, 47 };
62
63     private byte[] outBytes;
64     private byte[] inBytes;
65     private int blockCount;
66     private int pos;
67     private int available;
68
69     /**
70      * Constructs a Base64EncoderInputStream.
71      *
72      * @param in the input bytestream
73      */

74     public Base64EncoderInputStream( InputStream JavaDoc in )
75     {
76         super(in);
77         outBytes = new byte[4];
78         inBytes = new byte[3];
79     }
80
81
82     
83     /**
84      * Reads 3 bytes from the inputstream and decodes it
85      * into 4 characters encoded in base64.
86      *
87      * @return number of bytes read
88      * @throws IOException
89      */

90     private int encodeNextPack() throws IOException JavaDoc {
91         if( blockCount == 24) {
92             outBytes[0] = '\r';
93             outBytes[1] = '\n';
94             blockCount = 0;
95             return 2;
96         }
97
98         int read = in.read( inBytes );
99         
100         if( read == 3 ) {
101             outBytes[0] = table[(byte)(0x03F & (inBytes[0]>>2))];
102             outBytes[1] = table[(byte)((0x03F & (inBytes[0]<<4)) | (0x00F & (inBytes[1]>>4)))];
103             outBytes[2] = table[(byte)((0x03F & (inBytes[1]<<2)) | (0x003 & (inBytes[2]>>6)))];
104             outBytes[3] = table[(byte)(0x03F & inBytes[2])];
105
106             blockCount++;
107         } else if (read > 0){
108         
109             outBytes[0] = table[(byte)(0x03F & (inBytes[0]>>2))];
110             
111             if( read == 2 ) {
112                 outBytes[1] = table[(byte)((0x03F & (inBytes[0]<<4)) | (0x00F & (inBytes[1]>>4)))];
113                 outBytes[2] = table[(byte)(0x03F & (inBytes[1]<<2) )];
114                 outBytes[3] = '=';
115             } else {
116                 outBytes[1] = table[(byte)(0x03F & (inBytes[0]<<4))];
117                 outBytes[2] = '=';
118                 outBytes[3] = '=';
119             }
120         } else {
121             return -1;
122         }
123         
124         return 4;
125     }
126
127     /**
128      * @see java.io.InputStream#read()
129      */

130     public int read() throws IOException JavaDoc {
131         if( pos == available ) {
132             available = encodeNextPack();
133             pos = 0;
134         }
135         
136         if( available == -1) return -1;
137         
138         return outBytes[pos++];
139     }
140     
141     /**
142      * @see java.io.InputStream#read(byte[], int, int)
143      */

144     public int read(byte[] arg0, int arg1, int arg2) throws IOException JavaDoc {
145         int next;
146         for( int i=0; i<arg2; i++) {
147             next = read();
148             if( next == -1 ) {
149                 if( i == 0 ) {
150                     return -1;
151                 } else {
152                     return i;
153                 }
154             }
155             arg0[arg1+i] = (byte) next;
156         }
157         return arg2;
158     }
159     
160
161     /**
162      * @see java.io.InputStream#available()
163      */

164     public int available() throws IOException JavaDoc {
165         return (int) (in.available() * 1.33);
166     }
167
168 }
169
Popular Tags