From 9f1f97a26f090ffec6568c004a38c6534aa82b94 Mon Sep 17 00:00:00 2001 From: Lasse Collin Date: Mon, 4 Nov 2019 19:06:10 +0200 Subject: Rename normalizeOffset to normalizationOffset for consistency. Thanks to Yusuke Shinyama. --- src/org/tukaani/xz/lz/Hash234.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/org/tukaani/xz/lz/Hash234.java b/src/org/tukaani/xz/lz/Hash234.java index 299ec44..bfa51b0 100644 --- a/src/org/tukaani/xz/lz/Hash234.java +++ b/src/org/tukaani/xz/lz/Hash234.java @@ -94,9 +94,9 @@ final class Hash234 extends CRC32Hash { hash4Table[hash4Value] = pos; } - void normalize(int normalizeOffset) { - LZEncoder.normalize(hash2Table, HASH_2_SIZE, normalizeOffset); - LZEncoder.normalize(hash3Table, HASH_3_SIZE, normalizeOffset); - LZEncoder.normalize(hash4Table, hash4Size, normalizeOffset); + void normalize(int normalizationOffset) { + LZEncoder.normalize(hash2Table, HASH_2_SIZE, normalizationOffset); + LZEncoder.normalize(hash3Table, HASH_3_SIZE, normalizationOffset); + LZEncoder.normalize(hash4Table, hash4Size, normalizationOffset); } } -- cgit v1.2.3 From 844489b116303be16b5860929cbb75093a76323f Mon Sep 17 00:00:00 2001 From: Lasse Collin Date: Fri, 29 Jan 2021 19:40:10 +0200 Subject: Add LZMAInputStream.enableRelaxedEndCondition(). It is useful to decompress LZMA data from .7z files created by some old 7-Zip versions that put the end marker in the LZMA stream. The slightly weakened error detection doesn't matter because in .7z there is a separate integrity check on the data anyway. Thanks to Simon. --- src/org/tukaani/xz/LZMAInputStream.java | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/src/org/tukaani/xz/LZMAInputStream.java b/src/org/tukaani/xz/LZMAInputStream.java index e46d5bb..73cb49e 100644 --- a/src/org/tukaani/xz/LZMAInputStream.java +++ b/src/org/tukaani/xz/LZMAInputStream.java @@ -53,6 +53,7 @@ public class LZMAInputStream extends InputStream { private LZMADecoder lzma; private boolean endReached = false; + private boolean relaxedEndCondition = false; private final byte[] tempBuf = new byte[1]; @@ -605,6 +606,31 @@ public class LZMAInputStream extends InputStream { remainingSize = uncompSize; } + /** + * Enables relaxed end-of-stream condition when uncompressed size is known. + * This is useful if uncompressed size is known but it is unknown if + * the end of stream (EOS) marker is present. After calling this function, + * both are allowed. + *

+ * Note that this doesn't actually check if the EOS marker is present. + * This introduces a few minor downsides: + *

+ *

+ * This should be called after the constructor before reading any data + * from the stream. This is a separate function because adding even more + * constructors to this class didn't look like a good alternative. + */ + public void enableRelaxedEndCondition() { + relaxedEndCondition = true; + } + /** * Decompresses the next byte from this input stream. *

@@ -718,9 +744,10 @@ public class LZMAInputStream extends InputStream { if (endReached) { // Checking these helps a lot when catching corrupt // or truncated .lzma files. LZMA Utils doesn't do - // the first check and thus it accepts many invalid + // the second check and thus it accepts many invalid // files that this implementation and XZ Utils don't. - if (!rc.isFinished() || lz.hasPending()) + if (lz.hasPending() || (!relaxedEndCondition + && !rc.isFinished())) throw new CorruptedInputException(); putArraysToCache(); -- cgit v1.2.3 From e0802e9d6a1ed2b7b4517d0bd4b62a68d3460721 Mon Sep 17 00:00:00 2001 From: Lasse Collin Date: Mon, 1 Feb 2021 13:25:42 +0200 Subject: Fix javadoc errors and a few warnings, and change a HTTP URL to HTTPS. In addition to pure comment changes, two imports for java.io.EOFException were added so that javadoc sees what is referenced. Gazillion javadoc warnings remain. --- src/org/tukaani/xz/CloseIgnoringInputStream.java | 2 +- src/org/tukaani/xz/LZMA2InputStream.java | 1 + src/org/tukaani/xz/LZMAInputStream.java | 1 + src/org/tukaani/xz/SeekableXZInputStream.java | 4 ++-- src/org/tukaani/xz/SingleXZInputStream.java | 2 +- src/org/tukaani/xz/XZInputStream.java | 8 ++++---- src/org/tukaani/xz/XZOutputStream.java | 8 ++++---- src/org/tukaani/xz/package-info.java | 8 ++++---- 8 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/org/tukaani/xz/CloseIgnoringInputStream.java b/src/org/tukaani/xz/CloseIgnoringInputStream.java index db68ddb..c29f268 100644 --- a/src/org/tukaani/xz/CloseIgnoringInputStream.java +++ b/src/org/tukaani/xz/CloseIgnoringInputStream.java @@ -18,7 +18,7 @@ import java.io.FilterInputStream; * {@code close()} to release memory allocated from an {@link ArrayCache} * but don't want to close the underlying {@code InputStream}. * For example: - *

+ * 
  * InputStream rawdec = new LZMA2InputStream(
  *         new CloseIgnoringInputStream(myInputStream),
  *         myDictSize, null, myArrayCache);
diff --git a/src/org/tukaani/xz/LZMA2InputStream.java b/src/org/tukaani/xz/LZMA2InputStream.java
index 9708052..c494a07 100644
--- a/src/org/tukaani/xz/LZMA2InputStream.java
+++ b/src/org/tukaani/xz/LZMA2InputStream.java
@@ -13,6 +13,7 @@ package org.tukaani.xz;
 import java.io.InputStream;
 import java.io.DataInputStream;
 import java.io.IOException;
+import java.io.EOFException;
 import org.tukaani.xz.lz.LZDecoder;
 import org.tukaani.xz.rangecoder.RangeDecoderFromBuffer;
 import org.tukaani.xz.lzma.LZMADecoder;
diff --git a/src/org/tukaani/xz/LZMAInputStream.java b/src/org/tukaani/xz/LZMAInputStream.java
index 73cb49e..34527b9 100644
--- a/src/org/tukaani/xz/LZMAInputStream.java
+++ b/src/org/tukaani/xz/LZMAInputStream.java
@@ -13,6 +13,7 @@ package org.tukaani.xz;
 import java.io.InputStream;
 import java.io.DataInputStream;
 import java.io.IOException;
+import java.io.EOFException;
 import org.tukaani.xz.lz.LZDecoder;
 import org.tukaani.xz.rangecoder.RangeDecoderFromStream;
 import org.tukaani.xz.lzma.LZMADecoder;
diff --git a/src/org/tukaani/xz/SeekableXZInputStream.java b/src/org/tukaani/xz/SeekableXZInputStream.java
index 74f130e..bc08671 100644
--- a/src/org/tukaani/xz/SeekableXZInputStream.java
+++ b/src/org/tukaani/xz/SeekableXZInputStream.java
@@ -45,7 +45,7 @@ import org.tukaani.xz.index.BlockInfo;
  * Block inside a Stream is located using binary search and thus is fast
  * even with a huge number of Blocks.
  *
- * 

Memory usage

+ *

Memory usage

*

* The amount of memory needed for the Indexes is taken into account when * checking the memory usage limit. Each Stream is calculated to need at @@ -53,7 +53,7 @@ import org.tukaani.xz.index.BlockInfo; * to the next kibibyte. So unless the file has a huge number of Streams or * Blocks, these don't take significant amount of memory. * - *

Creating random-accessible .xz files

+ *

Creating random-accessible .xz files

*

* When using {@link XZOutputStream}, a new Block can be started by calling * its {@link XZOutputStream#endBlock() endBlock} method. If you know diff --git a/src/org/tukaani/xz/SingleXZInputStream.java b/src/org/tukaani/xz/SingleXZInputStream.java index 8da2be0..e106771 100644 --- a/src/org/tukaani/xz/SingleXZInputStream.java +++ b/src/org/tukaani/xz/SingleXZInputStream.java @@ -28,7 +28,7 @@ import org.tukaani.xz.check.Check; * Unless you know what you are doing, don't use this class to decompress * standalone .xz files. For that purpose, use XZInputStream. * - *

When uncompressed size is known beforehand

+ *

When uncompressed size is known beforehand

*

* If you are decompressing complete XZ streams and your application knows * exactly how much uncompressed data there should be, it is good to try diff --git a/src/org/tukaani/xz/XZInputStream.java b/src/org/tukaani/xz/XZInputStream.java index 680f647..30374eb 100644 --- a/src/org/tukaani/xz/XZInputStream.java +++ b/src/org/tukaani/xz/XZInputStream.java @@ -22,10 +22,10 @@ import org.tukaani.xz.common.DecoderUtil; * its input stream until the end of the input or until an error occurs. * This supports decompressing concatenated .xz files. * - *

Typical use cases

+ *

Typical use cases

*

* Getting an input stream to decompress a .xz file: - *

+ * 
  * InputStream infile = new FileInputStream("foo.xz");
  * XZInputStream inxz = new XZInputStream(infile);
  * 
@@ -42,12 +42,12 @@ import org.tukaani.xz.common.DecoderUtil; * the specified limit, MemoryLimitException will be thrown when reading * from the stream. For example, the following sets the memory usage limit * to 100 MiB: - *

+ * 
  * InputStream infile = new FileInputStream("foo.xz");
  * XZInputStream inxz = new XZInputStream(infile, 100 * 1024);
  * 
* - *

When uncompressed size is known beforehand

+ *

When uncompressed size is known beforehand

*

* If you are decompressing complete files and your application knows * exactly how much uncompressed data there should be, it is good to try diff --git a/src/org/tukaani/xz/XZOutputStream.java b/src/org/tukaani/xz/XZOutputStream.java index 107ef7f..63cf5cf 100644 --- a/src/org/tukaani/xz/XZOutputStream.java +++ b/src/org/tukaani/xz/XZOutputStream.java @@ -19,18 +19,18 @@ import org.tukaani.xz.index.IndexEncoder; /** * Compresses into the .xz file format. * - *

Examples

+ *

Examples

*

* Getting an output stream to compress with LZMA2 using the default * settings and the default integrity check type (CRC64): - *

+ * 
  * FileOutputStream outfile = new FileOutputStream("foo.xz");
  * XZOutputStream outxz = new XZOutputStream(outfile, new LZMA2Options());
  * 
*

* Using the preset level 8 for LZMA2 (the default * is 6) and SHA-256 instead of CRC64 for integrity checking: - *

+ * 
  * XZOutputStream outxz = new XZOutputStream(outfile, new LZMA2Options(8),
  *                                           XZ.CHECK_SHA256);
  * 
@@ -38,7 +38,7 @@ import org.tukaani.xz.index.IndexEncoder; * Using the x86 BCJ filter together with LZMA2 to compress x86 executables * and printing the memory usage information before creating the * XZOutputStream: - *

+ * 
  * X86Options x86 = new X86Options();
  * LZMA2Options lzma2 = new LZMA2Options();
  * FilterOptions[] options = { x86, lzma2 };
diff --git a/src/org/tukaani/xz/package-info.java b/src/org/tukaani/xz/package-info.java
index 4e961df..1f20e89 100644
--- a/src/org/tukaani/xz/package-info.java
+++ b/src/org/tukaani/xz/package-info.java
@@ -10,7 +10,7 @@
 /**
  * XZ data compression support.
  *
- * 

Introduction

+ *

Introduction

*

* This aims to be a complete implementation of XZ data compression * in pure Java. Features: @@ -25,16 +25,16 @@ * Threading is planned but it is unknown when it will be implemented. *

* For the latest source code, see the - * home page of XZ for Java. + * home page of XZ for Java. * - *

Getting started

+ *

Getting started

*

* Start by reading the documentation of {@link org.tukaani.xz.XZOutputStream} * and {@link org.tukaani.xz.XZInputStream}. * If you use XZ inside another file format or protocol, * see also {@link org.tukaani.xz.SingleXZInputStream}. * - *

Licensing

+ *

Licensing

*

* XZ for Java has been put into the public domain, thus you can do * whatever you want with it. All the files in the package have been -- cgit v1.2.3 From 61532d352f0d21fee3188e2e0dc3587cb41f9756 Mon Sep 17 00:00:00 2001 From: Lasse Collin Date: Mon, 1 Feb 2021 13:26:23 +0200 Subject: Javadoc: Omit deprecated list (which is empty) and the generic help page. --- build.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/build.xml b/build.xml index 4abaec6..38e57c1 100644 --- a/build.xml +++ b/build.xml @@ -40,6 +40,7 @@ -- cgit v1.2.3 From b82f736da5fa06610bf4cea7316f95c6c3852fe9 Mon Sep 17 00:00:00 2001 From: Lasse Collin Date: Mon, 1 Feb 2021 13:46:15 +0200 Subject: Add support for javac --release on OpenJDK 9 and later. This requires Ant >= 1.9.8. --- build.properties | 10 ++++++---- build.xml | 1 + 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/build.properties b/build.properties index fd5c373..c488dc3 100644 --- a/build.properties +++ b/build.properties @@ -12,12 +12,14 @@ homepage = https://tukaani.org/xz/java.html version = 1.8 debug = false -# sourcever sets -source and -target options for javac. +# sourcever sets --release for javac 9 (or later) or -source and -target for +# older javac versions which don't support --release. # # The source code is Java 5 compatible but the oldest -source/-target pair -# that OpenJDK 9 supports is 1.6 (Java 6). Edit this if you are using -# OpenJDK 9 or later. -sourcever = 1.5 +# (and also --release) that OpenJDK 15 supports is 7 (Java 7). +# If you need to build this on an older JDK: +# - Set sourcever appropriately (5 or higher) +sourcever = 7 src_dir = src build_dir = build diff --git a/build.xml b/build.xml index 38e57c1..acc3655 100644 --- a/build.xml +++ b/build.xml @@ -49,6 +49,7 @@ -- cgit v1.2.3 From badfdc1c4b2eed8c1fd511075184e202909d2531 Mon Sep 17 00:00:00 2001 From: Lasse Collin Date: Mon, 1 Feb 2021 13:51:17 +0200 Subject: For javadoc, add support for "element-list" from Java 11 and later. The file needed for -linkoffline is package-list with Java 7, 8, and 9, and element-list with Java 11 and later. The new default is to link to Java 15 docs. --- build.properties | 17 ++++++++++++++++- build.xml | 6 +++--- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/build.properties b/build.properties index c488dc3..7622810 100644 --- a/build.properties +++ b/build.properties @@ -19,6 +19,7 @@ debug = false # (and also --release) that OpenJDK 15 supports is 7 (Java 7). # If you need to build this on an older JDK: # - Set sourcever appropriately (5 or higher) +# - Adjust extdoc_url and extdoc_dir to point to older documentation. sourcever = 7 src_dir = src @@ -29,7 +30,21 @@ classes_dir = ${build_dir}/classes jar_dir = ${build_dir}/jar doc_dir = ${build_dir}/doc -extdoc_url = https://docs.oracle.com/javase/9/docs/api +# extdoc_url and extdoc_file must be modified as a pair. +# +# Possible values for extdoc_url: +# https://docs.oracle.com/javase/7/docs/api +# https://docs.oracle.com/javase/8/docs/api +# https://docs.oracle.com/javase/9/docs/api +# https://docs.oracle.com/en/java/javase/11/docs/api +# ... +# https://docs.oracle.com/en/java/javase/15/docs/api +# +# Possible values for extdoc_file: +# - Java 7, 8, and 9: package-list +# - Java 11 and later: element-list +extdoc_url = https://docs.oracle.com/en/java/javase/15/docs/api +extdoc_file = element-list extdoc_dir = extdoc pom_template = maven/pom_template.xml diff --git a/build.xml b/build.xml index acc3655..f103429 100644 --- a/build.xml +++ b/build.xml @@ -14,7 +14,7 @@ + description="Deletes generated files except 'extdoc'"> @@ -35,8 +35,8 @@ description="Generates HTML documentation with javadoc"> - + Date: Mon, 1 Feb 2021 14:07:29 +0200 Subject: Silence warnings about obsolete javac options. This avoids warnings with java 15 with the default "sourcever = 7" in build.properties. --- build.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.xml b/build.xml index f103429..81da32f 100644 --- a/build.xml +++ b/build.xml @@ -52,7 +52,7 @@ release="${sourcever}" includesfile="fileset-src.txt" excludes="**/package-info.java"> - + -- cgit v1.2.3 From 3dd2c2da01f363ceaa2bb16a2dd44f541f5dcd27 Mon Sep 17 00:00:00 2001 From: Lasse Collin Date: Mon, 1 Feb 2021 19:45:48 +0200 Subject: Add module-info.java as multi-release JAR. Automatic-Module-Name was removed. --- build.properties | 15 ++++++++++++--- build.xml | 44 ++++++++++++++++++++++++++++++++++++++------ fileset-src9.txt | 1 + src9/module-info.java | 12 ++++++++++++ 4 files changed, 63 insertions(+), 9 deletions(-) create mode 100644 fileset-src9.txt create mode 100644 src9/module-info.java diff --git a/build.properties b/build.properties index 7622810..243dbd6 100644 --- a/build.properties +++ b/build.properties @@ -13,20 +13,29 @@ version = 1.8 debug = false # sourcever sets --release for javac 9 (or later) or -source and -target for -# older javac versions which don't support --release. +# older javac versions which don't support --release. The main source code is +# Java 5 compatible but the oldest -source/-target pair (and also --release) +# that OpenJDK 15 supports is 7 (Java 7). +# +# sourcever9 does the same as sourcever but for files that require Java 9 or +# later. The resulting classes are packaged as multi-release JAR, including +# module-info.java. If sourcever9 is commented out, these files won't be +# built but the package will still work. # -# The source code is Java 5 compatible but the oldest -source/-target pair -# (and also --release) that OpenJDK 15 supports is 7 (Java 7). # If you need to build this on an older JDK: # - Set sourcever appropriately (5 or higher) +# - Comment the sourcever9 line below to disable building Java 9 files. # - Adjust extdoc_url and extdoc_dir to point to older documentation. sourcever = 7 +sourcever9 = 9 src_dir = src +src9_dir = src9 build_dir = build dist_dir = ${build_dir}/dist dist_file = ${dist_dir}/xz-java-${version}.zip classes_dir = ${build_dir}/classes +classes9_dir = ${build_dir}/classes9 jar_dir = ${build_dir}/jar doc_dir = ${build_dir}/doc diff --git a/build.xml b/build.xml index 81da32f..05bd9ad 100644 --- a/build.xml +++ b/build.xml @@ -28,6 +28,7 @@ + @@ -54,21 +55,50 @@ excludes="**/package-info.java"> + + + + + + + + + + + + + + + + - + + + - + @@ -157,8 +187,10 @@ - + + + + diff --git a/fileset-src9.txt b/fileset-src9.txt new file mode 100644 index 0000000..d060ebd --- /dev/null +++ b/fileset-src9.txt @@ -0,0 +1 @@ +src9/module-info.java diff --git a/src9/module-info.java b/src9/module-info.java new file mode 100644 index 0000000..1b28bc4 --- /dev/null +++ b/src9/module-info.java @@ -0,0 +1,12 @@ +/* + * module-info + * + * Author: Lasse Collin + * + * This file has been put into the public domain. + * You can do whatever you want with this file. + */ + +module org.tukaani.xz { + exports org.tukaani.xz; +} -- cgit v1.2.3 From 74a7e71b84c330122991dea4717996de1850272f Mon Sep 17 00:00:00 2001 From: Lasse Collin Date: Tue, 2 Feb 2021 19:15:23 +0200 Subject: BlockInputStream: Don't allocate unneeded memory for Block Header. Thanks to Brett Okken for the original patch. --- src/org/tukaani/xz/BlockInputStream.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/org/tukaani/xz/BlockInputStream.java b/src/org/tukaani/xz/BlockInputStream.java index 1931bd6..a9fff5f 100644 --- a/src/org/tukaani/xz/BlockInputStream.java +++ b/src/org/tukaani/xz/BlockInputStream.java @@ -44,17 +44,18 @@ class BlockInputStream extends InputStream { this.verifyCheck = verifyCheck; inData = new DataInputStream(in); - byte[] buf = new byte[DecoderUtil.BLOCK_HEADER_SIZE_MAX]; - // Block Header Size or Index Indicator - inData.readFully(buf, 0, 1); + int b = inData.readUnsignedByte(); // See if this begins the Index field. - if (buf[0] == 0x00) + if (b == 0x00) throw new IndexIndicatorException(); // Read the rest of the Block Header. - headerSize = 4 * ((buf[0] & 0xFF) + 1); + headerSize = 4 * (b + 1); + + final byte[] buf = new byte[headerSize]; + buf[0] = (byte)b; inData.readFully(buf, 1, headerSize - 1); // Validate the CRC32. -- cgit v1.2.3 From e42989df728f3c0981e625bc0aa8009c00b21cb1 Mon Sep 17 00:00:00 2001 From: Lasse Collin Date: Tue, 2 Feb 2021 21:00:27 +0200 Subject: LZMA2OutputStream: Combine tiny writes into bigger writes. Thanks to Brett Okken. --- src/org/tukaani/xz/LZMA2OutputStream.java | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/org/tukaani/xz/LZMA2OutputStream.java b/src/org/tukaani/xz/LZMA2OutputStream.java index a82a1a5..9b5f55b 100644 --- a/src/org/tukaani/xz/LZMA2OutputStream.java +++ b/src/org/tukaani/xz/LZMA2OutputStream.java @@ -22,7 +22,6 @@ class LZMA2OutputStream extends FinishableOutputStream { private final ArrayCache arrayCache; private FinishableOutputStream out; - private final DataOutputStream outData; private LZEncoder lz; private RangeEncoderToBuffer rc; @@ -37,6 +36,8 @@ class LZMA2OutputStream extends FinishableOutputStream { private boolean finished = false; private IOException exception = null; + private final byte[] chunkHeader = new byte[6]; + private final byte[] tempBuf = new byte[1]; private static int getExtraSizeBefore(int dictSize) { @@ -60,7 +61,6 @@ class LZMA2OutputStream extends FinishableOutputStream { this.arrayCache = arrayCache; this.out = out; - outData = new DataOutputStream(out); rc = new RangeEncoderToBuffer(COMPRESSED_SIZE_MAX, arrayCache); int dictSize = options.getDictSize(); @@ -154,13 +154,18 @@ class LZMA2OutputStream extends FinishableOutputStream { } control |= (uncompressedSize - 1) >>> 16; - outData.writeByte(control); - - outData.writeShort(uncompressedSize - 1); - outData.writeShort(compressedSize - 1); + chunkHeader[0] = (byte)control; + chunkHeader[1] = (byte)((uncompressedSize - 1) >>> 8); + chunkHeader[2] = (byte)(uncompressedSize - 1); + chunkHeader[3] = (byte)((compressedSize - 1) >>> 8); + chunkHeader[4] = (byte)(compressedSize - 1); - if (propsNeeded) - outData.writeByte(props); + if (propsNeeded) { + chunkHeader[5] = (byte)props; + out.write(chunkHeader, 0, 6); + } else { + out.write(chunkHeader, 0, 5); + } rc.write(out); @@ -172,8 +177,10 @@ class LZMA2OutputStream extends FinishableOutputStream { private void writeUncompressed(int uncompressedSize) throws IOException { while (uncompressedSize > 0) { int chunkSize = Math.min(uncompressedSize, COMPRESSED_SIZE_MAX); - outData.writeByte(dictResetNeeded ? 0x01 : 0x02); - outData.writeShort(chunkSize - 1); + chunkHeader[0] = (byte)(dictResetNeeded ? 0x01 : 0x02); + chunkHeader[1] = (byte)((chunkSize - 1) >>> 8); + chunkHeader[2] = (byte)(chunkSize - 1); + out.write(chunkHeader, 0, 3); lz.copyUncompressed(out, uncompressedSize, chunkSize); uncompressedSize -= chunkSize; dictResetNeeded = false; -- cgit v1.2.3 From a73b97ee4923dc14206162656ad91ec124d12069 Mon Sep 17 00:00:00 2001 From: Lasse Collin Date: Fri, 5 Feb 2021 18:04:29 +0200 Subject: LZMAInputStream.enableRelaxedEndCondition(): Add missing @since tag. --- src/org/tukaani/xz/LZMAInputStream.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/org/tukaani/xz/LZMAInputStream.java b/src/org/tukaani/xz/LZMAInputStream.java index 34527b9..1432eb1 100644 --- a/src/org/tukaani/xz/LZMAInputStream.java +++ b/src/org/tukaani/xz/LZMAInputStream.java @@ -627,6 +627,8 @@ public class LZMAInputStream extends InputStream { * This should be called after the constructor before reading any data * from the stream. This is a separate function because adding even more * constructors to this class didn't look like a good alternative. + * + * @since 1.9 */ public void enableRelaxedEndCondition() { relaxedEndCondition = true; -- cgit v1.2.3 From db61b22f7981da29f140f4e83d88daaebe7fa5f2 Mon Sep 17 00:00:00 2001 From: Lasse Collin Date: Fri, 5 Feb 2021 18:16:58 +0200 Subject: CRC64: Minor speed improvement. For some reason it is faster to do "& 0xFF" separately first and then xor the two numbers. This improves decompression speed by 5-10 % in the extreme case where the uncompressed file contains only null bytes. --- src/org/tukaani/xz/check/CRC64.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/org/tukaani/xz/check/CRC64.java b/src/org/tukaani/xz/check/CRC64.java index 02b15b7..f40dbd7 100644 --- a/src/org/tukaani/xz/check/CRC64.java +++ b/src/org/tukaani/xz/check/CRC64.java @@ -38,7 +38,8 @@ public class CRC64 extends Check { int end = off + len; while (off < end) - crc = crcTable[(buf[off++] ^ (int)crc) & 0xFF] ^ (crc >>> 8); + crc = crcTable[(buf[off++] & 0xFF) ^ ((int)crc & 0xFF)] + ^ (crc >>> 8); } public byte[] finish() { -- cgit v1.2.3 From 8df03bcf2ac492ec459c9a24fe43817c5a73b8df Mon Sep 17 00:00:00 2001 From: Lasse Collin Date: Fri, 5 Feb 2021 21:23:23 +0200 Subject: Remove two unneeded imports. --- src/org/tukaani/xz/LZMA2OutputStream.java | 1 - src/org/tukaani/xz/rangecoder/RangeDecoder.java | 1 - 2 files changed, 2 deletions(-) diff --git a/src/org/tukaani/xz/LZMA2OutputStream.java b/src/org/tukaani/xz/LZMA2OutputStream.java index 9b5f55b..1bb2d85 100644 --- a/src/org/tukaani/xz/LZMA2OutputStream.java +++ b/src/org/tukaani/xz/LZMA2OutputStream.java @@ -10,7 +10,6 @@ package org.tukaani.xz; -import java.io.DataOutputStream; import java.io.IOException; import org.tukaani.xz.lz.LZEncoder; import org.tukaani.xz.rangecoder.RangeEncoderToBuffer; diff --git a/src/org/tukaani/xz/rangecoder/RangeDecoder.java b/src/org/tukaani/xz/rangecoder/RangeDecoder.java index e63532e..7bcf718 100644 --- a/src/org/tukaani/xz/rangecoder/RangeDecoder.java +++ b/src/org/tukaani/xz/rangecoder/RangeDecoder.java @@ -10,7 +10,6 @@ package org.tukaani.xz.rangecoder; -import java.io.DataInputStream; import java.io.IOException; public abstract class RangeDecoder extends RangeCoder { -- cgit v1.2.3 From 94de588b2258f0c7216ea5a2dfef5afbda18f361 Mon Sep 17 00:00:00 2001 From: Lasse Collin Date: Fri, 5 Feb 2021 21:48:58 +0200 Subject: Use the slice-by-four algorithm for CRC64. Compared to the C version, this reads the input byte by byte instead of four aligned bytes at a time. This is still faster than the previous simpler version. This code was adapted from XZ Utils by Brett Okken. He also did benchmarking. Thanks! --- src/org/tukaani/xz/check/CRC64.java | 50 ++++++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/src/org/tukaani/xz/check/CRC64.java b/src/org/tukaani/xz/check/CRC64.java index f40dbd7..a590a25 100644 --- a/src/org/tukaani/xz/check/CRC64.java +++ b/src/org/tukaani/xz/check/CRC64.java @@ -1,7 +1,8 @@ /* * CRC64 * - * Author: Lasse Collin + * Authors: Brett Okken + * Lasse Collin * * This file has been put into the public domain. * You can do whatever you want with this file. @@ -10,38 +11,53 @@ package org.tukaani.xz.check; public class CRC64 extends Check { - private static final long poly = 0xC96C5795D7870F42L; - private static final long[] crcTable = new long[256]; - - private long crc = -1; + private static final long[][] TABLE = new long[4][256]; static { - for (int b = 0; b < crcTable.length; ++b) { - long r = b; + final long poly64 = 0xC96C5795D7870F42L; + + for (int s = 0; s < 4; ++s) { + for (int b = 0; b < 256; ++b) { + long r = s == 0 ? b : TABLE[s - 1][b]; for (int i = 0; i < 8; ++i) { - if ((r & 1) == 1) - r = (r >>> 1) ^ poly; - else - r >>>= 1; + if ((r & 1) == 1) { + r = (r >>> 1) ^ poly64; + } else { + r >>>= 1; + } } - - crcTable[b] = r; + TABLE[s][b] = r; + } } } + private long crc = -1; + public CRC64() { size = 8; name = "CRC64"; } + @Override public void update(byte[] buf, int off, int len) { - int end = off + len; + final int end = off + len; + int i = off; + + for (int end4 = end - 3; i < end4; i += 4) { + final int tmp = (int)crc; + crc = TABLE[3][(tmp & 0xFF) ^ (buf[i] & 0xFF)] ^ + TABLE[2][((tmp >>> 8) & 0xFF) ^ (buf[i + 1] & 0xFF)] ^ + (crc >>> 32) ^ + TABLE[1][((tmp >>> 16) & 0xFF) ^ (buf[i + 2] & 0xFF)] ^ + TABLE[0][((tmp >>> 24) & 0xFF) ^ (buf[i + 3] & 0xFF)]; + } - while (off < end) - crc = crcTable[(buf[off++] & 0xFF) ^ ((int)crc & 0xFF)] - ^ (crc >>> 8); + while (i < end) + crc = TABLE[0][(buf[i++] & 0xFF) ^ ((int)crc & 0xFF)] ^ + (crc >>> 8); } + @Override public byte[] finish() { long value = ~crc; crc = -1; -- cgit v1.2.3 From 09e93bd21c1b276c72372673728fc4b346f8708d Mon Sep 17 00:00:00 2001 From: Lasse Collin Date: Mon, 8 Mar 2021 18:22:46 +0200 Subject: Speed optimization to LZDecoder.repeat. With extremely compressible data this may even double the LZMA2 decompression speed. However, with typical files the improvement is minor (possibly only 1-2 %). Big thanks to Brett Okken. He suggested using a loop where the amount to copy doubles on each iteration which is a great idea in a Java implementation of this method. He also took care of benchmarking several different alternatives. --- src/org/tukaani/xz/lz/LZDecoder.java | 39 +++++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/src/org/tukaani/xz/lz/LZDecoder.java b/src/org/tukaani/xz/lz/LZDecoder.java index 85b2ca1..6115e54 100644 --- a/src/org/tukaani/xz/lz/LZDecoder.java +++ b/src/org/tukaani/xz/lz/LZDecoder.java @@ -92,14 +92,43 @@ public final class LZDecoder { pendingDist = dist; int back = pos - dist - 1; - if (dist >= pos) + if (back < 0) { + // The distance wraps around to the end of the cyclic dictionary + // buffer. We cannot get here if the dictionary isn't full. + assert full == bufSize; back += bufSize; + // Here we will never copy more than dist + 1 bytes and + // so the copying won't repeat from its own output. + // Thus, we can always use arraycopy safely. + int copySize = Math.min(bufSize - back, left); + assert copySize <= dist + 1; + + System.arraycopy(buf, back, buf, pos, copySize); + pos += copySize; + back = 0; + left -= copySize; + + if (left == 0) + return; + } + + assert back < pos; + assert left > 0; + do { - buf[pos++] = buf[back++]; - if (back == bufSize) - back = 0; - } while (--left > 0); + // Determine the number of bytes to copy on this loop iteration: + // copySize is set so that the source and destination ranges + // don't overlap. If "left" is large enough, the destination + // range will start right after the last byte of the source + // range. This way we don't need to advance "back" which + // allows the next iteration of this loop to copy (up to) + // twice the number of bytes. + int copySize = Math.min(left, pos - back); + System.arraycopy(buf, back, buf, pos, copySize); + pos += copySize; + left -= copySize; + } while (left > 0); if (full < pos) full = pos; -- cgit v1.2.3 From 4f10e1d075b8078b65e5b7bf5ce47d180609635f Mon Sep 17 00:00:00 2001 From: Lasse Collin Date: Mon, 8 Mar 2021 19:24:07 +0200 Subject: Fix a wrong variable name in a comment in build.properties. --- build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.properties b/build.properties index 243dbd6..7ac8178 100644 --- a/build.properties +++ b/build.properties @@ -25,7 +25,7 @@ debug = false # If you need to build this on an older JDK: # - Set sourcever appropriately (5 or higher) # - Comment the sourcever9 line below to disable building Java 9 files. -# - Adjust extdoc_url and extdoc_dir to point to older documentation. +# - Adjust extdoc_url and extdoc_file to point to older documentation. sourcever = 7 sourcever9 = 9 -- cgit v1.2.3 From b0f11a51b821f353fbfa63b8210f2ac89c4fae74 Mon Sep 17 00:00:00 2001 From: Lasse Collin Date: Mon, 8 Mar 2021 19:43:45 +0200 Subject: Update README. --- README | 57 ++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 44 insertions(+), 13 deletions(-) diff --git a/README b/README index 8869996..ed592c8 100644 --- a/README +++ b/README @@ -18,23 +18,54 @@ Introduction https://tukaani.org/xz/java.html - The source code is compatible with Java 5 and later. + The source code is compatible with Java 5 and later (except + module-info.java which is Java 9 or later). However, the default + build options require OpenJDK 11 or later, and create Java 7 + compatible binaries. -Building +Building with Apache Ant - It is recommended to use Apache Ant. Type "ant" to compile the - classes and create the .jar files. Type "ant doc" to build the - javadoc HTML documentation. Note that building the documentation - will download a small file named "package-list" from Oracle to - enable linking to the documentation of the standard Java classes. + Type "ant" to compile the classes and create the .jar files. + Type "ant doc" to build the javadoc HTML documentation. Note + that building the documentation will download a small file named + "element-list" or "package-list" from Oracle to enable linking to + the documentation of the standard Java classes. - If you are using OpenJDK 9 or later, you will need to edit the - "sourcever = 1.5" line in the file "build.properties" before - running "ant". Set it to 1.6 or higher. The default value 1.5 - isn't supported by OpenJDK 9 or later. + If you are using Ant older than 1.9.8: - If you cannot or don't want to use Ant, just compile all .java - files under the "src" directory. + Edit build.xml and remove the release attributes from + tags, that is, remove all occurrences of these two lines: + + release="${sourcever}" + + release="${sourcever9}" + + The downside of the above is that then -source and -target + options will be used instead of --release. + + If you are using OpenJDK version older than 11: + + Adjust extdoc_url and extdoc_file to point to an older URL + and to use "package-list" instead of "element-list". This + modification isn't required if the documentation won't be + built. + + If you are using OpenJDK version older than 9: + + Comment the sourcever9 line in the file build.properties. + When it is commented, module-info.java won't be built and + xz.jar won't be a modular JAR. + + If you are using OpenJDK version older than 7: + + In build.properties, set "sourcever = 5" or "sourcever = 6" + to be compatible with Java 5 or 6. + +Building without Apache Ant + + If you cannot or don't want to use Ant, just compile all .java files + under the "src" directory (possibly skip the demo files src/*.java). + For module support (Java >= 9) compile also src9/module-info.java. Demo programs -- cgit v1.2.3 From b9aff7f4c0c3a6bdaa306d926c939fa81a72cb07 Mon Sep 17 00:00:00 2001 From: Lasse Collin Date: Mon, 8 Mar 2021 19:44:06 +0200 Subject: Update COPYING. --- COPYING | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/COPYING b/COPYING index c1d404d..8dd1764 100644 --- a/COPYING +++ b/COPYING @@ -2,9 +2,9 @@ Licensing of XZ for Java ======================== - All the files in this package have been written by Lasse Collin - and/or Igor Pavlov. All these files have been put into the - public domain. You can do whatever you want with these files. + All the files in this package have been written by Lasse Collin, + Igor Pavlov, and/or Brett Okken. All these files have been put into + the public domain. You can do whatever you want with these files. This software is provided "as is", without any warranty. -- cgit v1.2.3 From 8ce3788cb4f5602dab33782b5edaf16a6b13571e Mon Sep 17 00:00:00 2001 From: Lasse Collin Date: Mon, 8 Mar 2021 20:27:39 +0200 Subject: Add an example to the javadoc of SeekableXZInputStream. --- src/org/tukaani/xz/SeekableXZInputStream.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/org/tukaani/xz/SeekableXZInputStream.java b/src/org/tukaani/xz/SeekableXZInputStream.java index bc08671..74da2e1 100644 --- a/src/org/tukaani/xz/SeekableXZInputStream.java +++ b/src/org/tukaani/xz/SeekableXZInputStream.java @@ -69,6 +69,21 @@ import org.tukaani.xz.index.BlockInfo; * --block-list=SIZES which allows specifying sizes of * individual Blocks. * + *

Example: getting the uncompressed size of a .xz file

+ *
+ * String filename = "foo.xz";
+ * SeekableFileInputStream seekableFile
+ *         = new SeekableFileInputStream(filename);
+ *
+ * try {
+ *     SeekableXZInputStream seekableXZ
+ *             = new SeekableXZInputStream(seekableFile);
+ *     System.out.println("Uncompressed size: " + seekableXZ.length());
+ * } finally {
+ *     seekableFile.close();
+ * }
+ * 
+ * * @see SeekableFileInputStream * @see XZInputStream * @see XZOutputStream -- cgit v1.2.3 From df0d765a562091affe6b6724b20137da030d5373 Mon Sep 17 00:00:00 2001 From: Lasse Collin Date: Fri, 12 Mar 2021 17:18:27 +0200 Subject: Update author/contributor info to package-info.java and pom_template.xml. --- maven/pom_template.xml | 5 +++++ src/org/tukaani/xz/package-info.java | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/maven/pom_template.xml b/maven/pom_template.xml index 235844c..666c51a 100644 --- a/maven/pom_template.xml +++ b/maven/pom_template.xml @@ -53,6 +53,11 @@ Igor Pavlov http://7-zip.org/ + + + Brett Okken + brett.okken.os@gmail.com + diff --git a/src/org/tukaani/xz/package-info.java b/src/org/tukaani/xz/package-info.java index 1f20e89..ad23233 100644 --- a/src/org/tukaani/xz/package-info.java +++ b/src/org/tukaani/xz/package-info.java @@ -38,7 +38,7 @@ *

* XZ for Java has been put into the public domain, thus you can do * whatever you want with it. All the files in the package have been - * written by Lasse Collin and/or Igor Pavlov. + * written by Lasse Collin, Igor Pavlov, and/or Brett Okken. *

* This software is provided "as is", without any warranty. */ -- cgit v1.2.3 From d6b1eb3ec3f567ce26e75c49cf8def44da6ef6d0 Mon Sep 17 00:00:00 2001 From: Lasse Collin Date: Fri, 12 Mar 2021 17:32:26 +0200 Subject: Add fileset-src9.txt to fileset-misc.txt. This was forgotten when fileset-src9.txt was added. --- fileset-misc.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/fileset-misc.txt b/fileset-misc.txt index 9d16359..3b1d150 100644 --- a/fileset-misc.txt +++ b/fileset-misc.txt @@ -5,6 +5,7 @@ THANKS build.xml build.properties fileset-src.txt +fileset-src9.txt fileset-misc.txt .gitignore maven/README -- cgit v1.2.3 From 32348847366babe96ee491e423dfa2397730c07b Mon Sep 17 00:00:00 2001 From: Lasse Collin Date: Fri, 12 Mar 2021 18:31:37 +0200 Subject: Fixing building of the docs. The linkoffline attribute in Ant 1.10.9 only looks for the file "package-list" while Java >= 11 use "element-list" instead. To workaround this problem in Ant, rename element-list to package-list. This seems to work fine with Java 15 but obviously it's a hack that might break some day. Don't specify the source language version when building the docs. If source="7" is used and linking to Java 15 documentation that uses element-list, this warning will be repeated for every file: The code being documented uses packages in the unnamed module, but the packages defined in https://docs.oracle.com/en/java/javase/15/docs/api/ are in named modules. --- build.xml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/build.xml b/build.xml index 05bd9ad..0559836 100644 --- a/build.xml +++ b/build.xml @@ -36,10 +36,13 @@ description="Generates HTML documentation with javadoc"> + + dest="${extdoc_dir}/package-list" skipexisting="true"/> -- cgit v1.2.3 From 75cf8d2805979c7e89025696aa1d527206fded19 Mon Sep 17 00:00:00 2001 From: Lasse Collin Date: Fri, 12 Mar 2021 18:31:45 +0200 Subject: Add NEWS for 1.9. --- NEWS | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/NEWS b/NEWS index 3183f2e..d18a53b 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,32 @@ XZ for Java release notes ========================= +1.9 (2021-03-12) + + * Add LZMAInputStream.enableRelaxedEndCondition(). It allows + decompression of LZMA streams whose uncompressed size is known + but it is unknown if the end of stream marker is present. This + method is meant to be useful in Apache Commons Compress to + support .7z files created by certain very old 7-Zip versions. + Such files have the end of stream marker in the LZMA data even + though the uncompressed size is known. 7-Zip supports such files + and thus other implementations of the .7z format should support + them too. + + * Make LZMA/LZMA2 decompression faster. With files that compress + extremely well the performance can be a lot better but with + more typical files the improvement is minor. + + * Make the CRC64 code faster. + + * Add module-info.java as multi-release JAR. The attribute + Automatic-Module-Name was removed. + + * The binaries for XZ for Java 1.9 in the Maven Central now + require Java 7. Building the package requires at least Java 9 + for module-info support but otherwise the code should still be + Java 5 compatible (see README and comments in build.properties). + 1.8 (2018-01-04) * Fix a binary compatibility regression: XZ for Java 1.7 binaries -- cgit v1.2.3 From a6e4dc6aca696af220ca64f9336786d5fbff3c0b Mon Sep 17 00:00:00 2001 From: Lasse Collin Date: Fri, 12 Mar 2021 18:31:55 +0200 Subject: Bump the version number to 1.9. --- build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.properties b/build.properties index 7ac8178..052d972 100644 --- a/build.properties +++ b/build.properties @@ -9,7 +9,7 @@ title = XZ data compression homepage = https://tukaani.org/xz/java.html -version = 1.8 +version = 1.9 debug = false # sourcever sets --release for javac 9 (or later) or -source and -target for -- cgit v1.2.3