@Signature public void __construct(Environment env, InputStream inputStream, boolean framed) throws IOException { this.inputStream = framed ? new FramedLZ4CompressorInputStream(inputStream) : new BlockLZ4CompressorInputStream(inputStream); } }
/** {@inheritDoc} */ @Override public int read(final byte[] b, final int off, final int len) throws IOException { if (endReached) { return -1; } int r = readOnce(b, off, len); if (r == -1) { nextBlock(); if (!endReached) { r = readOnce(b, off, len); } } if (r != -1) { if (expectBlockDependency) { appendToBlockDependencyBuffer(b, off, r); } if (expectContentChecksum) { contentHash.update(b, off, r); } } return r; }
private boolean readSignature(boolean firstFrame) throws IOException { String garbageMessage = firstFrame ? "Not a LZ4 frame stream" : "LZ4 frame stream followed by garbage"; final byte[] b = new byte[4]; int read = IOUtils.readFully(in, b); count(read); if (0 == read && !firstFrame) { // good LZ4 frame and nothing after it endReached = true; return false; } if (4 != read) { throw new IOException(garbageMessage); } read = skipSkippableFrame(b); if (0 == read && !firstFrame) { // good LZ4 frame with only some skippable frames after it endReached = true; return false; } if (4 != read || !matches(b, 4)) { throw new IOException(garbageMessage); } return true; }
private void init(boolean firstFrame) throws IOException { if (readSignature(firstFrame)) { readFrameDescriptor(); nextBlock(); } }
private void nextBlock() throws IOException { maybeFinishCurrentBlock(); long len = ByteUtils.fromLittleEndian(supplier, 4); boolean uncompressed = (len & UNCOMPRESSED_FLAG_MASK) != 0; int realLen = (int) (len & (~UNCOMPRESSED_FLAG_MASK)); if (realLen == 0) { verifyContentChecksum(); if (!decompressConcatenated) { endReached = true; } else { init(false); } return; } InputStream capped = new BoundedInputStream(in, realLen); if (expectBlockChecksum) { capped = new ChecksumCalculatingInputStream(blockHash, capped); } if (uncompressed) { inUncompressed = true; currentBlock = capped; } else { inUncompressed = false; BlockLZ4CompressorInputStream s = new BlockLZ4CompressorInputStream(capped); if (expectBlockDependency) { s.prefill(blockDependencyBuffer); } currentBlock = s; } }
/** * Skips over the contents of a skippable frame as well as * skippable frames following it. * * <p>It then tries to read four more bytes which are supposed to * hold an LZ4 signature and returns the number of bytes read * while storing the bytes in the given array.</p> */ private int skipSkippableFrame(byte[] b) throws IOException { int read = 4; while (read == 4 && isSkippableFrameSignature(b)) { long len = ByteUtils.fromLittleEndian(supplier, 4); long skipped = IOUtils.skip(in, len); count(skipped); if (len != skipped) { throw new IOException("Premature end of stream while skipping frame"); } read = IOUtils.readFully(in, b); count(read); } return read; }
private void readFrameDescriptor() throws IOException { int flags = readOneByte(); if (flags == -1) { throw new IOException("Premature end of stream while reading frame flags"); expectContentSize = (flags & CONTENT_SIZE_MASK) != 0; expectContentChecksum = (flags & CONTENT_CHECKSUM_MASK) != 0; int bdByte = readOneByte(); if (bdByte == -1) { // max size is irrelevant for this implementation throw new IOException("Premature end of stream while reading frame BD byte"); byte[] contentSize = new byte[8]; int skipped = IOUtils.readFully(in, contentSize); count(skipped); if (8 != skipped) { throw new IOException("Premature end of stream while reading content size"); int headerHash = readOneByte(); if (headerHash == -1) { // partial hash of header. throw new IOException("Premature end of stream while reading frame header checksum");
private int readOneByte() throws IOException { final int b = in.read(); if (b != -1) { count(1); return b & 0xFF; } return -1; }
/** {@inheritDoc} */ @Override public int read() throws IOException { return read(oneByte, 0, 1) == -1 ? -1 : oneByte[0] & 0xFF; }
/** * Creates a new input stream that decompresses streams compressed * using the LZ4 frame format. * @param in the InputStream from which to read the compressed data * @param decompressConcatenated if true, decompress until the end * of the input; if false, stop after the first LZ4 frame * and leave the input position to point to the next byte * after the frame stream * @throws IOException if reading fails */ public FramedLZ4CompressorInputStream(InputStream in, boolean decompressConcatenated) throws IOException { this.in = new CountingInputStream(in); this.decompressConcatenated = decompressConcatenated; init(true); }
if (FramedLZ4CompressorInputStream.matches(signature, signatureLength)) { return LZ4_FRAMED;
private void init(boolean firstFrame) throws IOException { if (readSignature(firstFrame)) { readFrameDescriptor(); nextBlock(); } }
private void nextBlock() throws IOException { maybeFinishCurrentBlock(); long len = ByteUtils.fromLittleEndian(supplier, 4); boolean uncompressed = (len & UNCOMPRESSED_FLAG_MASK) != 0; int realLen = (int) (len & (~UNCOMPRESSED_FLAG_MASK)); if (realLen == 0) { verifyContentChecksum(); if (!decompressConcatenated) { endReached = true; } else { init(false); } return; } InputStream capped = new BoundedInputStream(in, realLen); if (expectBlockChecksum) { capped = new ChecksumCalculatingInputStream(blockHash, capped); } if (uncompressed) { inUncompressed = true; currentBlock = capped; } else { inUncompressed = false; BlockLZ4CompressorInputStream s = new BlockLZ4CompressorInputStream(capped); if (expectBlockDependency) { s.prefill(blockDependencyBuffer); } currentBlock = s; } }
/** * Skips over the contents of a skippable frame as well as * skippable frames following it. * * <p>It then tries to read four more bytes which are supposed to * hold an LZ4 signature and returns the number of bytes read * while storing the bytes in the given array.</p> */ private int skipSkippableFrame(byte[] b) throws IOException { int read = 4; while (read == 4 && isSkippableFrameSignature(b)) { long len = ByteUtils.fromLittleEndian(supplier, 4); long skipped = IOUtils.skip(in, len); count(skipped); if (len != skipped) { throw new IOException("Premature end of stream while skipping frame"); } read = IOUtils.readFully(in, b); count(read); } return read; }
private void readFrameDescriptor() throws IOException { int flags = readOneByte(); if (flags == -1) { throw new IOException("Premature end of stream while reading frame flags"); expectContentSize = (flags & CONTENT_SIZE_MASK) != 0; expectContentChecksum = (flags & CONTENT_CHECKSUM_MASK) != 0; int bdByte = readOneByte(); if (bdByte == -1) { // max size is irrelevant for this implementation throw new IOException("Premature end of stream while reading frame BD byte"); byte[] contentSize = new byte[8]; int skipped = IOUtils.readFully(in, contentSize); count(skipped); if (8 != skipped) { throw new IOException("Premature end of stream while reading content size"); int headerHash = readOneByte(); if (headerHash == -1) { // partial hash of header. throw new IOException("Premature end of stream while reading frame header checksum");
private int readOnce(byte[] b, int off, int len) throws IOException { if (inUncompressed) { int cnt = currentBlock.read(b, off, len); count(cnt); return cnt; } BlockLZ4CompressorInputStream l = (BlockLZ4CompressorInputStream) currentBlock; long before = l.getBytesRead(); int cnt = currentBlock.read(b, off, len); count(l.getBytesRead() - before); return cnt; }
/** {@inheritDoc} */ @Override public int read() throws IOException { return read(oneByte, 0, 1) == -1 ? -1 : oneByte[0] & 0xFF; }
/** * Creates a new input stream that decompresses streams compressed * using the LZ4 frame format. * @param in the InputStream from which to read the compressed data * @param decompressConcatenated if true, decompress until the end * of the input; if false, stop after the first LZ4 frame * and leave the input position to point to the next byte * after the frame stream * @throws IOException if reading fails */ public FramedLZ4CompressorInputStream(InputStream in, boolean decompressConcatenated) throws IOException { this.in = in; this.decompressConcatenated = decompressConcatenated; init(true); }
if (FramedLZ4CompressorInputStream.matches(signature, signatureLength)) { return LZ4_FRAMED;
return new FramedLZ4CompressorInputStream(in, actualDecompressConcatenated);