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 org.apache.commons.io.input.BoundedInputStreamThe 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()longGets the amount of raw or compressed bytes read by the stream.intgetSize()Gets 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, read, read, reset, skipMethods 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
private final org.apache.commons.io.input.BoundedInputStream inThe 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:
IllegalArgumentException- if windowSize is not bigger than 0
-
-
Method Details
-
available
public int available()- Overrides:
availablein classInputStream
-
close
- Specified by:
closein interfaceAutoCloseable- Specified by:
closein interfaceCloseable- Overrides:
closein classInputStream- Throws:
IOException
-
getCompressedCount
public long getCompressedCount()Description copied from interface:InputStreamStatisticsGets the amount of raw or compressed bytes read by the stream.- Specified by:
getCompressedCountin interfaceInputStreamStatistics- Returns:
- the amount of raw or compressed bytes read by the stream.
- Since:
- 1.17
-
getSize
public int getSize()Gets the uncompressed size of the stream- Returns:
- the uncompressed size
-
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.
-
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
-
read
- Specified by:
readin classInputStream- Throws:
IOException
-
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
-
readFromBuffer
private int readFromBuffer(byte[] b, int off, int len) -
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
-
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
-
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
-
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
-
tryToCopy
private void tryToCopy(int bytesToCopy) -
tryToReadLiteral
- Throws:
IOException
-