diff options
author | Lasse Collin <lasse.collin@tukaani.org> | 2017-10-27 22:27:59 +0300 |
---|---|---|
committer | Lasse Collin <lasse.collin@tukaani.org> | 2017-12-28 19:52:20 +0200 |
commit | 28ca97fc3f9153460b0b88054351f959a36d1dfb (patch) | |
tree | 5213c102fd1c14d318281cd054185428c171e0f0 | |
parent | c5569e41b895c1a47ecf751f07287861c62f9ced (diff) | |
download | xz-java-28ca97fc3f9153460b0b88054351f959a36d1dfb.tar.gz |
Add ArrayCache support to LZMA and LZMA2 coders, part 2.
This makes the LZMA(2) code compliant with the ArrayCache API
by supporting buffers that are larger than requested.
-rw-r--r-- | src/org/tukaani/xz/UncompressedLZMA2OutputStream.java | 5 | ||||
-rw-r--r-- | src/org/tukaani/xz/lz/BT4.java | 2 | ||||
-rw-r--r-- | src/org/tukaani/xz/lz/HC4.java | 2 | ||||
-rw-r--r-- | src/org/tukaani/xz/lz/Hash234.java | 12 | ||||
-rw-r--r-- | src/org/tukaani/xz/lz/LZDecoder.java | 20 | ||||
-rw-r--r-- | src/org/tukaani/xz/lz/LZEncoder.java | 18 | ||||
-rw-r--r-- | src/org/tukaani/xz/rangecoder/RangeDecoderFromBuffer.java | 2 |
7 files changed, 35 insertions, 26 deletions
diff --git a/src/org/tukaani/xz/UncompressedLZMA2OutputStream.java b/src/org/tukaani/xz/UncompressedLZMA2OutputStream.java index 45e1a2f..5d0e65f 100644 --- a/src/org/tukaani/xz/UncompressedLZMA2OutputStream.java +++ b/src/org/tukaani/xz/UncompressedLZMA2OutputStream.java @@ -65,12 +65,13 @@ class UncompressedLZMA2OutputStream extends FinishableOutputStream { try { while (len > 0) { - int copySize = Math.min(uncompBuf.length - uncompPos, len); + int copySize = Math.min(LZMA2OutputStream.COMPRESSED_SIZE_MAX + - uncompPos, len); System.arraycopy(buf, off, uncompBuf, uncompPos, copySize); len -= copySize; uncompPos += copySize; - if (uncompPos == uncompBuf.length) + if (uncompPos == LZMA2OutputStream.COMPRESSED_SIZE_MAX) writeChunk(); } } catch (IOException e) { diff --git a/src/org/tukaani/xz/lz/BT4.java b/src/org/tukaani/xz/lz/BT4.java index d0116dd..6c46feb 100644 --- a/src/org/tukaani/xz/lz/BT4.java +++ b/src/org/tukaani/xz/lz/BT4.java @@ -59,7 +59,7 @@ final class BT4 extends LZEncoder { if (++lzPos == Integer.MAX_VALUE) { int normalizationOffset = Integer.MAX_VALUE - cyclicSize; hash.normalize(normalizationOffset); - normalize(tree, normalizationOffset); + normalize(tree, cyclicSize * 2, normalizationOffset); lzPos -= normalizationOffset; } diff --git a/src/org/tukaani/xz/lz/HC4.java b/src/org/tukaani/xz/lz/HC4.java index 3643609..d2b4e84 100644 --- a/src/org/tukaani/xz/lz/HC4.java +++ b/src/org/tukaani/xz/lz/HC4.java @@ -76,7 +76,7 @@ final class HC4 extends LZEncoder { if (++lzPos == Integer.MAX_VALUE) { int normalizationOffset = Integer.MAX_VALUE - cyclicSize; hash.normalize(normalizationOffset); - normalize(chain, normalizationOffset); + normalize(chain, cyclicSize, normalizationOffset); lzPos -= normalizationOffset; } diff --git a/src/org/tukaani/xz/lz/Hash234.java b/src/org/tukaani/xz/lz/Hash234.java index 3c106e2..299ec44 100644 --- a/src/org/tukaani/xz/lz/Hash234.java +++ b/src/org/tukaani/xz/lz/Hash234.java @@ -24,6 +24,7 @@ final class Hash234 extends CRC32Hash { private final int[] hash2Table; private final int[] hash3Table; private final int[] hash4Table; + private final int hash4Size; private int hash2Value = 0; private int hash3Value = 0; @@ -53,8 +54,9 @@ final class Hash234 extends CRC32Hash { hash2Table = arrayCache.getIntArray(HASH_2_SIZE, true); hash3Table = arrayCache.getIntArray(HASH_3_SIZE, true); - hash4Table = arrayCache.getIntArray(getHash4Size(dictSize), true); - hash4Mask = hash4Table.length - 1; + hash4Size = getHash4Size(dictSize); + hash4Table = arrayCache.getIntArray(hash4Size, true); + hash4Mask = hash4Size - 1; } void putArraysToCache(ArrayCache arrayCache) { @@ -93,8 +95,8 @@ final class Hash234 extends CRC32Hash { } void normalize(int normalizeOffset) { - LZEncoder.normalize(hash2Table, normalizeOffset); - LZEncoder.normalize(hash3Table, normalizeOffset); - LZEncoder.normalize(hash4Table, normalizeOffset); + LZEncoder.normalize(hash2Table, HASH_2_SIZE, normalizeOffset); + LZEncoder.normalize(hash3Table, HASH_3_SIZE, normalizeOffset); + LZEncoder.normalize(hash4Table, hash4Size, normalizeOffset); } } diff --git a/src/org/tukaani/xz/lz/LZDecoder.java b/src/org/tukaani/xz/lz/LZDecoder.java index b22b791..85b2ca1 100644 --- a/src/org/tukaani/xz/lz/LZDecoder.java +++ b/src/org/tukaani/xz/lz/LZDecoder.java @@ -17,6 +17,7 @@ import org.tukaani.xz.CorruptedInputException; public final class LZDecoder { private final byte[] buf; + private final int bufSize; // To avoid buf.length with an array-cached buf. private int start = 0; private int pos = 0; private int full = 0; @@ -25,7 +26,8 @@ public final class LZDecoder { private int pendingDist = 0; public LZDecoder(int dictSize, byte[] presetDict, ArrayCache arrayCache) { - buf = arrayCache.getByteArray(dictSize, false); + bufSize = dictSize; + buf = arrayCache.getByteArray(bufSize, false); if (presetDict != null) { pos = Math.min(presetDict.length, dictSize); @@ -44,12 +46,12 @@ public final class LZDecoder { pos = 0; full = 0; limit = 0; - buf[buf.length - 1] = 0x00; + buf[bufSize - 1] = 0x00; } public void setLimit(int outMax) { - if (buf.length - pos <= outMax) - limit = buf.length; + if (bufSize - pos <= outMax) + limit = bufSize; else limit = pos + outMax; } @@ -69,7 +71,7 @@ public final class LZDecoder { public int getByte(int dist) { int offset = pos - dist - 1; if (dist >= pos) - offset += buf.length; + offset += bufSize; return buf[offset] & 0xFF; } @@ -91,11 +93,11 @@ public final class LZDecoder { int back = pos - dist - 1; if (dist >= pos) - back += buf.length; + back += bufSize; do { buf[pos++] = buf[back++]; - if (back == buf.length) + if (back == bufSize) back = 0; } while (--left > 0); @@ -110,7 +112,7 @@ public final class LZDecoder { public void copyUncompressed(DataInputStream inData, int len) throws IOException { - int copySize = Math.min(buf.length - pos, len); + int copySize = Math.min(bufSize - pos, len); inData.readFully(buf, pos, copySize); pos += copySize; @@ -120,7 +122,7 @@ public final class LZDecoder { public int flush(byte[] out, int outOff) { int copySize = pos - start; - if (pos == buf.length) + if (pos == bufSize) pos = 0; System.arraycopy(buf, start, out, outOff, copySize); diff --git a/src/org/tukaani/xz/lz/LZEncoder.java b/src/org/tukaani/xz/lz/LZEncoder.java index de36ae0..0f13029 100644 --- a/src/org/tukaani/xz/lz/LZEncoder.java +++ b/src/org/tukaani/xz/lz/LZEncoder.java @@ -36,6 +36,7 @@ public abstract class LZEncoder { final int niceLen; final byte[] buf; + final int bufSize; // To avoid buf.length with an array-cached buf. int readPos = -1; private int readLimit = -1; @@ -43,8 +44,9 @@ public abstract class LZEncoder { private int writePos = 0; private int pendingSize = 0; - static void normalize(int[] positions, int normalizationOffset) { - for (int i = 0; i < positions.length; ++i) { + static void normalize(int[] positions, int positionsCount, + int normalizationOffset) { + for (int i = 0; i < positionsCount; ++i) { if (positions[i] <= normalizationOffset) positions[i] = 0; else @@ -137,9 +139,9 @@ public abstract class LZEncoder { */ LZEncoder(int dictSize, int extraSizeBefore, int extraSizeAfter, int niceLen, int matchLenMax, ArrayCache arrayCache) { - buf = arrayCache.getByteArray(getBufSize(dictSize, extraSizeBefore, - extraSizeAfter, matchLenMax), - false); + bufSize = getBufSize(dictSize, extraSizeBefore, extraSizeAfter, + matchLenMax); + buf = arrayCache.getByteArray(bufSize, false); keepSizeBefore = extraSizeBefore + dictSize; keepSizeAfter = extraSizeAfter + matchLenMax; @@ -196,13 +198,13 @@ public abstract class LZEncoder { assert !finishing; // Move the sliding window if needed. - if (readPos >= buf.length - keepSizeAfter) + if (readPos >= bufSize - keepSizeAfter) moveWindow(); // Try to fill the dictionary buffer. If it becomes full, // some of the input bytes may be left unused. - if (len > buf.length - writePos) - len = buf.length - writePos; + if (len > bufSize - writePos) + len = bufSize - writePos; System.arraycopy(in, off, buf, writePos, len); writePos += len; diff --git a/src/org/tukaani/xz/rangecoder/RangeDecoderFromBuffer.java b/src/org/tukaani/xz/rangecoder/RangeDecoderFromBuffer.java index c443a1b..dd2f7cc 100644 --- a/src/org/tukaani/xz/rangecoder/RangeDecoderFromBuffer.java +++ b/src/org/tukaani/xz/rangecoder/RangeDecoderFromBuffer.java @@ -22,6 +22,8 @@ public final class RangeDecoderFromBuffer extends RangeDecoder { private int pos; public RangeDecoderFromBuffer(int inputSizeMax, ArrayCache arrayCache) { + // We will use the *end* of the array so if the cache gives us + // a bigger-than-requested array, we still want to use buf.length. buf = arrayCache.getByteArray(inputSizeMax - INIT_SIZE, false); pos = buf.length; } |