Repository: commons-compress Updated Branches: refs/heads/master 71f33fc90 -> 1845f0897
COMPRESS-271 incomplete implementation of writing block LZ4 streams the current code doesn't fulfill the "specific parsing rules", yet. This means the resulting output is not valid right now. Project: http://git-wip-us.apache.org/repos/asf/commons-compress/repo Commit: http://git-wip-us.apache.org/repos/asf/commons-compress/commit/1845f089 Tree: http://git-wip-us.apache.org/repos/asf/commons-compress/tree/1845f089 Diff: http://git-wip-us.apache.org/repos/asf/commons-compress/diff/1845f089 Branch: refs/heads/master Commit: 1845f089720f61cc0ba1227742ab3ccc92b99c70 Parents: 71f33fc Author: Stefan Bodewig <bode...@apache.org> Authored: Sat Jan 21 19:36:54 2017 +0100 Committer: Stefan Bodewig <bode...@apache.org> Committed: Sat Jan 21 19:38:59 2017 +0100 ---------------------------------------------------------------------- .../lz4/BlockLZ4CompressorOutputStream.java | 57 +++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/commons-compress/blob/1845f089/src/main/java/org/apache/commons/compress/compressors/lz4/BlockLZ4CompressorOutputStream.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/compress/compressors/lz4/BlockLZ4CompressorOutputStream.java b/src/main/java/org/apache/commons/compress/compressors/lz4/BlockLZ4CompressorOutputStream.java index d9c47d4..856d9b3 100644 --- a/src/main/java/org/apache/commons/compress/compressors/lz4/BlockLZ4CompressorOutputStream.java +++ b/src/main/java/org/apache/commons/compress/compressors/lz4/BlockLZ4CompressorOutputStream.java @@ -21,6 +21,8 @@ package org.apache.commons.compress.compressors.lz4; import java.io.IOException; import java.io.OutputStream; import java.util.Arrays; +import java.util.Deque; +import java.util.Iterator; import java.util.LinkedList; import java.util.List; @@ -56,7 +58,7 @@ public class BlockLZ4CompressorOutputStream extends CompressorOutputStream { start writing the literal before we know how long the next back-reference is going to be. - * there is a special rule for the final blocks + * there are special rules for the final blocks > There are specific parsing rules to respect in order to remain > compatible with assumptions made by the decoder : @@ -82,6 +84,8 @@ public class BlockLZ4CompressorOutputStream extends CompressorOutputStream { private boolean finished = false; + private Deque<Pair> pairs = new LinkedList<>(); + /** * Creates a new LZ4 output stream. * @@ -139,17 +143,64 @@ public class BlockLZ4CompressorOutputStream extends CompressorOutputStream { } private void addLiteralBlock(LZ77Compressor.LiteralBlock block) throws IOException { + Pair last = writeBlocksAndReturnUnfinishedPair(block.getLength()); + last.addLiteral(block); } private void addBackReference(LZ77Compressor.BackReference block) throws IOException { + Pair last = writeBlocksAndReturnUnfinishedPair(block.getLength()); + last.setBackReference(block); + } + + private Pair writeBlocksAndReturnUnfinishedPair(int length) throws IOException { + writeWritablePairs(length); + Pair last = pairs.peekLast(); + if (last == null || last.hasBackReference()) { + last = new Pair(); + pairs.addLast(last); + } + return last; } private void writeFinalLiteralBlock() throws IOException { + rewriteLastPairs(); + for (Pair p : pairs) { + if (!p.hasBeenWritten()) { + p.writeTo(os); + } + } + pairs.clear(); + } + + private void writeWritablePairs(int lengthOfBlocksAfterLastPair) throws IOException { + int unwrittenLength = lengthOfBlocksAfterLastPair; + for (Iterator<Pair> it = pairs.descendingIterator(); it.hasNext(); ) { + Pair p = it.next(); + if (p.hasBeenWritten()) { + break; + } + unwrittenLength += p.length(); + } + for (Pair p : pairs) { + if (p.hasBeenWritten()) { + continue; + } + unwrittenLength -= p.length(); + if (p.canBeWritten(unwrittenLength)) { + p.writeTo(os); + } else { + break; + } + } + } + + private void rewriteLastPairs() { } final static class Pair { private final List<byte[]> literals = new LinkedList<>(); private int brOffset, brLength; + private boolean written; void addLiteral(LZ77Compressor.LiteralBlock block) { literals.add(Arrays.copyOfRange(block.getData(), block.getOffset(), @@ -173,6 +224,9 @@ public class BlockLZ4CompressorOutputStream extends CompressorOutputStream { int length() { return literalLength() + brLength; } + boolean hasBeenWritten() { + return written; + } void writeTo(OutputStream out) throws IOException { int litLength = literalLength(); out.write(lengths(litLength, brLength)); @@ -189,6 +243,7 @@ public class BlockLZ4CompressorOutputStream extends CompressorOutputStream { - BlockLZ4CompressorInputStream.BACK_REFERENCE_SIZE_MASK, out); } } + written = true; } private int literalLength() { int length = 0;