diff --git a/src/org/tukaani/xz/lz/BT4.java b/src/org/tukaani/xz/lz/BT4.java
index 6c46feb..c96c766 100644
--- a/src/org/tukaani/xz/lz/BT4.java
+++ b/src/org/tukaani/xz/lz/BT4.java
@@ -11,6 +11,7 @@
package org.tukaani.xz.lz;
import org.tukaani.xz.ArrayCache;
+import org.tukaani.xz.common.ArrayUtil;
final class BT4 extends LZEncoder {
private final Hash234 hash;
@@ -118,9 +119,10 @@ final class BT4 extends LZEncoder {
// If a match was found, see how long it is.
if (matches.count > 0) {
- while (lenBest < matchLenLimit && buf[readPos + lenBest - delta2]
- == buf[readPos + lenBest])
- ++lenBest;
+ lenBest += ArrayUtil.mismatch(buf,
+ readPos + lenBest - delta2,
+ readPos + lenBest,
+ matchLenLimit - lenBest);
matches.len[matches.count - 1] = lenBest;
@@ -160,10 +162,12 @@ final class BT4 extends LZEncoder {
+ (delta > cyclicPos ? cyclicSize : 0)) << 1;
int len = Math.min(len0, len1);
- if (buf[readPos + len - delta] == buf[readPos + len]) {
- while (++len < matchLenLimit)
- if (buf[readPos + len - delta] != buf[readPos + len])
- break;
+ int mismatch = ArrayUtil.mismatch(buf,
+ readPos + len - delta,
+ readPos + len,
+ matchLenLimit - len);
+ if (mismatch != 0) {
+ len += mismatch;
if (len > lenBest) {
lenBest = len;
@@ -215,18 +219,19 @@ final class BT4 extends LZEncoder {
+ (delta > cyclicPos ? cyclicSize : 0)) << 1;
int len = Math.min(len0, len1);
- if (buf[readPos + len - delta] == buf[readPos + len]) {
- // No need to look for longer matches than niceLenLimit
- // because we only are updating the tree, not returning
- // matches found to the caller.
- do {
- if (++len == niceLenLimit) {
- tree[ptr1] = tree[pair];
- tree[ptr0] = tree[pair + 1];
- return;
- }
- } while (buf[readPos + len - delta] == buf[readPos + len]);
+ // No need to look for longer matches than niceLenLimit
+ // because we only are updating the tree, not returning
+ // matches found to the caller.
+ int mismatch = ArrayUtil.mismatch(buf,
+ readPos + len - delta,
+ readPos + len,
+ niceLenLimit);
+ if (mismatch == niceLenLimit) {
+ tree[ptr1] = tree[pair];
+ tree[ptr0] = tree[pair + 1];
+ return;
}
+ len += mismatch;
if ((buf[readPos + len - delta] & 0xFF)
< (buf[readPos + len] & 0xFF)) {
diff --git a/src/org/tukaani/xz/lz/HC4.java b/src/org/tukaani/xz/lz/HC4.java
index d2b4e84..623d59d 100644
--- a/src/org/tukaani/xz/lz/HC4.java
+++ b/src/org/tukaani/xz/lz/HC4.java
@@ -11,6 +11,7 @@
package org.tukaani.xz.lz;
import org.tukaani.xz.ArrayCache;
+import org.tukaani.xz.common.ArrayUtil;
final class HC4 extends LZEncoder {
private final Hash234 hash;
@@ -136,9 +137,10 @@ final class HC4 extends LZEncoder {
// If a match was found, see how long it is.
if (matches.count > 0) {
- while (lenBest < matchLenLimit && buf[readPos + lenBest - delta2]
- == buf[readPos + lenBest])
- ++lenBest;
+ lenBest += ArrayUtil.mismatch(buf,
+ readPos + lenBest - delta2,
+ readPos + lenBest,
+ matchLenLimit - lenBest);
matches.len[matches.count - 1] = lenBest;
@@ -167,30 +169,21 @@ final class HC4 extends LZEncoder {
currentMatch = chain[cyclicPos - delta
+ (delta > cyclicPos ? cyclicSize : 0)];
- // Test the first byte and the first new byte that would give us
- // a match that is at least one byte longer than lenBest. This
- // too short matches get quickly skipped.
- if (buf[readPos + lenBest - delta] == buf[readPos + lenBest]
- && buf[readPos - delta] == buf[readPos]) {
- // Calculate the length of the match.
- int len = 0;
- while (++len < matchLenLimit)
- if (buf[readPos + len - delta] != buf[readPos + len])
- break;
-
- // Use the match if and only if it is better than the longest
- // match found so far.
- if (len > lenBest) {
- lenBest = len;
- matches.len[matches.count] = len;
- matches.dist[matches.count] = delta - 1;
- ++matches.count;
-
- // Return if it is long enough (niceLen or reached the
- // end of the dictionary).
- if (len >= niceLenLimit)
- return matches;
- }
+ final int mismatch = ArrayUtil.mismatch(buf,
+ readPos - delta,
+ readPos,
+ matchLenLimit);
+ //use the match iff it is better than the longest match
found so far
+ if (mismatch > lenBest) {
+ lenBest = mismatch;
+ matches.len[matches.count] = mismatch;
+ matches.dist[matches.count] = delta - 1;
+ ++matches.count;
+
+ // Return if it is long enough (niceLen or reached the
+ // end of the dictionary).
+ if (mismatch >= niceLenLimit)
+ return matches;
}
}
}
diff --git a/src/org/tukaani/xz/lz/LZEncoder.java
b/src/org/tukaani/xz/lz/LZEncoder.java
index 0f13029..afa8185 100644
--- a/src/org/tukaani/xz/lz/LZEncoder.java
+++ b/src/org/tukaani/xz/lz/LZEncoder.java
@@ -10,9 +10,11 @@
package org.tukaani.xz.lz;
-import java.io.OutputStream;
import java.io.IOException;
+import java.io.OutputStream;
+
import org.tukaani.xz.ArrayCache;
+import org.tukaani.xz.common.ArrayUtil;
public abstract class LZEncoder {
public static final int MF_HC4 = 0x04;
@@ -334,13 +336,7 @@ public abstract class LZEncoder {
* @return length of the match; it is in the range [0, lenLimit]
*/
public int getMatchLen(int dist, int lenLimit) {
- int backPos = readPos - dist - 1;
- int len = 0;
-
- while (len < lenLimit && buf[readPos + len] == buf[backPos + len])
- ++len;
-
- return len;
+ return ArrayUtil.mismatch(buf, readPos - dist - 1, readPos, lenLimit);
}
/**
@@ -353,14 +349,8 @@ public abstract class LZEncoder {
* @return length of the match; it is in the range [0, lenLimit]
*/
public int getMatchLen(int forward, int dist, int lenLimit) {
- int curPos = readPos + forward;
- int backPos = curPos - dist - 1;
- int len = 0;
-
- while (len < lenLimit && buf[curPos + len] == buf[backPos + len])
- ++len;
-
- return len;
+ final int curPos = readPos + forward;
+ return ArrayUtil.mismatch(buf, curPos - dist - 1, curPos, lenLimit);
}
/**