aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLasse Collin <lasse.collin@tukaani.org>2017-10-27 22:27:59 +0300
committerLasse Collin <lasse.collin@tukaani.org>2017-12-28 19:52:20 +0200
commit28ca97fc3f9153460b0b88054351f959a36d1dfb (patch)
tree5213c102fd1c14d318281cd054185428c171e0f0
parentc5569e41b895c1a47ecf751f07287861c62f9ced (diff)
downloadxz-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.java5
-rw-r--r--src/org/tukaani/xz/lz/BT4.java2
-rw-r--r--src/org/tukaani/xz/lz/HC4.java2
-rw-r--r--src/org/tukaani/xz/lz/Hash234.java12
-rw-r--r--src/org/tukaani/xz/lz/LZDecoder.java20
-rw-r--r--src/org/tukaani/xz/lz/LZEncoder.java18
-rw-r--r--src/org/tukaani/xz/rangecoder/RangeDecoderFromBuffer.java2
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;
}