diff options
Diffstat (limited to 'pg/src/main/java/org/spongycastle/openpgp/PGPCompressedData.java')
-rw-r--r-- | pg/src/main/java/org/spongycastle/openpgp/PGPCompressedData.java | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/pg/src/main/java/org/spongycastle/openpgp/PGPCompressedData.java b/pg/src/main/java/org/spongycastle/openpgp/PGPCompressedData.java new file mode 100644 index 00000000..9269dfee --- /dev/null +++ b/pg/src/main/java/org/spongycastle/openpgp/PGPCompressedData.java @@ -0,0 +1,153 @@ +package org.spongycastle.openpgp; + +import java.io.EOFException; +import java.io.IOException; +import java.io.InputStream; +import java.util.zip.Inflater; +import java.util.zip.InflaterInputStream; + +import org.spongycastle.apache.bzip2.CBZip2InputStream; +import org.spongycastle.bcpg.BCPGInputStream; +import org.spongycastle.bcpg.CompressedDataPacket; +import org.spongycastle.bcpg.CompressionAlgorithmTags; +import org.spongycastle.bcpg.PacketTags; + +/** + * A PGP compressed data object. + */ +public class PGPCompressedData + implements CompressionAlgorithmTags +{ + CompressedDataPacket data; + + /** + * Construct a compressed data object, reading a single {@link PacketTags#COMPRESSED_DATA} + * packet from the stream. + * + * @param pIn a PGP input stream, with a compressed data packet as the current packet. + * @throws IOException if an error occurs reading the packet from the stream. + */ + public PGPCompressedData( + BCPGInputStream pIn) + throws IOException + { + data = (CompressedDataPacket)pIn.readPacket(); + } + + /** + * Return the {@link CompressionAlgorithmTags compression algorithm} used for this packet. + * + * @return the compression algorithm code + */ + public int getAlgorithm() + { + return data.getAlgorithm(); + } + + /** + * Return the raw input stream contained in the object. + * <p/> + * Note that this stream is shared with the decompression stream, so consuming the returned + * stream will affect decompression. + * + * @return the raw data in the compressed data packet. + */ + public InputStream getInputStream() + { + return data.getInputStream(); + } + + /** + * Return an input stream that decompresses and returns data in the compressed packet. + * + * @return a stream over the uncompressed data. + * @throws PGPException if an error occurs constructing the decompression stream. + */ + public InputStream getDataStream() + throws PGPException + { + if (this.getAlgorithm() == UNCOMPRESSED) + { + return this.getInputStream(); + } + if (this.getAlgorithm() == ZIP) + { + return new InflaterInputStream(this.getInputStream(), new Inflater(true)) + { + // If the "nowrap" inflater option is used the stream can + // apparently overread - we override fill() and provide + // an extra byte for the end of the input stream to get + // around this. + // + // Totally weird... + // + protected void fill() throws IOException + { + if (eof) + { + throw new EOFException("Unexpected end of ZIP input stream"); + } + + len = this.in.read(buf, 0, buf.length); + + if (len == -1) + { + buf[0] = 0; + len = 1; + eof = true; + } + + inf.setInput(buf, 0, len); + } + + private boolean eof = false; + }; + } + if (this.getAlgorithm() == ZLIB) + { + return new InflaterInputStream(this.getInputStream()) + { + // If the "nowrap" inflater option is used the stream can + // apparently overread - we override fill() and provide + // an extra byte for the end of the input stream to get + // around this. + // + // Totally weird... + // + protected void fill() throws IOException + { + if (eof) + { + throw new EOFException("Unexpected end of ZIP input stream"); + } + + len = this.in.read(buf, 0, buf.length); + + if (len == -1) + { + buf[0] = 0; + len = 1; + eof = true; + } + + inf.setInput(buf, 0, len); + } + + private boolean eof = false; + }; + } + if (this.getAlgorithm() == BZIP2) + { + try + { + return new CBZip2InputStream(this.getInputStream()); + } + catch (IOException e) + { + throw new PGPException("I/O problem with stream: " + e, e); + } + } + + throw new PGPException("can't recognise compression algorithm: " + this.getAlgorithm()); + } +} |