QPDecoderStreampublic class QPDecoderStream extends FilterInputStream This class implements a QP Decoder. It is implemented as
a FilterInputStream, so one can just wrap this class around
any input stream and read bytes from this filter. The decoding
is done as the bytes are read out. |
Fields Summary |
---|
protected byte[] | ba | protected int | spaces |
Constructors Summary |
---|
public QPDecoderStream(InputStream in)Create a Quoted Printable decoder that decodes the specified
input stream.
super(new PushbackInputStream(in, 2)); // pushback of size=2
|
Methods Summary |
---|
public int | available()Returns the number of bytes that can be read from this input
stream without blocking. The QP algorithm does not permit
a priori knowledge of the number of bytes after decoding, so
this method just invokes the available method
of the original input stream.
// This is bogus ! We don't really know how much
// bytes are available *after* decoding
return in.available();
| public boolean | markSupported()Tests if this input stream supports marks. Currently this class
does not support marks
return false;
| public int | read()Read the next decoded byte from this input stream. The byte
is returned as an int in the range 0
to 255 . If no byte is available because the end of
the stream has been reached, the value -1 is returned.
This method blocks until input data is available, the end of the
stream is detected, or an exception is thrown.
if (spaces > 0) {
// We have cached space characters, return one
spaces--;
return ' ";
}
int c = in.read();
if (c == ' ") {
// Got space, keep reading till we get a non-space char
while ((c = in.read()) == ' ")
spaces++;
if (c == '\r" || c == '\n" || c == -1)
// If the non-space char is CR/LF/EOF, the spaces we got
// so far is junk introduced during transport. Junk 'em.
spaces = 0;
else {
// The non-space char is NOT CR/LF, the spaces are valid.
((PushbackInputStream)in).unread(c);
c = ' ";
}
return c; // return either <SPACE> or <CR/LF>
}
else if (c == '=") {
// QP Encoded atom. Decode the next two bytes
int a = in.read();
if (a == '\n") {
/* Hmm ... not really confirming QP encoding, but lets
* allow this as a LF terminated encoded line .. and
* consider this a soft linebreak and recurse to fetch
* the next char.
*/
return read();
} else if (a == '\r") {
// Expecting LF. This forms a soft linebreak to be ignored.
int b = in.read();
if (b != '\n")
/* Not really confirming QP encoding, but
* lets allow this as well.
*/
((PushbackInputStream)in).unread(b);
return read();
} else if (a == -1) {
// Not valid QP encoding, but we be nice and tolerant here !
return -1;
} else {
ba[0] = (byte)a;
ba[1] = (byte)in.read();
try {
return ASCIIUtility.parseInt(ba, 0, 2, 16);
} catch (NumberFormatException nex) {
/*
System.err.println(
"Illegal characters in QP encoded stream: " +
ASCIIUtility.toString(ba, 0, 2)
);
*/
((PushbackInputStream)in).unread(ba);
return c;
}
}
}
return c;
| public int | read(byte[] buf, int off, int len)Reads up to len decoded bytes of data from this input stream
into an array of bytes. This method blocks until some input is
available.
int i, c;
for (i = 0; i < len; i++) {
if ((c = read()) == -1) {
if (i == 0) // At end of stream, so we should
i = -1; // return -1 , NOT 0.
break;
}
buf[off+i] = (byte)c;
}
return i;
| public long | skip(long n)Skips over and discards n bytes of data from this stream.
long skipped = 0;
while (n-- > 0 && read() >= 0)
skipped++;
return skipped;
|
|