1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20 package org.apache.geronimo.mail.util;
21
22 import java.io.ByteArrayOutputStream;
23 import java.io.FilterInputStream;
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.io.UnsupportedEncodingException;
27
28 /**
29 * An implementation of a FilterOutputStream that decodes the
30 * stream data in Q-P encoding format. This version does the
31 * decoding "on the fly" rather than decoding a single block of
32 * data. Since this version is intended for use by the MimeUtilty class,
33 * it also handles line breaks in the encoded data.
34 */
35 public class QuotedPrintableDecoderStream extends FilterInputStream {
36 // our decoder for processing the data
37 protected QuotedPrintableEncoder decoder;
38
39
40 /**
41 * Stream constructor.
42 *
43 * @param in The InputStream this stream is filtering.
44 */
45 public QuotedPrintableDecoderStream(InputStream in) {
46 super(in);
47 decoder = new QuotedPrintableEncoder();
48 }
49
50 // in order to function as a filter, these streams need to override the different
51 // read() signatures.
52
53
54 /**
55 * Read a single byte from the stream.
56 *
57 * @return The next byte of the stream. Returns -1 for an EOF condition.
58 * @exception IOException
59 */
60 public int read() throws IOException
61 {
62 // just get a single byte from the decoder
63 return decoder.decode(in);
64 }
65
66
67 /**
68 * Read a buffer of data from the input stream.
69 *
70 * @param buffer The target byte array the data is placed into.
71 * @param offset The starting offset for the read data.
72 * @param length How much data is requested.
73 *
74 * @return The number of bytes of data read.
75 * @exception IOException
76 */
77 public int read(byte [] buffer, int offset, int length) throws IOException {
78
79 for (int i = 0; i < length; i++) {
80 int ch = decoder.decode(in);
81 if (ch == -1) {
82 return i == 0 ? -1 : i;
83 }
84 buffer[offset + i] = (byte)ch;
85 }
86
87 return length;
88 }
89
90
91 /**
92 * Indicate whether this stream supports the mark() operation.
93 *
94 * @return Always returns false.
95 */
96 public boolean markSupported() {
97 return false;
98 }
99
100
101 /**
102 * Give an estimate of how much additional data is available
103 * from this stream.
104 *
105 * @return Always returns -1.
106 * @exception IOException
107 */
108 public int available() throws IOException {
109 // this is almost impossible to determine at this point
110 return -1;
111 }
112 }
113
114