This is an automated email from the ASF dual-hosted git repository. ggregory 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 7d7b5ad6d Refactor magic numbers 7d7b5ad6d is described below commit 7d7b5ad6d8ad5d09f5ab8b6eb34fd571565187d0 Author: Gary Gregory <garydgreg...@gmail.com> AuthorDate: Wed Jan 1 11:16:53 2025 -0500 Refactor magic numbers - Rename private methods - Javadoc internals - End sentences in a period in exception messages --- .../gzip/GzipCompressorInputStream.java | 18 +++++----- .../gzip/GzipCompressorOutputStream.java | 33 ++++++++++++------ .../compress/compressors/gzip/GzipUtils.java | 40 ++++++++++++++++++++-- 3 files changed, 68 insertions(+), 23 deletions(-) diff --git a/src/main/java/org/apache/commons/compress/compressors/gzip/GzipCompressorInputStream.java b/src/main/java/org/apache/commons/compress/compressors/gzip/GzipCompressorInputStream.java index fab11a42f..1ba1828ee 100644 --- a/src/main/java/org/apache/commons/compress/compressors/gzip/GzipCompressorInputStream.java +++ b/src/main/java/org/apache/commons/compress/compressors/gzip/GzipCompressorInputStream.java @@ -267,7 +267,7 @@ public class GzipCompressorInputStream extends CompressorInputStream implements private boolean init(final boolean isFirstMember) throws IOException { if (!isFirstMember && !decompressConcatenated) { // at least one must be true - throw new IllegalStateException("Unexpected: isFirstMember and decompressConcatenated are both false!"); + throw new IllegalStateException("Unexpected: isFirstMember and decompressConcatenated are both false."); } parameters.setFileNameCharset(fileNameCharset); // Check the magic bytes without a possibility of EOFException. @@ -279,8 +279,8 @@ public class GzipCompressorInputStream extends CompressorInputStream implements return false; } - if (magic0 != 31 || in.read() != 139) { - throw new IOException(isFirstMember ? "Input is not in the .gz format" : "Unexpected data after a valid .gz stream"); + if (magic0 != GzipUtils.ID1 || in.read() != GzipUtils.ID2) { + throw new IOException(isFirstMember ? "Input is not in the .gz format." : "Unexpected data after a valid .gz stream."); } // Parsing the rest of the header may throw EOFException. @@ -292,15 +292,15 @@ public class GzipCompressorInputStream extends CompressorInputStream implements final int flg = inData.readUnsignedByte(); if ((flg & GzipUtils.FRESERVED) != 0) { - throw new IOException("Reserved flags are set in the .gz header"); + throw new IOException("Reserved flags are set in the .gz header."); } parameters.setModificationTime(ByteUtils.fromLittleEndian(inData, 4)); switch (inData.readUnsignedByte()) { // extra flags - case 2: + case GzipUtils.XFL_MAX_COMPRESSION: parameters.setCompressionLevel(Deflater.BEST_COMPRESSION); break; - case 4: + case GzipUtils.XFL_MAX_SPEED: parameters.setCompressionLevel(Deflater.BEST_SPEED); break; default: @@ -384,7 +384,7 @@ public class GzipCompressorInputStream extends CompressorInputStream implements try { ret = inflater.inflate(b, off, len); } catch (final DataFormatException e) { // NOSONAR - throw new IOException("Gzip-compressed data is corrupt", e); + throw new IOException("Gzip-compressed data is corrupt.", e); } crc.update(b, off, ret); @@ -411,14 +411,14 @@ public class GzipCompressorInputStream extends CompressorInputStream implements final long crcStored = ByteUtils.fromLittleEndian(inData, 4); if (crcStored != crc.getValue()) { - throw new IOException("Gzip-compressed data is corrupt " + "(CRC32 error)"); + throw new IOException("Gzip-compressed data is corrupt (CRC32 error)."); } // Uncompressed size modulo 2^32 (ISIZE in the spec) final long isize = ByteUtils.fromLittleEndian(inData, 4); if (isize != (inflater.getBytesWritten() & 0xffffffffL)) { - throw new IOException("Gzip-compressed data is corrupt" + "(uncompressed size mismatch)"); + throw new IOException("Gzip-compressed data is corrupt (uncompressed size mismatch)."); } // See if this is the end of the file. diff --git a/src/main/java/org/apache/commons/compress/compressors/gzip/GzipCompressorOutputStream.java b/src/main/java/org/apache/commons/compress/compressors/gzip/GzipCompressorOutputStream.java index 3496a9965..1f501e90e 100644 --- a/src/main/java/org/apache/commons/compress/compressors/gzip/GzipCompressorOutputStream.java +++ b/src/main/java/org/apache/commons/compress/compressors/gzip/GzipCompressorOutputStream.java @@ -25,7 +25,6 @@ import java.nio.ByteOrder; import java.nio.charset.Charset; import java.util.zip.CRC32; import java.util.zip.Deflater; -import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; import org.apache.commons.compress.compressors.CompressorOutputStream; @@ -70,7 +69,7 @@ public class GzipCompressorOutputStream extends CompressorOutputStream<OutputStr this.deflater = new Deflater(parameters.getCompressionLevel(), true); this.deflater.setStrategy(parameters.getDeflateStrategy()); this.deflateBuffer = new byte[parameters.getBufferSize()]; - writeHeader(parameters); + writeMemberHeader(parameters); } @Override @@ -105,7 +104,7 @@ public class GzipCompressorOutputStream extends CompressorOutputStream<OutputStr while (!deflater.finished()) { deflate(); } - writeTrailer(); + writeMemberTrailer(); } } @@ -127,7 +126,7 @@ public class GzipCompressorOutputStream extends CompressorOutputStream<OutputStr @Override public void write(final byte[] buffer, final int offset, final int length) throws IOException { if (deflater.finished()) { - throw new IOException("Cannot write more data, the end of the compressed data stream has been reached"); + throw new IOException("Cannot write more data, the end of the compressed data stream has been reached."); } if (length > 0) { deflater.setInput(buffer, offset, length); @@ -144,7 +143,7 @@ public class GzipCompressorOutputStream extends CompressorOutputStream<OutputStr } /** - * Writes a NUL-terminated String encoded with the {@code charset}. + * Writes a C-style string, a NUL-terminated string, encoded with the {@code charset}. * * @param value The String to write. * @param charset Specifies the Charset to use. @@ -160,13 +159,14 @@ public class GzipCompressorOutputStream extends CompressorOutputStream<OutputStr } } - private void writeHeader(final GzipParameters parameters) throws IOException { + private void writeMemberHeader(final GzipParameters parameters) throws IOException { final String fileName = parameters.getFileName(); final String comment = parameters.getComment(); final byte[] extra = parameters.getExtraField() != null ? parameters.getExtraField().toByteArray() : null; final ByteBuffer buffer = ByteBuffer.allocate(10); buffer.order(ByteOrder.LITTLE_ENDIAN); - buffer.putShort((short) GZIPInputStream.GZIP_MAGIC); + buffer.put((byte) GzipUtils.ID1); + buffer.put((byte) GzipUtils.ID2); buffer.put((byte) Deflater.DEFLATED); // compression method (8: deflate) buffer.put((byte) ((extra != null ? GzipUtils.FEXTRA : 0) | (fileName != null ? GzipUtils.FNAME : 0) @@ -177,11 +177,11 @@ public class GzipCompressorOutputStream extends CompressorOutputStream<OutputStr // extra flags final int compressionLevel = parameters.getCompressionLevel(); if (compressionLevel == Deflater.BEST_COMPRESSION) { - buffer.put((byte) 2); + buffer.put(GzipUtils.XFL_MAX_COMPRESSION); } else if (compressionLevel == Deflater.BEST_SPEED) { - buffer.put((byte) 4); + buffer.put(GzipUtils.XFL_MAX_SPEED); } else { - buffer.put((byte) 0); + buffer.put(GzipUtils.XFL_UNKNOWN); } buffer.put((byte) parameters.getOperatingSystem()); out.write(buffer.array()); @@ -204,7 +204,18 @@ public class GzipCompressorOutputStream extends CompressorOutputStream<OutputStr crc.reset(); } - private void writeTrailer() throws IOException { + /** + * Writes the member trailer. + * <pre> + * 0 1 2 3 4 5 6 7 + * +---+---+---+---+---+---+---+---+ + * | CRC32 | ISIZE | + * +---+---+---+---+---+---+---+---+ + * </pre> + * + * @throws IOException if an I/O error occurs. + */ + private void writeMemberTrailer() throws IOException { final ByteBuffer buffer = ByteBuffer.allocate(8); buffer.order(ByteOrder.LITTLE_ENDIAN); buffer.putInt((int) crc.getValue()); diff --git a/src/main/java/org/apache/commons/compress/compressors/gzip/GzipUtils.java b/src/main/java/org/apache/commons/compress/compressors/gzip/GzipUtils.java index 5d8b99902..da4d5ea52 100644 --- a/src/main/java/org/apache/commons/compress/compressors/gzip/GzipUtils.java +++ b/src/main/java/org/apache/commons/compress/compressors/gzip/GzipUtils.java @@ -42,18 +42,49 @@ public class GzipUtils { /** Header flag indicating a header CRC follows the header. */ static final int FHCRC = 0x02; + private static final FileNameUtil fileNameUtil; + /** Header flag indicating a file name follows the header. */ static final int FNAME = 0x08; static final int FRESERVED = 0xE0; - private static final FileNameUtil fileNameUtil; - /** * Charset for file name and comments per the <a href="https://tools.ietf.org/html/rfc1952">GZIP File Format Specification</a>. */ static final Charset GZIP_ENCODING = StandardCharsets.ISO_8859_1; + /** + * Member header ID1 (IDentification 1). + * + * See <a href="https://datatracker.ietf.org/doc/html/rfc1952#page-5">RFC1952</a> 2.3.1. Member header and trailer. + */ + static final int ID1 = 31; + + /** + * Member header ID2 (IDentification 2). + * + * See <a href="https://datatracker.ietf.org/doc/html/rfc1952#page-5">RFC1952</a> 2.3.1. Member header and trailer. + */ + static final int ID2 = 139; + + /** + * Member header XFL (eXtra FLags) when the "deflate" method (CM = 8) is set, then XFL = 2 means the compressor used maximum compression (slowest + * algorithm). + * + * See <a href="https://datatracker.ietf.org/doc/html/rfc1952#page-5">RFC1952</a> 2.3.1. Member header and trailer. + */ + static final byte XFL_MAX_COMPRESSION = 2; + + /** + * Member header XFL (eXtra FLags) when the "deflate" method (CM = 8) is set, then XFL = 4 means the compressor used the fastest algorithm. + * + * See <a href="https://datatracker.ietf.org/doc/html/rfc1952#page-5">RFC1952</a> 2.3.1. Member header and trailer. + */ + static final byte XFL_MAX_SPEED = 4; + + static final byte XFL_UNKNOWN = 0; + static { // using LinkedHashMap so .tgz is preferred over .taz as // compressed extension of .tar as FileNameUtil will use the @@ -72,7 +103,6 @@ public class GzipUtils { uncompressSuffix.put("_z", ""); fileNameUtil = new FileNameUtil(uncompressSuffix, ".gz"); } - /** * Maps the given file name to the name that the file should have after compression with gzip. Common file types with custom suffixes for compressed * versions are automatically detected and correctly mapped. For example the name "package.tar" is mapped to "package.tgz". If no custom mapping is @@ -99,6 +129,7 @@ public class GzipUtils { public static String getCompressedFileName(final String fileName) { return fileNameUtil.getCompressedFileName(fileName); } + /** * Maps the given name of a gzip-compressed file to the name that the file should have after uncompression. Commonly used file type specific suffixes like * ".tgz" or ".svgz" are automatically detected and correctly mapped. For example the name "package.tgz" is mapped to "package.tar". And any file names with @@ -113,6 +144,7 @@ public class GzipUtils { public static String getUncompressedFilename(final String fileName) { return fileNameUtil.getUncompressedFileName(fileName); } + /** * Maps the given name of a gzip-compressed file to the name that the file should have after uncompression. Commonly used file type specific suffixes like * ".tgz" or ".svgz" are automatically detected and correctly mapped. For example the name "package.tgz" is mapped to "package.tar". And any file names with @@ -126,6 +158,7 @@ public class GzipUtils { public static String getUncompressedFileName(final String fileName) { return fileNameUtil.getUncompressedFileName(fileName); } + /** * Detects common gzip suffixes in the given file name. * @@ -137,6 +170,7 @@ public class GzipUtils { public static boolean isCompressedFilename(final String fileName) { return fileNameUtil.isCompressedFileName(fileName); } + /** * Detects common gzip suffixes in the given file name. *