You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gg...@apache.org on 2024/07/03 15:05:53 UTC
(commons-compress) 01/04: ArchiveOutputStream now extends FilterOutputStream
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
commit facbd45c65bd6a151c0f705a2dbbff55864d91cc
Author: Gary Gregory <ga...@gmail.com>
AuthorDate: Wed Jul 3 10:35:23 2024 -0400
ArchiveOutputStream now extends FilterOutputStream
---
src/changes/changes.xml | 1 +
.../compress/archivers/ArchiveOutputStream.java | 24 +++++++-
.../archivers/ar/ArArchiveOutputStream.java | 3 +-
.../archivers/cpio/CpioArchiveOutputStream.java | 4 +-
.../archivers/tar/TarArchiveOutputStream.java | 7 +--
.../archivers/zip/ZipArchiveOutputStream.java | 68 +++++++++++-----------
.../compress/archivers/cpio/CpioArchiveTest.java | 47 ++++++++++++++-
7 files changed, 109 insertions(+), 45 deletions(-)
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 412f6aa99..103217cbb 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -50,6 +50,7 @@ The <action> type attribute can be add,update,fix,remove.
<action type="fix" issue="COMPRESS-681" dev="ggregory" due-to="joker53-1, Gary Gregory">Support reading a 7z file that writing archive properties #541.</action>
<action type="fix" dev="ggregory" due-to="Mike Drob, Gary Gregory">Upgrade commons-io from 2.15.1 to 2.16.1 #513</action>
<action type="fix" dev="ggregory" due-to="Gary Gregory">CompressorOutputStream now extends FilterOutputStream.</action>
+ <action type="fix" dev="ggregory" due-to="Gary Gregory">ArchiveOutputStream now extends FilterOutputStream.</action>
<!-- ADD -->
<action type="add" dev="ggregory" due-to="Gary Gregory">Add ArchiveInputStream.forEach(IOConsumer).</action>
<action type="add" dev="ggregory" due-to="Gary Gregory">Add ArchiveInputStream.iterator().</action>
diff --git a/src/main/java/org/apache/commons/compress/archivers/ArchiveOutputStream.java b/src/main/java/org/apache/commons/compress/archivers/ArchiveOutputStream.java
index 7199ca437..038a2ea42 100644
--- a/src/main/java/org/apache/commons/compress/archivers/ArchiveOutputStream.java
+++ b/src/main/java/org/apache/commons/compress/archivers/ArchiveOutputStream.java
@@ -19,6 +19,7 @@
package org.apache.commons.compress.archivers;
import java.io.File;
+import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.LinkOption;
@@ -48,7 +49,7 @@ import java.nio.file.Path;
*
* @param <E> The type of {@link ArchiveEntry} consumed.
*/
-public abstract class ArchiveOutputStream<E extends ArchiveEntry> extends OutputStream {
+public abstract class ArchiveOutputStream<E extends ArchiveEntry> extends FilterOutputStream {
static final int BYTE_MASK = 0xFF;
@@ -58,6 +59,27 @@ public abstract class ArchiveOutputStream<E extends ArchiveEntry> extends Output
/** Holds the number of bytes written to this stream. */
private long bytesWritten;
+ /**
+ * Constructs a new instance without a backing OutputStream.
+ * <p>
+ * You must initialize {@code this.out} after construction.
+ * </p>
+ */
+ public ArchiveOutputStream() {
+ super(null);
+ }
+
+ /**
+ * Constructs a new instance with the given backing OutputStream.
+ *
+ * @param out the underlying output stream to be assigned to the field {@code this.out} for later use, or {@code null} if this instance is to be created
+ * without an underlying stream.
+ * @since 1.27.0.
+ */
+ public ArchiveOutputStream(final OutputStream out) {
+ super(out);
+ }
+
/**
* Whether this stream is able to write the given entry.
*
diff --git a/src/main/java/org/apache/commons/compress/archivers/ar/ArArchiveOutputStream.java b/src/main/java/org/apache/commons/compress/archivers/ar/ArArchiveOutputStream.java
index c3323a61f..61445a363 100644
--- a/src/main/java/org/apache/commons/compress/archivers/ar/ArArchiveOutputStream.java
+++ b/src/main/java/org/apache/commons/compress/archivers/ar/ArArchiveOutputStream.java
@@ -46,7 +46,6 @@ public class ArArchiveOutputStream extends ArchiveOutputStream<ArArchiveEntry> {
/** BSD ar extensions are used to store long file names in the archive. */
public static final int LONGFILE_BSD = 1;
- private final OutputStream out;
private long entryOffset;
private int headerPlus;
private ArArchiveEntry prevEntry;
@@ -57,7 +56,7 @@ public class ArArchiveOutputStream extends ArchiveOutputStream<ArArchiveEntry> {
private boolean finished;
public ArArchiveOutputStream(final OutputStream out) {
- this.out = out;
+ super(out);
}
/**
diff --git a/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveOutputStream.java b/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveOutputStream.java
index 1d1e000d4..bf16427ed 100644
--- a/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveOutputStream.java
+++ b/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveOutputStream.java
@@ -87,8 +87,6 @@ public class CpioArchiveOutputStream extends ArchiveOutputStream<CpioArchiveEntr
private long written;
- private final OutputStream out;
-
private final int blockSize;
private long nextArtificalDeviceAndInode = 1;
@@ -145,7 +143,7 @@ public class CpioArchiveOutputStream extends ArchiveOutputStream<CpioArchiveEntr
* @since 1.6
*/
public CpioArchiveOutputStream(final OutputStream out, final short format, final int blockSize, final String encoding) {
- this.out = out;
+ super(out);
switch (format) {
case FORMAT_NEW:
case FORMAT_NEW_CRC:
diff --git a/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveOutputStream.java b/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveOutputStream.java
index 492bdb4ea..82838af1f 100644
--- a/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveOutputStream.java
+++ b/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveOutputStream.java
@@ -122,8 +122,6 @@ public class TarArchiveOutputStream extends ArchiveOutputStream<TarArchiveEntry>
*/
private boolean finished;
- private final FixedLengthBlockOutputStream out;
-
private final CountingOutputStream countingOut;
private final ZipEncoding zipEncoding;
@@ -199,6 +197,7 @@ public class TarArchiveOutputStream extends ArchiveOutputStream<TarArchiveEntry>
* @since 1.4
*/
public TarArchiveOutputStream(final OutputStream os, final int blockSize, final String encoding) {
+ super(os);
final int realBlockSize;
if (BLOCK_SIZE_UNSPECIFIED == blockSize) {
realBlockSize = RECORD_SIZE;
@@ -209,7 +208,7 @@ public class TarArchiveOutputStream extends ArchiveOutputStream<TarArchiveEntry>
if (realBlockSize <= 0 || realBlockSize % RECORD_SIZE != 0) {
throw new IllegalArgumentException("Block size must be a multiple of 512 bytes. Attempt to use set size of " + blockSize);
}
- out = new FixedLengthBlockOutputStream(countingOut = new CountingOutputStream(os), RECORD_SIZE);
+ this.out = new FixedLengthBlockOutputStream(countingOut = new CountingOutputStream(os), RECORD_SIZE);
this.charsetName = Charsets.toCharset(encoding).name();
this.zipEncoding = ZipEncodingHelper.getZipEncoding(encoding);
@@ -326,7 +325,7 @@ public class TarArchiveOutputStream extends ArchiveOutputStream<TarArchiveEntry>
if (!haveUnclosedEntry) {
throw new IOException("No current entry to close");
}
- out.flushBlock();
+ ((FixedLengthBlockOutputStream) out).flushBlock();
if (currBytes < currSize) {
throw new IOException(
"Entry '" + currName + "' closed at '" + currBytes + "' before the '" + currSize + "' bytes specified in the header were written");
diff --git a/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java b/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java
index 488b3d8ca..bd0a5ad45 100644
--- a/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java
+++ b/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java
@@ -337,7 +337,7 @@ public class ZipArchiveOutputStream extends ArchiveOutputStream<ZipArchiveEntry>
*/
protected final Deflater def;
- private final OutputStream outputStream;
+ private final OutputStream out;
/**
* whether to use the general purpose bit flag when writing UTF-8 file names or not.
@@ -415,7 +415,7 @@ public class ZipArchiveOutputStream extends ArchiveOutputStream<ZipArchiveEntry>
* @param out the outputstream to zip
*/
public ZipArchiveOutputStream(final OutputStream out) {
- this.outputStream = out;
+ this.out = out;
this.def = new Deflater(level, true);
this.streamCompressor = StreamCompressor.create(out, def);
this.isSplitZip = false;
@@ -440,8 +440,8 @@ public class ZipArchiveOutputStream extends ArchiveOutputStream<ZipArchiveEntry>
*/
public ZipArchiveOutputStream(final Path path, final long zipSplitSize) throws IOException {
this.def = new Deflater(level, true);
- this.outputStream = new ZipSplitOutputStream(path, zipSplitSize);
- this.streamCompressor = StreamCompressor.create(this.outputStream, def);
+ this.out = new ZipSplitOutputStream(path, zipSplitSize);
+ this.streamCompressor = StreamCompressor.create(this.out, def);
this.isSplitZip = true;
}
@@ -455,8 +455,8 @@ public class ZipArchiveOutputStream extends ArchiveOutputStream<ZipArchiveEntry>
*/
public ZipArchiveOutputStream(final Path file, final OpenOption... options) throws IOException {
this.def = new Deflater(level, true);
- this.outputStream = options.length == 0 ? new FileRandomAccessOutputStream(file) : new FileRandomAccessOutputStream(file, options);
- this.streamCompressor = StreamCompressor.create(outputStream, def);
+ this.out = options.length == 0 ? new FileRandomAccessOutputStream(file) : new FileRandomAccessOutputStream(file, options);
+ this.streamCompressor = StreamCompressor.create(out, def);
this.isSplitZip = false;
}
@@ -471,9 +471,9 @@ public class ZipArchiveOutputStream extends ArchiveOutputStream<ZipArchiveEntry>
* @since 1.13
*/
public ZipArchiveOutputStream(final SeekableByteChannel channel) {
- this.outputStream = new SeekableChannelRandomAccessOutputStream(channel);
+ this.out = new SeekableChannelRandomAccessOutputStream(channel);
this.def = new Deflater(level, true);
- this.streamCompressor = StreamCompressor.create(outputStream, def);
+ this.streamCompressor = StreamCompressor.create(out, def);
this.isSplitZip = false;
}
@@ -609,7 +609,7 @@ public class ZipArchiveOutputStream extends ArchiveOutputStream<ZipArchiveEntry>
}
private void closeEntry(final boolean actuallyNeedsZip64, final boolean phased) throws IOException {
- if (!phased && outputStream instanceof RandomAccessOutputStream) {
+ if (!phased && out instanceof RandomAccessOutputStream) {
rewriteSizesAndCrc(actuallyNeedsZip64);
}
@@ -707,7 +707,7 @@ public class ZipArchiveOutputStream extends ArchiveOutputStream<ZipArchiveEntry>
if (isSplitZip) {
// calculate the disk number for every central file header,
// this will be used in writing End Of Central Directory and Zip64 End Of Central Directory
- final int currentSplitSegment = ((ZipSplitOutputStream) this.outputStream).getCurrentSplitSegmentIndex();
+ final int currentSplitSegment = ((ZipSplitOutputStream) this.out).getCurrentSplitSegmentIndex();
if (numberOfCDInDiskData.get(currentSplitSegment) == null) {
numberOfCDInDiskData.put(currentSplitSegment, 1);
} else {
@@ -849,7 +849,7 @@ public class ZipArchiveOutputStream extends ArchiveOutputStream<ZipArchiveEntry>
ZipUtil.toDosTime(ze.getTime(), buf, LFH_TIME_OFFSET);
// CRC
- if (phased || !(zipMethod == DEFLATED || outputStream instanceof RandomAccessOutputStream)) {
+ if (phased || !(zipMethod == DEFLATED || out instanceof RandomAccessOutputStream)) {
ZipLong.putLong(ze.getCrc(), buf, LFH_CRC_OFFSET);
} else {
System.arraycopy(LZERO, 0, buf, LFH_CRC_OFFSET, ZipConstants.WORD);
@@ -866,7 +866,7 @@ public class ZipArchiveOutputStream extends ArchiveOutputStream<ZipArchiveEntry>
} else if (phased) {
ZipLong.putLong(ze.getCompressedSize(), buf, LFH_COMPRESSED_SIZE_OFFSET);
ZipLong.putLong(ze.getSize(), buf, LFH_ORIGINAL_SIZE_OFFSET);
- } else if (zipMethod == DEFLATED || outputStream instanceof RandomAccessOutputStream) {
+ } else if (zipMethod == DEFLATED || out instanceof RandomAccessOutputStream) {
System.arraycopy(LZERO, 0, buf, LFH_COMPRESSED_SIZE_OFFSET, ZipConstants.WORD);
System.arraycopy(LZERO, 0, buf, LFH_ORIGINAL_SIZE_OFFSET, ZipConstants.WORD);
} else { // Stored
@@ -904,8 +904,8 @@ public class ZipArchiveOutputStream extends ArchiveOutputStream<ZipArchiveEntry>
* </p>
*/
void destroy() throws IOException {
- if (outputStream != null) {
- outputStream.close();
+ if (out != null) {
+ out.close();
}
}
@@ -930,7 +930,7 @@ public class ZipArchiveOutputStream extends ArchiveOutputStream<ZipArchiveEntry>
if (isSplitZip) {
// when creating a split zip, the offset should be
// the offset to the corresponding segment disk
- final ZipSplitOutputStream zipSplitOutputStream = (ZipSplitOutputStream) this.outputStream;
+ final ZipSplitOutputStream zipSplitOutputStream = (ZipSplitOutputStream) this.out;
cdOffset = zipSplitOutputStream.getCurrentSplitSegmentBytesWritten();
cdDiskNumberStart = zipSplitOutputStream.getCurrentSplitSegmentIndex();
}
@@ -958,7 +958,7 @@ public class ZipArchiveOutputStream extends ArchiveOutputStream<ZipArchiveEntry>
streamCompressor.close();
if (isSplitZip) {
// trigger the ZipSplitOutputStream to write the final split segment
- outputStream.close();
+ out.close();
}
finished = true;
}
@@ -970,8 +970,8 @@ public class ZipArchiveOutputStream extends ArchiveOutputStream<ZipArchiveEntry>
*/
@Override
public void flush() throws IOException {
- if (outputStream != null) {
- outputStream.flush();
+ if (out != null) {
+ out.flush();
}
}
@@ -1001,7 +1001,7 @@ public class ZipArchiveOutputStream extends ArchiveOutputStream<ZipArchiveEntry>
* @since 1.3
*/
private Zip64Mode getEffectiveZip64Mode(final ZipArchiveEntry ze) {
- if (zip64Mode != Zip64Mode.AsNeeded || outputStream instanceof RandomAccessOutputStream ||
+ if (zip64Mode != Zip64Mode.AsNeeded || out instanceof RandomAccessOutputStream ||
ze.getMethod() != DEFLATED || ze.getSize() != ArchiveEntry.SIZE_UNKNOWN) {
return zip64Mode;
}
@@ -1074,7 +1074,7 @@ public class ZipArchiveOutputStream extends ArchiveOutputStream<ZipArchiveEntry>
entry.entry.setCompressedSize(bytesWritten);
entry.entry.setCrc(crc);
- } else if (!(outputStream instanceof RandomAccessOutputStream)) {
+ } else if (!(out instanceof RandomAccessOutputStream)) {
if (entry.entry.getCrc() != crc) {
throw new ZipException("Bad CRC checksum for entry " + entry.entry.getName() + ": " + Long.toHexString(entry.entry.getCrc()) + " instead of "
+ Long.toHexString(crc));
@@ -1140,7 +1140,7 @@ public class ZipArchiveOutputStream extends ArchiveOutputStream<ZipArchiveEntry>
* @return true if seekable
*/
public boolean isSeekable() {
- return outputStream instanceof RandomAccessOutputStream;
+ return out instanceof RandomAccessOutputStream;
}
private boolean isTooLargeForZip32(final ZipArchiveEntry zipArchiveEntry) {
@@ -1239,7 +1239,7 @@ public class ZipArchiveOutputStream extends ArchiveOutputStream<ZipArchiveEntry>
* sizes.
*/
private void rewriteSizesAndCrc(final boolean actuallyNeedsZip64) throws IOException {
- final RandomAccessOutputStream randomStream = (RandomAccessOutputStream) outputStream;
+ final RandomAccessOutputStream randomStream = (RandomAccessOutputStream) out;
long dataStart = entry.localDataStart;
if (randomStream instanceof ZipSplitOutputStream) {
dataStart = ((ZipSplitOutputStream) randomStream).calculateDiskPosition(entry.entry.getDiskNumberStart(), dataStart);
@@ -1446,7 +1446,7 @@ public class ZipArchiveOutputStream extends ArchiveOutputStream<ZipArchiveEntry>
private boolean shouldAddZip64Extra(final ZipArchiveEntry entry, final Zip64Mode mode) {
return mode == Zip64Mode.Always || mode == Zip64Mode.AlwaysWithCompatibility || entry.getSize() >= ZipConstants.ZIP64_MAGIC
|| entry.getCompressedSize() >= ZipConstants.ZIP64_MAGIC
- || entry.getSize() == ArchiveEntry.SIZE_UNKNOWN && outputStream instanceof RandomAccessOutputStream && mode != Zip64Mode.Never;
+ || entry.getSize() == ArchiveEntry.SIZE_UNKNOWN && out instanceof RandomAccessOutputStream && mode != Zip64Mode.Never;
}
/**
@@ -1458,7 +1458,7 @@ public class ZipArchiveOutputStream extends ArchiveOutputStream<ZipArchiveEntry>
private boolean shouldUseZip64EOCD() {
int numberOfThisDisk = 0;
if (isSplitZip) {
- numberOfThisDisk = ((ZipSplitOutputStream) this.outputStream).getCurrentSplitSegmentIndex();
+ numberOfThisDisk = ((ZipSplitOutputStream) this.out).getCurrentSplitSegmentIndex();
}
final int numOfEntriesOnThisDisk = numberOfCDInDiskData.getOrDefault(numberOfThisDisk, 0);
return numberOfThisDisk >= ZipConstants.ZIP64_MAGIC_SHORT /* number of this disk */
@@ -1472,7 +1472,7 @@ public class ZipArchiveOutputStream extends ArchiveOutputStream<ZipArchiveEntry>
}
private boolean usesDataDescriptor(final int zipMethod, final boolean phased) {
- return !phased && zipMethod == DEFLATED && !(outputStream instanceof RandomAccessOutputStream);
+ return !phased && zipMethod == DEFLATED && !(out instanceof RandomAccessOutputStream);
}
/**
@@ -1488,7 +1488,7 @@ public class ZipArchiveOutputStream extends ArchiveOutputStream<ZipArchiveEntry>
int numberOfThisDisk = 0;
if (isSplitZip) {
- numberOfThisDisk = ((ZipSplitOutputStream) this.outputStream).getCurrentSplitSegmentIndex();
+ numberOfThisDisk = ((ZipSplitOutputStream) this.out).getCurrentSplitSegmentIndex();
}
if (numberOfThisDisk >= ZipConstants.ZIP64_MAGIC_SHORT) {
throw new Zip64RequiredException(Zip64RequiredException.DISK_NUMBER_TOO_BIG_MESSAGE);
@@ -1523,7 +1523,7 @@ public class ZipArchiveOutputStream extends ArchiveOutputStream<ZipArchiveEntry>
*/
private void validateSizeInformation(final Zip64Mode effectiveMode) throws ZipException {
// Size/CRC not required if SeekableByteChannel is used
- if (entry.entry.getMethod() == STORED && !(outputStream instanceof RandomAccessOutputStream)) {
+ if (entry.entry.getMethod() == STORED && !(out instanceof RandomAccessOutputStream)) {
if (entry.entry.getSize() == ArchiveEntry.SIZE_UNKNOWN) {
throw new ZipException("Uncompressed size is required for" + " STORED method when not writing to a" + " file");
}
@@ -1580,7 +1580,7 @@ public class ZipArchiveOutputStream extends ArchiveOutputStream<ZipArchiveEntry>
*/
protected void writeCentralDirectoryEnd() throws IOException {
if (!hasUsedZip64 && isSplitZip) {
- ((ZipSplitOutputStream) this.outputStream).prepareToWriteUnsplittableContent(eocdLength);
+ ((ZipSplitOutputStream) this.out).prepareToWriteUnsplittableContent(eocdLength);
}
validateIfZip64IsNeededInEOCD();
@@ -1590,7 +1590,7 @@ public class ZipArchiveOutputStream extends ArchiveOutputStream<ZipArchiveEntry>
// number of this disk
int numberOfThisDisk = 0;
if (isSplitZip) {
- numberOfThisDisk = ((ZipSplitOutputStream) this.outputStream).getCurrentSplitSegmentIndex();
+ numberOfThisDisk = ((ZipSplitOutputStream) this.out).getCurrentSplitSegmentIndex();
}
writeCounted(ZipShort.getBytes(numberOfThisDisk));
@@ -1700,7 +1700,7 @@ public class ZipArchiveOutputStream extends ArchiveOutputStream<ZipArchiveEntry>
if (isSplitZip) {
// when creating a split zip, the offset should be
// the offset to the corresponding segment disk
- final ZipSplitOutputStream splitOutputStream = (ZipSplitOutputStream) this.outputStream;
+ final ZipSplitOutputStream splitOutputStream = (ZipSplitOutputStream) this.out;
ze.setDiskNumberStart(splitOutputStream.getCurrentSplitSegmentIndex());
localHeaderStart = splitOutputStream.getCurrentSplitSegmentBytesWritten();
}
@@ -1786,7 +1786,7 @@ public class ZipArchiveOutputStream extends ArchiveOutputStream<ZipArchiveEntry>
if (isSplitZip) {
// when creating a split zip, the offset of should be
// the offset to the corresponding segment disk
- final ZipSplitOutputStream zipSplitOutputStream = (ZipSplitOutputStream) this.outputStream;
+ final ZipSplitOutputStream zipSplitOutputStream = (ZipSplitOutputStream) this.out;
offset = zipSplitOutputStream.getCurrentSplitSegmentBytesWritten();
diskNumberStart = zipSplitOutputStream.getCurrentSplitSegmentIndex();
}
@@ -1811,7 +1811,7 @@ public class ZipArchiveOutputStream extends ArchiveOutputStream<ZipArchiveEntry>
// number of this disk
int numberOfThisDisk = 0;
if (isSplitZip) {
- numberOfThisDisk = ((ZipSplitOutputStream) this.outputStream).getCurrentSplitSegmentIndex();
+ numberOfThisDisk = ((ZipSplitOutputStream) this.out).getCurrentSplitSegmentIndex();
}
writeOut(ZipLong.getBytes(numberOfThisDisk));
@@ -1842,7 +1842,7 @@ public class ZipArchiveOutputStream extends ArchiveOutputStream<ZipArchiveEntry>
+ ZipConstants.WORD /* total number of disks */;
final long unsplittableContentSize = zip64EOCDLOCLength + eocdLength;
- ((ZipSplitOutputStream) this.outputStream).prepareToWriteUnsplittableContent(unsplittableContentSize);
+ ((ZipSplitOutputStream) this.out).prepareToWriteUnsplittableContent(unsplittableContentSize);
}
// and now the "ZIP64 end of central directory locator"
@@ -1856,7 +1856,7 @@ public class ZipArchiveOutputStream extends ArchiveOutputStream<ZipArchiveEntry>
if (isSplitZip) {
// the Zip64 End Of Central Directory Locator and the End Of Central Directory must be
// in the same split disk, it means they must be located in the last disk
- final int totalNumberOfDisks = ((ZipSplitOutputStream) this.outputStream).getCurrentSplitSegmentIndex() + 1;
+ final int totalNumberOfDisks = ((ZipSplitOutputStream) this.out).getCurrentSplitSegmentIndex() + 1;
writeOut(ZipLong.getBytes(totalNumberOfDisks));
} else {
writeOut(ONE);
diff --git a/src/test/java/org/apache/commons/compress/archivers/cpio/CpioArchiveTest.java b/src/test/java/org/apache/commons/compress/archivers/cpio/CpioArchiveTest.java
index e02b1c9ef..1818f68f2 100644
--- a/src/test/java/org/apache/commons/compress/archivers/cpio/CpioArchiveTest.java
+++ b/src/test/java/org/apache/commons/compress/archivers/cpio/CpioArchiveTest.java
@@ -28,6 +28,7 @@ import java.nio.charset.StandardCharsets;
import java.util.stream.Stream;
import org.apache.commons.io.IOUtils;
+import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
@@ -39,9 +40,53 @@ public class CpioArchiveTest {
Arguments.of(CpioConstants.FORMAT_OLD_BINARY));
}
+ @Test
+ public void utf18RoundtripTestCtor2() throws Exception {
+ try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
+ try (CpioArchiveOutputStream os = new CpioArchiveOutputStream(baos, StandardCharsets.UTF_8.name())) {
+ final CpioArchiveEntry entry = new CpioArchiveEntry("Test.txt", 4);
+ os.putArchiveEntry(entry);
+ os.write(new byte[] { 1, 2, 3, 4 });
+ os.closeArchiveEntry();
+ }
+ baos.close();
+ try (ByteArrayInputStream bin = new ByteArrayInputStream(baos.toByteArray());
+ CpioArchiveInputStream in = new CpioArchiveInputStream(bin, StandardCharsets.UTF_8.name())) {
+ final CpioArchiveEntry entry = in.getNextEntry();
+ assertNotNull(entry);
+ assertEquals("Test.txt", entry.getName());
+ assertArrayEquals(new byte[] { 1, 2, 3, 4 }, IOUtils.toByteArray(in));
+ }
+ }
+ }
+
+ @ParameterizedTest
+ @MethodSource("factory")
+ public void utf18RoundtripTestCtor3(final short format) throws Exception {
+ try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
+ try (CpioArchiveOutputStream os = new CpioArchiveOutputStream(baos, format, CpioConstants.BLOCK_SIZE)) {
+ final CpioArchiveEntry entry = new CpioArchiveEntry(format, "T\u00e4st.txt", 4);
+ if (format == CpioConstants.FORMAT_NEW_CRC) {
+ entry.setChksum(10);
+ }
+ os.putArchiveEntry(entry);
+ os.write(new byte[] { 1, 2, 3, 4 });
+ os.closeArchiveEntry();
+ }
+ baos.close();
+ try (ByteArrayInputStream bin = new ByteArrayInputStream(baos.toByteArray());
+ CpioArchiveInputStream in = new CpioArchiveInputStream(bin)) {
+ final CpioArchiveEntry entry = in.getNextEntry();
+ assertNotNull(entry);
+ assertEquals("T%U00E4st.txt", entry.getName());
+ assertArrayEquals(new byte[] { 1, 2, 3, 4 }, IOUtils.toByteArray(in));
+ }
+ }
+ }
+
@ParameterizedTest
@MethodSource("factory")
- public void utf18RoundtripTest(final short format) throws Exception {
+ public void utf18RoundtripTestCtor4(final short format) throws Exception {
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
try (CpioArchiveOutputStream os = new CpioArchiveOutputStream(baos, format, CpioConstants.BLOCK_SIZE, StandardCharsets.UTF_16LE.name())) {
final CpioArchiveEntry entry = new CpioArchiveEntry(format, "T\u00e4st.txt", 4);