KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > mail > util > QPEncoderStream


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  * @(#)QPEncoderStream.java 1.7 05/08/29
24  *
25  * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved.
26  */

27
28 package com.sun.mail.util;
29
30 import java.io.*;
31
32 /**
33  * This class implements a Quoted Printable Encoder. It is implemented as
34  * a FilterOutputStream, so one can just wrap this class around
35  * any output stream and write bytes into this filter. The Encoding
36  * is done as the bytes are written out.
37  *
38  * @author John Mani
39  */

40
41 public class QPEncoderStream extends FilterOutputStream {
42     private int count = 0; // number of bytes that have been output
43
private int bytesPerLine; // number of bytes per line
44
private boolean gotSpace = false;
45     private boolean gotCR = false;
46
47     /**
48      * Create a QP encoder that encodes the specified input stream
49      * @param out the output stream
50      * @param bytesPerLine the number of bytes per line. The encoder
51      * inserts a CRLF sequence after this many number
52      * of bytes.
53      */

54     public QPEncoderStream(OutputStream out, int bytesPerLine) {
55     super(out);
56     // Subtract 1 to account for the '=' in the soft-return
57
// at the end of a line
58
this.bytesPerLine = bytesPerLine - 1;
59     }
60
61     /**
62      * Create a QP encoder that encodes the specified input stream.
63      * Inserts the CRLF sequence after outputting 76 bytes.
64      * @param out the output stream
65      */

66     public QPEncoderStream(OutputStream out) {
67     this(out, 76);
68     }
69
70     /**
71      * Encodes <code>len</code> bytes from the specified
72      * <code>byte</code> array starting at offset <code>off</code> to
73      * this output stream.
74      *
75      * @param b the data.
76      * @param off the start offset in the data.
77      * @param len the number of bytes to write.
78      * @exception IOException if an I/O error occurs.
79      */

80     public void write(byte[] b, int off, int len) throws IOException {
81     for (int i = 0; i < len; i++)
82         write(b[off + i]);
83     }
84
85     /**
86      * Encodes <code>b.length</code> bytes to this output stream.
87      * @param b the data to be written.
88      * @exception IOException if an I/O error occurs.
89      */

90     public void write(byte[] b) throws IOException {
91     write(b, 0, b.length);
92     }
93
94     /**
95      * Encodes the specified <code>byte</code> to this output stream.
96      * @param c the <code>byte</code>.
97      * @exception IOException if an I/O error occurs.
98      */

99     public void write(int c) throws IOException {
100     c = c & 0xff; // Turn off the MSB.
101
if (gotSpace) { // previous character was <SPACE>
102
if (c == '\r' || c == '\n')
103         // if CR/LF, we need to encode the <SPACE> char
104
output(' ', true);
105         else // no encoding required, just output the char
106
output(' ', false);
107         gotSpace = false;
108     }
109
110     if (c == '\r') {
111         gotCR = true;
112         outputCRLF();
113     } else {
114         if (c == '\n') {
115         if (gotCR)
116             // This is a CRLF sequence, we already output the
117
// corresponding CRLF when we got the CR, so ignore this
118
;
119         else
120             outputCRLF();
121         } else if (c == ' ') {
122         gotSpace = true;
123         } else if (c < 040 || c >= 0177 || c == '=')
124         // Encoding required.
125
output(c, true);
126         else // No encoding required
127
output(c, false);
128         // whatever it was, it wasn't a CR
129
gotCR = false;
130     }
131     }
132
133     /**
134      * Flushes this output stream and forces any buffered output bytes
135      * to be encoded out to the stream.
136      * @exception IOException if an I/O error occurs.
137      */

138     public void flush() throws IOException {
139     out.flush();
140     }
141
142     /**
143      * Forces any buffered output bytes to be encoded out to the stream
144      * and closes this output stream
145      */

146     public void close() throws IOException {
147     out.close();
148     }
149
150     private void outputCRLF() throws IOException {
151     out.write('\r');
152     out.write('\n');
153     count = 0;
154     }
155
156     // The encoding table
157
private final static char hex[] = {
158     '0','1', '2', '3', '4', '5', '6', '7',
159     '8','9', 'A', 'B', 'C', 'D', 'E', 'F'
160     };
161
162     protected void output(int c, boolean encode) throws IOException {
163     if (encode) {
164         if ((count += 3) > bytesPerLine) {
165         out.write('=');
166             out.write('\r');
167             out.write('\n');
168         count = 3; // set the next line's length
169
}
170         out.write('=');
171         out.write(hex[c >> 4]);
172         out.write(hex[c & 0xf]);
173     } else {
174         if (++count > bytesPerLine) {
175         out.write('=');
176             out.write('\r');
177             out.write('\n');
178         count = 1; // set the next line's length
179
}
180         out.write(c);
181     }
182     }
183
184     /**** begin TEST program ***
185     public static void main(String argv[]) throws Exception {
186         FileInputStream infile = new FileInputStream(argv[0]);
187         QPEncoderStream encoder = new QPEncoderStream(System.out);
188         int c;
189  
190         while ((c = infile.read()) != -1)
191             encoder.write(c);
192         encoder.close();
193     }
194     *** end TEST program ***/

195 }
196
Popular Tags