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