This is an automated email from the ASF dual-hosted git repository.
garydgregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-compress.git
The following commit(s) were added to refs/heads/master by this push:
new 7895659d4 Javadoc
7895659d4 is described below
commit 7895659d4f3e309580f0a2c06b89bc72a3506b7d
Author: Gary Gregory <[email protected]>
AuthorDate: Fri Jul 31 11:29:14 2026 -0400
Javadoc
Reduce vertical whitespace.
---
...stractLhStaticHuffmanCompressorInputStream.java | 104 +++++++++------------
.../compress/compressors/lha/BinaryTree.java | 47 +++-------
.../compress/compressors/lha/CircularBuffer.java | 14 ++-
.../compressors/lha/Lh4CompressorInputStream.java | 3 +-
.../compressors/lha/Lh5CompressorInputStream.java | 5 +-
.../compressors/lha/Lh6CompressorInputStream.java | 5 +-
.../compressors/lha/Lh7CompressorInputStream.java | 5 +-
7 files changed, 77 insertions(+), 106 deletions(-)
diff --git
a/src/main/java/org/apache/commons/compress/compressors/lha/AbstractLhStaticHuffmanCompressorInputStream.java
b/src/main/java/org/apache/commons/compress/compressors/lha/AbstractLhStaticHuffmanCompressorInputStream.java
index e5756fc9b..4813c57c9 100644
---
a/src/main/java/org/apache/commons/compress/compressors/lha/AbstractLhStaticHuffmanCompressorInputStream.java
+++
b/src/main/java/org/apache/commons/compress/compressors/lha/AbstractLhStaticHuffmanCompressorInputStream.java
@@ -30,39 +30,48 @@
import org.apache.commons.io.input.CloseShieldInputStream;
/**
- * This is an implementation of a static Huffman compressor input stream for
LHA files that
- * supports lh4, lh5, lh6 and lh7 compression methods.
+ * Implements a static Huffman compressor input stream for LHA files that
supports lh4, lh5, lh6 and lh7 compression methods.
*/
abstract class AbstractLhStaticHuffmanCompressorInputStream extends
CompressorInputStream implements InputStreamStatistics {
+
/**
- * Number of bits used to encode the command decoding tree length.
+ * Number of bits used to encode the command decoding tree length.
*/
private static final int COMMAND_DECODING_LENGTH_BITS = 5;
+
/**
* Maximum number of codes in the command decoding tree.
*/
private static final int MAX_NUMBER_OF_COMMAND_DECODING_CODE_LENGTHS = 19;
+
/**
* Number of bits used to encode the command tree length.
*/
private static final int COMMAND_TREE_LENGTH_BITS = 9;
+
/**
* Number of literal codes (0-255).
*/
private static final int NUMBER_OF_LITERAL_CODES = 0x100;
+
/**
* Number of bits used to encode the code length.
*/
private static final int CODE_LENGTH_BITS = 3;
+
private static final int MAX_CODE_LENGTH = 16;
private BitInputStream bin;
+
private CircularBuffer buffer;
+
private int blockSize;
+
/**
* Command is either a literal or a copy command.
*/
private BinaryTree commandTree;
+
/**
* Distance is the offset to copy from the sliding dictionary.
*/
@@ -71,12 +80,11 @@ abstract class AbstractLhStaticHuffmanCompressorInputStream
extends CompressorIn
/**
* Constructs a new CompressorInputStream which decompresses bytes read
from the specified stream.
*
- * @param in the InputStream from which to read compressed data
- * @throws IOException if an I/O error occurs
+ * @param in the InputStream from which to read compressed data.
+ * @throws IOException if an I/O error occurs.
*/
AbstractLhStaticHuffmanCompressorInputStream(final InputStream in) throws
IOException {
this.bin = new BitInputStream(in == System.in ?
CloseShieldInputStream.wrap(in) : in, ByteOrder.BIG_ENDIAN);
-
// Create a sliding dictionary buffer that can hold the full
dictionary size and the maximum match length
this.buffer = new CircularBuffer(getDictionarySize() +
getMaxMatchLength());
}
@@ -97,7 +105,7 @@ public void close() throws IOException {
/**
* Fill the sliding dictionary with more data.
*
- * @throws IOException if an I/O error occurs
+ * @throws IOException if an I/O error occurs.
*/
private void fillBuffer() throws IOException {
if (this.blockSize == -1) {
@@ -106,23 +114,17 @@ private void fillBuffer() throws IOException {
}
if (this.blockSize == 0) {
// Start to read the next block
-
// Read the block size (number of commands to read)
this.blockSize = (int) bin.readBits(16);
if (this.blockSize == -1) {
// End of stream
return;
}
-
final BinaryTree commandDecodingTree = readCommandDecodingTree();
-
this.commandTree = readCommandTree(commandDecodingTree);
-
this.distanceTree = readDistanceTree();
}
-
this.blockSize--;
-
final int command = commandTree.read(bin);
if (command == -1) {
throw new CompressorException("Unexpected end of stream");
@@ -134,7 +136,6 @@ private void fillBuffer() throws IOException {
// Copy command, read the distance and calculate the length from
the command
final int distance = readDistance();
final int length = command - NUMBER_OF_LITERAL_CODES +
getCopyThreshold();
-
// Copy the data from the sliding dictionary and add to the buffer
buffer.copy(distance + 1, length);
}
@@ -146,10 +147,9 @@ public long getCompressedCount() {
}
/**
- * Gets the threshold for copying data from the sliding dictionary. This
is the minimum
- * possible number of bytes that will be part of a copy command.
+ * Gets the threshold for copying data from the sliding dictionary. This
is the minimum possible number of bytes that will be part of a copy command.
*
- * @return the copy threshold
+ * @return the copy threshold.
*/
int getCopyThreshold() {
return 3;
@@ -158,14 +158,14 @@ int getCopyThreshold() {
/**
* Gets the number of bits used for the dictionary size.
*
- * @return the number of bits used for the dictionary size
+ * @return the number of bits used for the dictionary size.
*/
abstract int getDictionaryBits();
/**
* Gets the size of the dictionary.
*
- * @return the size of the dictionary
+ * @return the size of the dictionary.
*/
int getDictionarySize() {
return 1 << getDictionaryBits();
@@ -174,24 +174,23 @@ int getDictionarySize() {
/**
* Gets the number of bits used for the distance.
*
- * @return the number of bits used for the distance
+ * @return the number of bits used for the distance.
*/
abstract int getDistanceBits();
/**
* Gets the maximum match length for the copy command.
*
- * @return the maximum match length
+ * @return the maximum match length.
*/
int getMaxMatchLength() {
return 256;
}
/**
- * Gets the maximum number of commands in the command tree.
- * This is 256 literals (0-255) and 254 copy lengths combinations (3-256).
+ * Gets the maximum number of commands in the command tree. This is 256
literals (0-255) and 254 copy lengths combinations (3-256).
*
- * @return the maximum number of commands
+ * @return the maximum number of commands.
*/
int getMaxNumberOfCommands() {
return NUMBER_OF_LITERAL_CODES + getMaxMatchLength() -
getCopyThreshold() + 1;
@@ -200,7 +199,7 @@ int getMaxNumberOfCommands() {
/**
* Gets the maximum number of distance codes in the distance tree.
*
- * @return the maximum number of distance codes
+ * @return the maximum number of distance codes.
*/
int getMaxNumberOfDistanceCodes() {
return getDictionaryBits() + 1;
@@ -219,18 +218,17 @@ public int read() throws IOException {
throw new CompressorException("Bad LHA stream", e);
}
}
-
final int ret = buffer.get();
count(ret < 0 ? 0 : 1); // Increment input stream statistics
return ret;
}
/**
- * Read the specified number of bits from the underlying stream throwing
CompressorException
- * if the end of the stream is reached before reading the requested number
of bits.
+ * Read the specified number of bits from the underlying stream throwing
CompressorException if the end of the stream is reached before reading the
+ * requested number of bits.
*
- * @param count the number of bits to read
- * @return the bits concatenated as an int using the stream's byte order
+ * @param count the number of bits to read.
+ * @return the bits concatenated as an int using the stream's byte order.
* @throws IOException if an I/O error occurs.
*/
private int readBits(final int count) throws IOException {
@@ -238,16 +236,14 @@ private int readBits(final int count) throws IOException {
if (value < 0) {
throw new CompressorException("Unexpected end of stream");
}
-
return (int) value;
}
/**
- * Read code length (depth in tree). Usually 0-7 but could be higher and
if so,
- * count the number of following consecutive one bits and add to the
length.
+ * Reads code length (depth in tree). Usually 0-7 but could be higher and
if so, count the number of following consecutive one bits and add to the length.
*
- * @return code length
- * @throws IOException if an I/O error occurs
+ * @return code length.
+ * @throws IOException if an I/O error occurs.
*/
int readCodeLength() throws IOException {
int len = readBits(CODE_LENGTH_BITS);
@@ -257,29 +253,25 @@ int readCodeLength() throws IOException {
if (++len > MAX_CODE_LENGTH) {
throw new CompressorException("Code length overflow");
}
-
bit = bin.readBit();
}
-
if (bit == -1) {
throw new CompressorException("Unexpected end of stream");
}
}
-
return len;
}
/**
- * Read the command decoding tree. The command decoding tree is used when
reading the command tree
- * which is then actually used to decode the commands (literals or copy
commands).
+ * Reads the command decoding tree. The command decoding tree is used when
reading the command tree which is then actually used to decode the commands
+ * (literals or copy commands).
*
- * @return the command decoding tree
- * @throws IOException if an I/O error occurs
+ * @return the command decoding tree.
+ * @throws IOException if an I/O error occurs.
*/
BinaryTree readCommandDecodingTree() throws IOException {
// Number of code lengths to read
final int numCodeLengths = readBits(COMMAND_DECODING_LENGTH_BITS);
-
if (numCodeLengths > MAX_NUMBER_OF_COMMAND_DECODING_CODE_LENGTHS) {
throw new CompressorException("Code length table has invalid size
(%d > %d)", numCodeLengths, MAX_NUMBER_OF_COMMAND_DECODING_CODE_LENGTHS);
}
@@ -291,7 +283,6 @@ BinaryTree readCommandDecodingTree() throws IOException {
final int[] codeLengths = new int[numCodeLengths];
for (int index = 0; index < numCodeLengths; index++) {
codeLengths[index] = readCodeLength();
-
if (index == 2) {
// After reading the first three code lengths, we read a 2-bit
skip range
index += readBits(2);
@@ -301,15 +292,14 @@ BinaryTree readCommandDecodingTree() throws IOException {
}
/**
- * Read the command tree which is used to decode the commands (literals or
copy commands).
+ * Reads the command tree which is used to decode the commands (literals
or copy commands).
*
- * @param commandDecodingTree the Huffman tree used to decode the command
lengths
- * @return the command tree
- * @throws IOException if an I/O error occurs
+ * @param commandDecodingTree the Huffman tree used to decode the command
lengths.
+ * @return the command tree.
+ * @throws IOException if an I/O error occurs.
*/
BinaryTree readCommandTree(final BinaryTree commandDecodingTree) throws
IOException {
final int numCodeLengths = readBits(COMMAND_TREE_LENGTH_BITS);
-
if (numCodeLengths > getMaxNumberOfCommands()) {
throw new CompressorException("Code length table has invalid size
(%d > %d)", numCodeLengths, getMaxNumberOfCommands());
}
@@ -321,7 +311,6 @@ BinaryTree readCommandTree(final BinaryTree
commandDecodingTree) throws IOExcept
final int[] codeLengths = new int[numCodeLengths];
for (int index = 0; index < numCodeLengths;) {
final int codeOrSkipRange = commandDecodingTree.read(bin);
-
switch (codeOrSkipRange) {
case -1:
throw new CompressorException("Unexpected end of stream");
@@ -347,11 +336,11 @@ BinaryTree readCommandTree(final BinaryTree
commandDecodingTree) throws IOExcept
}
/**
- * Read the distance by first decoding the number of bits to read from the
distance tree
- * and then reading the actual distance value from the bit input stream.
+ * Reads the distance by first decoding the number of bits to read from
the distance tree and then reading the actual distance value from the bit input
+ * stream.
*
- * @return the distance
- * @throws IOException if an I/O error occurs
+ * @return the distance.
+ * @throws IOException if an I/O error occurs.
*/
private int readDistance() throws IOException {
// Determine the number of bits to read for the distance by reading an
entry from the distance tree
@@ -371,15 +360,14 @@ private int readDistance() throws IOException {
}
/**
- * Read the distance tree which is used to decode the distance of the copy
command.
+ * Reads the distance tree which is used to decode the distance of the
copy command.
*
- * @return the distance tree
- * @throws IOException if an I/O error occurs
+ * @return the distance tree.
+ * @throws IOException if an I/O error occurs.
*/
private BinaryTree readDistanceTree() throws IOException {
// Number of code lengths to read
final int numCodeLengths = readBits(getDistanceBits());
-
if (numCodeLengths > getMaxNumberOfDistanceCodes()) {
throw new CompressorException("Code length table has invalid size
(%d > %d)", numCodeLengths, getMaxNumberOfDistanceCodes());
}
diff --git
a/src/main/java/org/apache/commons/compress/compressors/lha/BinaryTree.java
b/src/main/java/org/apache/commons/compress/compressors/lha/BinaryTree.java
index 416b6b853..63e8e83d8 100644
--- a/src/main/java/org/apache/commons/compress/compressors/lha/BinaryTree.java
+++ b/src/main/java/org/apache/commons/compress/compressors/lha/BinaryTree.java
@@ -27,16 +27,14 @@
import org.apache.commons.lang3.ArrayFill;
/**
- * Binary tree of positive values.
- *
- * Copied from org.apache.commons.compress.archivers.zip.BinaryTree and
modified for LHA.
+ * Binary tree of positive values. Copied from
org.apache.commons.compress.archivers.zip.BinaryTree and modified for LHA.
*/
class BinaryTree {
- /** Value in the array indicating an undefined node */
+ /** Value in the array indicating an undefined node. */
private static final int UNDEFINED = -1;
- /** Value in the array indicating a non leaf node */
+ /** Value in the array indicating a non leaf node. */
private static final int NODE = -2;
/**
@@ -45,16 +43,13 @@ class BinaryTree {
private final int[] tree;
/**
- * Constructs a binary tree from the given array that contains the depth
(code length) in the
- * binary tree as values in the array and the index into the array as the
value of the leaf node.
- *
- * If the array contains a single value, this is a special case where
there is only one node in the
- * tree (the root node) and it contains the value. For this case, the
array contains the value of
- * the root node instead of the depth in the tree. This special case also
means that no bits will
- * be read from the bit stream when the read method is called, as there
are no children to traverse.
+ * Constructs a binary tree from the given array that contains the depth
(code length) in the binary tree as values in the array and the index into the
+ * array as the value of the leaf node. If the array contains a single
value, this is a special case where there is only one node in the tree (the root
+ * node) and it contains the value. For this case, the array contains the
value of the root node instead of the depth in the tree. This special case also
+ * means that no bits will be read from the bit stream when the read
method is called, as there are no children to traverse.
*
- * @param array the array to build the binary tree from
- * @throws CompressorException if the tree is invalid
+ * @param array the array to build the binary tree from.
+ * @throws CompressorException if the tree is invalid.
*/
BinaryTree(final int... array) throws CompressorException {
if (array.length == 1) {
@@ -62,50 +57,40 @@ class BinaryTree {
this.tree = new int[] { array[0] };
return;
}
-
// Determine the maximum depth of the tree from the input array
final int maxDepth = Arrays.stream(array).max().getAsInt();
if (maxDepth == 0) {
throw new CompressorException("Tree contains no leaf nodes");
}
-
// Allocate binary tree with enough space for all nodes
this.tree = initTree(maxDepth);
-
int treePos = 0;
-
// Add root node pointing to left (0) and right (1) children
this.tree[treePos++] = NODE;
-
// Iterate over each possible tree depth (starting from 1)
for (int currentDepth = 1; currentDepth <= maxDepth; currentDepth++) {
final int startPos = (1 << currentDepth) - 1; // Start position
for the first node at this depth
final int maxNodesAtCurrentDepth = 1 << currentDepth; // Max
number of nodes at this depth
int numNodesAtCurrentDepth = treePos - startPos; // Number of
nodes added at this depth taking into account any already skipped nodes
(UNDEFINED)
-
// Add leaf nodes for values with the current depth
for (int value = 0; value < array.length; value++) {
if (array[value] == currentDepth) {
if (numNodesAtCurrentDepth == maxNodesAtCurrentDepth) {
throw new CompressorException("Tree contains too many
leaf nodes for depth %d", currentDepth);
}
-
this.tree[treePos++] = value; // Add leaf (value) node
numNodesAtCurrentDepth++;
}
}
-
// Add nodes pointing to child nodes until the maximum number of
nodes at this depth is reached
int skipToTreePos = -1;
while (currentDepth != maxDepth && numNodesAtCurrentDepth <
maxNodesAtCurrentDepth) {
if (skipToTreePos == -1) {
skipToTreePos = 2 * treePos + 1; // Next depth's tree
position that this node's left (0) child would occupy
}
-
this.tree[treePos++] = NODE; // Add node pointing to left (0)
and right (1) children
numNodesAtCurrentDepth++;
}
-
if (skipToTreePos != -1) {
treePos = skipToTreePos; // Skip to the next depth's tree
position based on the first node at this depth
}
@@ -115,30 +100,27 @@ class BinaryTree {
/**
* Initializes the binary tree with the specified depth but with all nodes
as UNDEFINED.
*
- * @param depth the depth of the tree, must be between 0 and 16 (inclusive)
- * @return an array representing the binary tree, initialized with
UNDEFINED values
- * @throws CompressorException for invalid depth
+ * @param depth the depth of the tree, must be between 0 and 16
(inclusive).
+ * @return an array representing the binary tree, initialized with
UNDEFINED values.
+ * @throws CompressorException for invalid depth.
*/
private int[] initTree(final int depth) throws CompressorException {
if (depth < 0 || depth > 16) {
throw new CompressorException("Tree depth must not be negative and
not bigger than 16 but is " + depth);
}
-
final int arraySize = depth == 0 ? 1 : (int) ((1L << depth + 1) - 1);
// Depth 0 has only a single node (the root)
-
return ArrayFill.fill(new int[arraySize], UNDEFINED);
}
/**
* Reads a value from the specified bit stream.
- *
+ *.
* @param stream The data source.
- * @return the value decoded, or -1 if the end of the stream is reached
+ * @return the value decoded, or -1 if the end of the stream is reached.
* @throws IOException on error.
*/
public int read(final BitInputStream stream) throws IOException {
int currentIndex = 0;
-
while (true) {
final int value = tree[currentIndex];
if (value == NODE) {
@@ -147,7 +129,6 @@ public int read(final BitInputStream stream) throws
IOException {
if (bit == -1) {
return -1;
}
-
currentIndex = 2 * currentIndex + 1 + bit;
} else if (value == UNDEFINED) {
throw new CompressorException("Invalid bitstream. The node at
index %d is not defined.", currentIndex);
diff --git
a/src/main/java/org/apache/commons/compress/compressors/lha/CircularBuffer.java
b/src/main/java/org/apache/commons/compress/compressors/lha/CircularBuffer.java
index 0b8a56323..1f15442b1 100644
---
a/src/main/java/org/apache/commons/compress/compressors/lha/CircularBuffer.java
+++
b/src/main/java/org/apache/commons/compress/compressors/lha/CircularBuffer.java
@@ -20,22 +20,20 @@
package org.apache.commons.compress.compressors.lha;
/**
- * Circular byte buffer.
- *
- * Copied from org.apache.commons.compress.archivers.zip.CircularBuffer and
modified for LHA.
+ * Circular byte buffer. Copied from
org.apache.commons.compress.archivers.zip.CircularBuffer and modified for LHA.
*/
final class CircularBuffer {
- /** Size of the buffer */
+ /** Size of the buffer. */
private final int size;
- /** The buffer */
+ /** The buffer. */
private final byte[] buffer;
- /** Index of the next data to be read from the buffer */
+ /** Index of the next data to be read from the buffer. */
private int readIndex;
- /** Index of the next data written in the buffer */
+ /** Index of the next data written in the buffer. */
private int writeIndex;
private int bytesAvailable;
@@ -43,7 +41,7 @@ final class CircularBuffer {
/**
* Creates a new circular buffer with the given size.
*
- * @param size the size of the buffer
+ * @param size the size of the buffer.
*/
CircularBuffer(final int size) {
this.size = size;
diff --git
a/src/main/java/org/apache/commons/compress/compressors/lha/Lh4CompressorInputStream.java
b/src/main/java/org/apache/commons/compress/compressors/lha/Lh4CompressorInputStream.java
index 396b8ff8a..a8063758c 100644
---
a/src/main/java/org/apache/commons/compress/compressors/lha/Lh4CompressorInputStream.java
+++
b/src/main/java/org/apache/commons/compress/compressors/lha/Lh4CompressorInputStream.java
@@ -28,10 +28,11 @@
* @since 1.29.0
*/
public class Lh4CompressorInputStream extends
AbstractLhStaticHuffmanCompressorInputStream {
+
/**
* Constructs a new Lh4CompressorInputStream which decompresses bytes read
from the specified stream.
*
- * @param in the InputStream from which to read compressed data
+ * @param in the InputStream from which to read compressed data.
* @throws IOException if an I/O error occurs
*/
public Lh4CompressorInputStream(final InputStream in) throws IOException {
diff --git
a/src/main/java/org/apache/commons/compress/compressors/lha/Lh5CompressorInputStream.java
b/src/main/java/org/apache/commons/compress/compressors/lha/Lh5CompressorInputStream.java
index 086dca62b..bb632890c 100644
---
a/src/main/java/org/apache/commons/compress/compressors/lha/Lh5CompressorInputStream.java
+++
b/src/main/java/org/apache/commons/compress/compressors/lha/Lh5CompressorInputStream.java
@@ -28,11 +28,12 @@
* @since 1.29.0
*/
public class Lh5CompressorInputStream extends
AbstractLhStaticHuffmanCompressorInputStream {
+
/**
* Constructs a new Lh5CompressorInputStream which decompresses bytes read
from the specified stream.
*
- * @param in the InputStream from which to read compressed data
- * @throws IOException if an I/O error occurs
+ * @param in the InputStream from which to read compressed data.
+ * @throws IOException if an I/O error occurs.
*/
public Lh5CompressorInputStream(final InputStream in) throws IOException {
super(in);
diff --git
a/src/main/java/org/apache/commons/compress/compressors/lha/Lh6CompressorInputStream.java
b/src/main/java/org/apache/commons/compress/compressors/lha/Lh6CompressorInputStream.java
index 59c96194b..156c78605 100644
---
a/src/main/java/org/apache/commons/compress/compressors/lha/Lh6CompressorInputStream.java
+++
b/src/main/java/org/apache/commons/compress/compressors/lha/Lh6CompressorInputStream.java
@@ -28,11 +28,12 @@
* @since 1.29.0
*/
public class Lh6CompressorInputStream extends
AbstractLhStaticHuffmanCompressorInputStream {
+
/**
* Constructs a new Lh6CompressorInputStream which decompresses bytes read
from the specified stream.
*
- * @param in the InputStream from which to read compressed data
- * @throws IOException if an I/O error occurs
+ * @param in the InputStream from which to read compressed data.
+ * @throws IOException if an I/O error occurs.
*/
public Lh6CompressorInputStream(final InputStream in) throws IOException {
super(in);
diff --git
a/src/main/java/org/apache/commons/compress/compressors/lha/Lh7CompressorInputStream.java
b/src/main/java/org/apache/commons/compress/compressors/lha/Lh7CompressorInputStream.java
index a27448b2d..26dca2d58 100644
---
a/src/main/java/org/apache/commons/compress/compressors/lha/Lh7CompressorInputStream.java
+++
b/src/main/java/org/apache/commons/compress/compressors/lha/Lh7CompressorInputStream.java
@@ -28,11 +28,12 @@
* @since 1.29.0
*/
public class Lh7CompressorInputStream extends
AbstractLhStaticHuffmanCompressorInputStream {
+
/**
* Constructs a new Lh7CompressorInputStream which decompresses bytes read
from the specified stream.
*
- * @param in the InputStream from which to read compressed data
- * @throws IOException if an I/O error occurs
+ * @param in the InputStream from which to read compressed data.
+ * @throws IOException if an I/O error occurs.
*/
public Lh7CompressorInputStream(final InputStream in) throws IOException {
super(in);