Class AbstractLZ77CompressorInputStream
- All Implemented Interfaces:
Closeable,AutoCloseable,InputStreamStatistics
- Direct Known Subclasses:
BlockLZ4CompressorInputStream,SnappyCompressorInputStream
Assumes the stream consists of blocks of literal data and
back-references (called copies) in any order. Of course the first
block must be a literal block for the scheme to work - unless the
prefill method has been used to provide initial
data that is never returned by read but only used for
back-references.
Subclasses must override the three-arg read method
as the no-arg version delegates to it and the default
implementation delegates to the no-arg version, leading to infinite
mutual recursion and a StackOverflowError otherwise.
The contract for subclasses' read implementation is:
- keep track of the current state of the stream. Is it inside a literal block or a back-reference or in-between blocks?
- Use
readOneByte()to access the underlying stream directly. - If a new literal block starts, use
startLiteral(long)to tell this class about it and read the literal data usingreadLiteral(byte[], int, int)until it returns0.hasMoreDataInBlock()will returnfalsebefore the next call toreadLiteral(byte[], int, int)would return0. - If a new back-reference starts, use
startBackReference(int, long)to tell this class about it and read the literal data usingreadBackReference(byte[], int, int)until it returns0.hasMoreDataInBlock()will returnfalsebefore the next call toreadBackReference(byte[], int, int)would return0. - If the end of the stream has been reached, return
-1as this class' methods will never do so themselves.
readOneByte() and readLiteral(byte[], int, int) update the counter
for bytes read.
- Since:
- 1.14
-
Field Summary
FieldsModifier and TypeFieldDescriptionprivate intOffset of the current back-reference.private final byte[]Buffer to write decompressed bytes to for back-references, will be three times windowSize big.private longNumber of bytes still to be read from the current literal or back-reference.private final CountingInputStreamThe underlying stream to read compressed data fromprivate final byte[]private intIndex of the next byte to be read.private intuncompressed sizeprotected final ByteUtils.ByteSupplierSupplier that delegates toreadOneByte().private final intSize of the window - must be bigger than the biggest offset expected.private intOne behind the index of the last byte in the buffer that was written, i.e. -
Constructor Summary
ConstructorsConstructorDescriptionAbstractLZ77CompressorInputStream(InputStream is, int windowSize) Creates a new LZ77 input stream. -
Method Summary
Modifier and TypeMethodDescriptionintvoidclose()longintgetSize()Get the uncompressed size of the streamprotected final booleanIs there still data remaining inside the current block?voidprefill(byte[] data) Adds some initial data to fill the window with.intread()protected final intreadBackReference(byte[] b, int off, int len) Reads data from the current back-reference.private intreadFromBuffer(byte[] b, int off, int len) protected final intreadLiteral(byte[] b, int off, int len) Reads data from the current literal block.protected final intReads a single byte from the real input stream and ensures the data is accounted for.private voidprotected final voidstartBackReference(int offset, long length) Used by subclasses to signal the next block contains a back-reference with the given coordinates.protected final voidstartLiteral(long length) Used by subclasses to signal the next block contains the given amount of literal data.private voidtryToCopy(int bytesToCopy) private voidtryToReadLiteral(int bytesToRead) Methods inherited from class org.apache.commons.compress.compressors.CompressorInputStream
count, count, getBytesRead, getCount, getUncompressedCount, pushedBackBytesMethods inherited from class java.io.InputStream
mark, markSupported, nullInputStream, read, read, readAllBytes, readNBytes, readNBytes, reset, skip, skipNBytes, transferToMethods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitMethods inherited from interface org.apache.commons.compress.utils.InputStreamStatistics
getUncompressedCount
-
Field Details
-
windowSize
private final int windowSizeSize of the window - must be bigger than the biggest offset expected. -
buf
private final byte[] bufBuffer to write decompressed bytes to for back-references, will be three times windowSize big.Three times so we can slide the whole buffer a windowSize to the left once we've read twice windowSize and still have enough data inside of it to satisfy back-references.
-
writeIndex
private int writeIndexOne behind the index of the last byte in the buffer that was written, i.e. the next position to write to -
readIndex
private int readIndexIndex of the next byte to be read. -
in
The underlying stream to read compressed data from -
bytesRemaining
private long bytesRemainingNumber of bytes still to be read from the current literal or back-reference. -
backReferenceOffset
private int backReferenceOffsetOffset of the current back-reference. -
size
private int sizeuncompressed size -
oneByte
private final byte[] oneByte -
supplier
Supplier that delegates toreadOneByte().
-
-
Constructor Details
-
AbstractLZ77CompressorInputStream
Creates a new LZ77 input stream.- Parameters:
is- An InputStream to read compressed data fromwindowSize- Size of the window kept for back-references, must be bigger than the biggest offset expected.- Throws:
IOException- if reading failsIllegalArgumentException- if windowSize is not bigger than 0
-
-
Method Details
-
read
- Specified by:
readin classInputStream- Throws:
IOException
-
close
- Specified by:
closein interfaceAutoCloseable- Specified by:
closein interfaceCloseable- Overrides:
closein classInputStream- Throws:
IOException
-
available
public int available()- Overrides:
availablein classInputStream
-
getSize
public int getSize()Get the uncompressed size of the stream- Returns:
- the uncompressed size
-
prefill
public void prefill(byte[] data) Adds some initial data to fill the window with.This is used if the stream has been cut into blocks and back-references of one block may refer to data of the previous block(s). One such example is the LZ4 frame format using block dependency.
- Parameters:
data- the data to fill the window with.- Throws:
IllegalStateException- if the stream has already started to read data
-
getCompressedCount
public long getCompressedCount()- Specified by:
getCompressedCountin interfaceInputStreamStatistics- Returns:
- the amount of raw or compressed bytes read by the stream
- Since:
- 1.17
-
startLiteral
protected final void startLiteral(long length) Used by subclasses to signal the next block contains the given amount of literal data.- Parameters:
length- the length of the block- Throws:
IllegalArgumentException- if length is negative
-
hasMoreDataInBlock
protected final boolean hasMoreDataInBlock()Is there still data remaining inside the current block?- Returns:
- true if there is still data remaining inside the current block.
-
readLiteral
Reads data from the current literal block.- Parameters:
b- buffer to write data tooff- offset to start writing tolen- maximum amount of data to read- Returns:
- number of bytes read, may be 0. Will never return -1 as EOF-detection is the responsibility of the subclass
- Throws:
IOException- if the underlying stream throws or signals an EOF before the amount of data promised for the block have been readNullPointerException- ifbis nullIndexOutOfBoundsException- ifoffis negative,lenis negative, orlenis greater thanb.length - off
-
tryToReadLiteral
- Throws:
IOException
-
readFromBuffer
private int readFromBuffer(byte[] b, int off, int len) -
slideBuffer
private void slideBuffer() -
startBackReference
protected final void startBackReference(int offset, long length) Used by subclasses to signal the next block contains a back-reference with the given coordinates.- Parameters:
offset- the offset of the back-referencelength- the length of the back-reference- Throws:
IllegalArgumentException- if offset not bigger than 0 or bigger than the number of bytes available for back-references or if length is negative
-
readBackReference
protected final int readBackReference(byte[] b, int off, int len) Reads data from the current back-reference.- Parameters:
b- buffer to write data tooff- offset to start writing tolen- maximum amount of data to read- Returns:
- number of bytes read, may be 0. Will never return -1 as EOF-detection is the responsibility of the subclass
- Throws:
NullPointerException- ifbis nullIndexOutOfBoundsException- ifoffis negative,lenis negative, orlenis greater thanb.length - off
-
tryToCopy
private void tryToCopy(int bytesToCopy) -
readOneByte
Reads a single byte from the real input stream and ensures the data is accounted for.- Returns:
- the byte read as value between 0 and 255 or -1 if EOF has been reached.
- Throws:
IOException- if the underlying stream throws
-