COMPRESS-306 ArchiveStreamFactory fails to pass on the encoding when creating some streams.
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/compress/trunk@1660245 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 428e0c7..0e6db4c 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -54,6 +54,15 @@
This also changes the superclass of ZCompressorInputStream.
">
+ <action issue="COMPRESS-306" type="fix">
+ ArchiveStreamFactory fails to pass on the encoding when creating some streams.
+ * ArjArchiveInputStream
+ * CpioArchiveInputStream
+ * DumpArchiveInputStream
+ * JarArchiveInputStream
+ * TarArchiveInputStream
+ * JarArchiveOutputStream
+ </action>
<action issue="COMPRESS-302" type="fix">
Restore immutability/thread-safety to ArchiveStreamFactory.
The class is now immutable provided that the method setEntryEncoding is not used.
diff --git a/src/main/java/org/apache/commons/compress/archivers/ArchiveStreamFactory.java b/src/main/java/org/apache/commons/compress/archivers/ArchiveStreamFactory.java
index 4aefb29..c73e665 100644
--- a/src/main/java/org/apache/commons/compress/archivers/ArchiveStreamFactory.java
+++ b/src/main/java/org/apache/commons/compress/archivers/ArchiveStreamFactory.java
@@ -150,10 +150,10 @@
}
/**
- * Returns the encoding to use for arj, zip, dump, cpio and tar
- * files, or null for the default.
+ * Returns the encoding to use for arj, jar, zip, dump, cpio and tar
+ * files, or null for the archiver default.
*
- * @return entry encoding, or null
+ * @return entry encoding, or null for the archiver default
* @since 1.5
*/
public String getEntryEncoding() {
@@ -161,9 +161,9 @@
}
/**
- * Sets the encoding to use for arj, zip, dump, cpio and tar files. Use null for the default.
+ * Sets the encoding to use for arj, jar, zip, dump, cpio and tar files. Use null for the archiver default.
*
- * @param entryEncoding the entry encoding, null uses the default.
+ * @param entryEncoding the entry encoding, null uses the archiver default.
* @since 1.5
* @deprecated 1.10 use {@link #ArchiveStreamFactory(String)} to specify the encoding
* @throws IllegalStateException if the constructor {@link #ArchiveStreamFactory(String)}
@@ -227,7 +227,11 @@
}
}
if (JAR.equalsIgnoreCase(archiverName)) {
- return new JarArchiveInputStream(in);
+ if (entryEncoding != null) {
+ return new JarArchiveInputStream(in, entryEncoding);
+ } else {
+ return new JarArchiveInputStream(in);
+ }
}
if (CPIO.equalsIgnoreCase(archiverName)) {
if (entryEncoding != null) {
@@ -254,7 +258,7 @@
* Create an archive output stream from an archiver name and an output stream.
*
* @param archiverName the archive name,
- * i.e. {@value #AR}, {@value #ZIP}, {@value #TAR}, {@value #JAR}, {@value #CPIO} or {@value #SEVEN_Z}
+ * i.e. {@value #AR}, {@value #ZIP}, {@value #TAR}, {@value #JAR} or {@value #CPIO}
* @param out the output stream
* @return the archive output stream
* @throws ArchiveException if the archiver name is not known
@@ -290,7 +294,11 @@
}
}
if (JAR.equalsIgnoreCase(archiverName)) {
- return new JarArchiveOutputStream(out);
+ if (entryEncoding != null) {
+ return new JarArchiveOutputStream(out, entryEncoding);
+ } else {
+ return new JarArchiveOutputStream(out);
+ }
}
if (CPIO.equalsIgnoreCase(archiverName)) {
if (entryEncoding != null) {
@@ -339,13 +347,25 @@
return new ZipArchiveInputStream(in);
}
} else if (JarArchiveInputStream.matches(signature, signatureLength)) {
- return new JarArchiveInputStream(in);
+ if (entryEncoding != null) {
+ return new JarArchiveInputStream(in, entryEncoding);
+ } else {
+ return new JarArchiveInputStream(in);
+ }
} else if (ArArchiveInputStream.matches(signature, signatureLength)) {
return new ArArchiveInputStream(in);
} else if (CpioArchiveInputStream.matches(signature, signatureLength)) {
- return new CpioArchiveInputStream(in);
+ if (entryEncoding != null) {
+ return new CpioArchiveInputStream(in, entryEncoding);
+ } else {
+ return new CpioArchiveInputStream(in);
+ }
} else if (ArjArchiveInputStream.matches(signature, signatureLength)) {
- return new ArjArchiveInputStream(in);
+ if (entryEncoding != null) {
+ return new ArjArchiveInputStream(in, entryEncoding);
+ } else {
+ return new ArjArchiveInputStream(in);
+ }
} else if (SevenZFile.matches(signature, signatureLength)) {
throw new StreamingNotSupportedException(SEVEN_Z);
}
@@ -356,7 +376,7 @@
signatureLength = IOUtils.readFully(in, dumpsig);
in.reset();
if (DumpArchiveInputStream.matches(dumpsig, signatureLength)) {
- return new DumpArchiveInputStream(in);
+ return new DumpArchiveInputStream(in, entryEncoding);
}
// Tar needs an even bigger buffer to check the signature; read the first block
@@ -365,11 +385,7 @@
signatureLength = IOUtils.readFully(in, tarheader);
in.reset();
if (TarArchiveInputStream.matches(tarheader, signatureLength)) {
- if (entryEncoding != null) {
- return new TarArchiveInputStream(in, entryEncoding);
- } else {
- return new TarArchiveInputStream(in);
- }
+ return new TarArchiveInputStream(in, entryEncoding);
}
// COMPRESS-117 - improve auto-recognition
if (signatureLength >= 512) {
@@ -378,7 +394,7 @@
tais = new TarArchiveInputStream(new ByteArrayInputStream(tarheader));
// COMPRESS-191 - verify the header checksum
if (tais.getNextTarEntry().isCheckSumOK()) {
- return new TarArchiveInputStream(in);
+ return new TarArchiveInputStream(in, encoding);
}
} catch (Exception e) { // NOPMD
// can generate IllegalArgumentException as well
diff --git a/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveInputStream.java b/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveInputStream.java
index 0d7e4ba..915b56e 100644
--- a/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveInputStream.java
+++ b/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveInputStream.java
@@ -91,7 +91,10 @@
/**
* The encoding to use for filenames and labels.
*/
- private final ZipEncoding encoding;
+ private final ZipEncoding zipEncoding;
+
+ // the provided encoding (for unit tests)
+ final String encoding;
/**
* Construct the cpio input stream with a blocksize of {@link
@@ -150,7 +153,8 @@
public CpioArchiveInputStream(final InputStream in, int blockSize, String encoding) {
this.in = in;
this.blockSize = blockSize;
- this.encoding = ZipEncodingHelper.getZipEncoding(encoding);
+ this.encoding = encoding;
+ this.zipEncoding = ZipEncodingHelper.getZipEncoding(encoding);
}
/**
@@ -444,7 +448,7 @@
byte tmpBuffer[] = new byte[length - 1];
readFully(tmpBuffer, 0, tmpBuffer.length);
this.in.read();
- return encoding.decode(tmpBuffer);
+ return zipEncoding.decode(tmpBuffer);
}
/**
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 ff86ddf..fc829ff 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
@@ -92,7 +92,10 @@
/**
* The encoding to use for filenames and labels.
*/
- private final ZipEncoding encoding;
+ private final ZipEncoding zipEncoding;
+
+ // the provided encoding (for unit tests)
+ final String encoding;
/**
* Construct the cpio output stream with a specified format, a
@@ -157,7 +160,8 @@
}
this.entryFormat = format;
this.blockSize = blockSize;
- this.encoding = ZipEncodingHelper.getZipEncoding(encoding);
+ this.encoding = encoding;
+ this.zipEncoding = ZipEncodingHelper.getZipEncoding(encoding);
}
/**
@@ -534,7 +538,7 @@
* @throws IOException if the string couldn't be written
*/
private void writeCString(final String str) throws IOException {
- ByteBuffer buf = encoding.encode(str);
+ ByteBuffer buf = zipEncoding.encode(str);
final int len = buf.limit() - buf.position();
out.write(buf.array(), buf.arrayOffset(), len);
out.write('\0');
diff --git a/src/main/java/org/apache/commons/compress/archivers/dump/DumpArchiveInputStream.java b/src/main/java/org/apache/commons/compress/archivers/dump/DumpArchiveInputStream.java
index 6381e89..09431a4 100644
--- a/src/main/java/org/apache/commons/compress/archivers/dump/DumpArchiveInputStream.java
+++ b/src/main/java/org/apache/commons/compress/archivers/dump/DumpArchiveInputStream.java
@@ -74,7 +74,10 @@
/**
* The encoding to use for filenames and labels.
*/
- private final ZipEncoding encoding;
+ private final ZipEncoding zipEncoding;
+
+ // the provided encoding (for unit tests)
+ final String encoding;
/**
* Constructor using the platform's default encoding for file
@@ -99,7 +102,8 @@
throws ArchiveException {
this.raw = new TapeInputStream(is);
this.hasHitEOF = false;
- this.encoding = ZipEncodingHelper.getZipEncoding(encoding);
+ this.encoding = encoding;
+ this.zipEncoding = ZipEncodingHelper.getZipEncoding(encoding);
try {
// read header, verify it's a dump archive.
@@ -110,7 +114,7 @@
}
// get summary information
- summary = new DumpArchiveSummary(headerBytes, this.encoding);
+ summary = new DumpArchiveSummary(headerBytes, this.zipEncoding);
// reset buffer with actual block size.
raw.resetBlockSize(summary.getNTRec(), summary.isCompressed());
@@ -351,7 +355,7 @@
byte type = blockBuffer[i + 6];
- String name = DumpArchiveUtil.decode(encoding, blockBuffer, i + 8, blockBuffer[i + 7]);
+ String name = DumpArchiveUtil.decode(zipEncoding, blockBuffer, i + 8, blockBuffer[i + 7]);
if (".".equals(name) || "..".equals(name)) {
// do nothing...
diff --git a/src/main/java/org/apache/commons/compress/archivers/jar/JarArchiveInputStream.java b/src/main/java/org/apache/commons/compress/archivers/jar/JarArchiveInputStream.java
index d051a4b..1ebac2f 100644
--- a/src/main/java/org/apache/commons/compress/archivers/jar/JarArchiveInputStream.java
+++ b/src/main/java/org/apache/commons/compress/archivers/jar/JarArchiveInputStream.java
@@ -32,10 +32,26 @@
*/
public class JarArchiveInputStream extends ZipArchiveInputStream {
+ /**
+ * Creates an instance from the input stream using the default encoding.
+ *
+ * @param inputStream the input stream to wrap
+ */
public JarArchiveInputStream( final InputStream inputStream ) {
super(inputStream);
}
+ /**
+ * Creates an instance from the input stream using the specified encoding.
+ *
+ * @param inputStream the input stream to wrap
+ * @param encoding the encoding to use
+ * @since 1.10
+ */
+ public JarArchiveInputStream( final InputStream inputStream, final String encoding ) {
+ super(inputStream, encoding);
+ }
+
public JarArchiveEntry getNextJarEntry() throws IOException {
ZipArchiveEntry entry = getNextZipEntry();
return entry == null ? null : new JarArchiveEntry(entry);
diff --git a/src/main/java/org/apache/commons/compress/archivers/jar/JarArchiveOutputStream.java b/src/main/java/org/apache/commons/compress/archivers/jar/JarArchiveOutputStream.java
index f372ad7..96d0fbf 100644
--- a/src/main/java/org/apache/commons/compress/archivers/jar/JarArchiveOutputStream.java
+++ b/src/main/java/org/apache/commons/compress/archivers/jar/JarArchiveOutputStream.java
@@ -41,6 +41,18 @@
super(out);
}
+ /**
+ * Create and instance that wraps the output stream using the provided encoding.
+ *
+ * @param out the output stream to wrap
+ * @param encoding the encoding to use. Use null for the platform default.
+ * @since 1.10
+ */
+ public JarArchiveOutputStream(final OutputStream out, final String encoding) {
+ super(out);
+ setEncoding(encoding);
+ }
+
// @throws ClassCastException if entry is not an instance of ZipArchiveEntry
@Override
public void putArchiveEntry(ArchiveEntry ze) throws IOException {
diff --git a/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveInputStream.java b/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveInputStream.java
index 545d15c..c557007 100644
--- a/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveInputStream.java
+++ b/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveInputStream.java
@@ -73,7 +73,10 @@
private TarArchiveEntry currEntry;
/** The encoding of the file */
- private final ZipEncoding encoding;
+ private final ZipEncoding zipEncoding;
+
+ // the provided encoding (for unit tests)
+ final String encoding;
/**
* Constructor for TarInputStream.
@@ -137,7 +140,8 @@
String encoding) {
this.is = is;
this.hasHitEOF = false;
- this.encoding = ZipEncodingHelper.getZipEncoding(encoding);
+ this.encoding = encoding;
+ this.zipEncoding = ZipEncodingHelper.getZipEncoding(encoding);
this.recordSize = recordSize;
this.blockSize = blockSize;
}
@@ -271,7 +275,7 @@
}
try {
- currEntry = new TarArchiveEntry(headerBuf, encoding);
+ currEntry = new TarArchiveEntry(headerBuf, zipEncoding);
} catch (IllegalArgumentException e) {
IOException ioe = new IOException("Error detected parsing the header");
ioe.initCause(e);
@@ -289,7 +293,7 @@
// entry
return null;
}
- currEntry.setLinkName(encoding.decode(longLinkData));
+ currEntry.setLinkName(zipEncoding.decode(longLinkData));
}
if (currEntry.isGNULongNameEntry()) {
@@ -300,7 +304,7 @@
// entry
return null;
}
- currEntry.setName(encoding.decode(longNameData));
+ currEntry.setName(zipEncoding.decode(longNameData));
}
if (currEntry.isPaxHeader()){ // Process Pax headers
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 1b134af..43525c8 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
@@ -84,7 +84,10 @@
private final OutputStream out;
- private final ZipEncoding encoding;
+ private final ZipEncoding zipEncoding;
+
+ // the provided encoding (for unit tests)
+ final String encoding;
private boolean addPaxHeadersForNonAsciiNames = false;
private static final ZipEncoding ASCII =
@@ -150,7 +153,8 @@
public TarArchiveOutputStream(OutputStream os, int blockSize,
int recordSize, String encoding) {
out = new CountingOutputStream(os);
- this.encoding = ZipEncodingHelper.getZipEncoding(encoding);
+ this.encoding = encoding;
+ this.zipEncoding = ZipEncodingHelper.getZipEncoding(encoding);
this.assemLen = 0;
this.assemBuf = new byte[recordSize];
@@ -301,7 +305,7 @@
writePaxHeaders(entry, entryName, paxHeaders);
}
- entry.writeEntryHeader(recordBuf, encoding,
+ entry.writeEntryHeader(recordBuf, zipEncoding,
bigNumberMode == BIGNUMBER_STAR);
writeRecord(recordBuf);
@@ -660,7 +664,7 @@
Map<String, String> paxHeaders,
String paxHeaderName, byte linkType, String fieldName)
throws IOException {
- final ByteBuffer encodedName = encoding.encode(name);
+ final ByteBuffer encodedName = zipEncoding.encode(name);
final int len = encodedName.limit() - encodedName.position();
if (len >= TarConstants.NAMELEN) {
diff --git a/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStream.java b/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStream.java
index 226d29e..7a69141 100644
--- a/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStream.java
+++ b/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStream.java
@@ -61,6 +61,9 @@
/** The zip encoding to use for filenames and the file comment. */
private final ZipEncoding zipEncoding;
+ // the provided encoding (for unit tests)
+ final String encoding;
+
/** Whether to look for and use Unicode extra fields. */
private final boolean useUnicodeExtraFields;
@@ -139,6 +142,10 @@
private int entriesRead = 0;
+ /**
+ * Create an instance using UTF-8 encoding
+ * @param inputStream the stream to wrap
+ */
public ZipArchiveInputStream(InputStream inputStream) {
this(inputStream, ZipEncodingHelper.UTF8);
}
@@ -175,6 +182,7 @@
String encoding,
boolean useUnicodeExtraFields,
boolean allowStoredEntriesWithDataDescriptor) {
+ this.encoding = encoding;
zipEncoding = ZipEncodingHelper.getZipEncoding(encoding);
this.useUnicodeExtraFields = useUnicodeExtraFields;
in = new PushbackInputStream(inputStream, buf.capacity());
diff --git a/src/test/java/org/apache/commons/compress/archivers/ArchiveStreamFactoryTest.java b/src/test/java/org/apache/commons/compress/archivers/ArchiveStreamFactoryTest.java
index d7b47b1..0352fed 100644
--- a/src/test/java/org/apache/commons/compress/archivers/ArchiveStreamFactoryTest.java
+++ b/src/test/java/org/apache/commons/compress/archivers/ArchiveStreamFactoryTest.java
@@ -18,7 +18,9 @@
*/
package org.apache.commons.compress.archivers;
+import static org.apache.commons.compress.AbstractTestCase.getFile;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -26,8 +28,15 @@
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
+import java.io.IOException;
import java.io.InputStream;
+import java.lang.reflect.Field;
+import org.apache.commons.compress.archivers.arj.ArjArchiveInputStream;
+import org.apache.commons.compress.archivers.cpio.CpioArchiveInputStream;
+import org.apache.commons.compress.archivers.dump.DumpArchiveInputStream;
+import org.apache.commons.compress.archivers.jar.JarArchiveInputStream;
+import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
import org.junit.Test;
@@ -147,4 +156,249 @@
fis.close();
}
}
+
+ @Test
+ public void testEncodingCtor() {
+ ArchiveStreamFactory fac = new ArchiveStreamFactory();
+ assertNull(fac.getEntryEncoding());
+ fac = new ArchiveStreamFactory(null);
+ assertNull(fac.getEntryEncoding());
+ fac = new ArchiveStreamFactory("UTF-8");
+ assertEquals("UTF-8", fac.getEntryEncoding());
+ }
+
+ @Test
+ @SuppressWarnings("deprecation")
+ public void testEncodingDeprecated() {
+ ArchiveStreamFactory fac = new ArchiveStreamFactory();
+ assertNull(fac.getEntryEncoding());
+ fac.setEntryEncoding("UTF-8");
+ assertEquals("UTF-8", fac.getEntryEncoding());
+ fac.setEntryEncoding("US_ASCII");
+ assertEquals("US_ASCII", fac.getEntryEncoding());
+ fac = new ArchiveStreamFactory("UTF-8");
+ assertEquals("UTF-8", fac.getEntryEncoding());
+ try {
+ fac.setEntryEncoding("US_ASCII");
+ fail("Expected IllegalStateException");
+ } catch (IllegalStateException ise) {
+ // expected
+ }
+ }
+
+ static class TestData {
+ final String testFile;
+ final String expectedEncoding;
+ final ArchiveStreamFactory fac;
+ final String fieldName;
+ final String type;
+ final boolean hasOutputStream;
+ TestData(String testFile, String type, boolean hasOut, String expectedEncoding, ArchiveStreamFactory fac, String fieldName) {
+ this.testFile = testFile;
+ this.expectedEncoding = expectedEncoding;
+ this.fac = fac;
+ this.fieldName = fieldName;
+ this.type = type;
+ this.hasOutputStream = hasOut;
+ }
+ }
+
+ @SuppressWarnings("deprecation") // test of deprecated method
+ static ArchiveStreamFactory getFactory(String entryEncoding) {
+ ArchiveStreamFactory fac = new ArchiveStreamFactory();
+ fac.setEntryEncoding(entryEncoding);
+ return fac;
+ }
+ // The different factory types
+ private static final ArchiveStreamFactory FACTORY = new ArchiveStreamFactory();
+ private static final ArchiveStreamFactory FACTORY_UTF8 = new ArchiveStreamFactory("UTF-8");
+ private static final ArchiveStreamFactory FACTORY_ASCII = new ArchiveStreamFactory("ASCII");
+ private static final ArchiveStreamFactory FACTORY_SET_UTF8 = getFactory("UTF-8");
+ private static final ArchiveStreamFactory FACTORY_SET_ASCII = getFactory("ASCII");
+
+ // Default encoding if none is provided (not even null)
+ // The test currently assumes that the output default is the same as the input default
+ private static final String ARJ_DEFAULT;
+ private static final String DUMP_DEFAULT;
+
+ private static final String ZIP_DEFAULT = getField(new ZipArchiveInputStream(null),"encoding");
+ private static final String CPIO_DEFAULT = getField(new CpioArchiveInputStream(null),"encoding");
+ private static final String TAR_DEFAULT = getField(new TarArchiveInputStream(null),"encoding");
+ private static final String JAR_DEFAULT = getField(new JarArchiveInputStream(null),"encoding");
+
+ static {
+ String dflt;
+ dflt = "??";
+ try {
+ dflt = getField(new ArjArchiveInputStream(new FileInputStream(getFile("bla.arj"))), "charsetName");
+ } catch (ArchiveException e) {
+ e.printStackTrace();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ ARJ_DEFAULT = dflt;
+ dflt = "??";
+ try {
+ dflt = getField(new DumpArchiveInputStream(new FileInputStream(getFile("bla.dump"))), "encoding");
+ } catch (ArchiveException e) {
+ e.printStackTrace();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ DUMP_DEFAULT = dflt;
+ }
+
+ static final TestData[] TESTS = {
+ new TestData("bla.arj", ArchiveStreamFactory.ARJ, false, ARJ_DEFAULT, FACTORY, "charsetName"),
+ new TestData("bla.arj", ArchiveStreamFactory.ARJ, false, "UTF-8", FACTORY_UTF8, "charsetName"),
+ new TestData("bla.arj", ArchiveStreamFactory.ARJ, false, "ASCII", FACTORY_ASCII, "charsetName"),
+ new TestData("bla.arj", ArchiveStreamFactory.ARJ, false, "UTF-8", FACTORY_SET_UTF8, "charsetName"),
+ new TestData("bla.arj", ArchiveStreamFactory.ARJ, false, "ASCII", FACTORY_SET_ASCII, "charsetName"),
+
+ new TestData("bla.cpio", ArchiveStreamFactory.CPIO, true, CPIO_DEFAULT, FACTORY, "encoding"),
+ new TestData("bla.cpio", ArchiveStreamFactory.CPIO, true, "UTF-8", FACTORY_UTF8, "encoding"),
+ new TestData("bla.cpio", ArchiveStreamFactory.CPIO, true, "ASCII", FACTORY_ASCII, "encoding"),
+ new TestData("bla.cpio", ArchiveStreamFactory.CPIO, true, "UTF-8", FACTORY_SET_UTF8, "encoding"),
+ new TestData("bla.cpio", ArchiveStreamFactory.CPIO, true, "ASCII", FACTORY_SET_ASCII, "encoding"),
+
+ new TestData("bla.dump", ArchiveStreamFactory.DUMP, false, DUMP_DEFAULT, FACTORY, "encoding"),
+ new TestData("bla.dump", ArchiveStreamFactory.DUMP, false, "UTF-8", FACTORY_UTF8, "encoding"),
+ new TestData("bla.dump", ArchiveStreamFactory.DUMP, false, "ASCII", FACTORY_ASCII, "encoding"),
+ new TestData("bla.dump", ArchiveStreamFactory.DUMP, false, "UTF-8", FACTORY_SET_UTF8, "encoding"),
+ new TestData("bla.dump", ArchiveStreamFactory.DUMP, false, "ASCII", FACTORY_SET_ASCII, "encoding"),
+
+ new TestData("bla.tar", ArchiveStreamFactory.TAR, true, TAR_DEFAULT, FACTORY, "encoding"),
+ new TestData("bla.tar", ArchiveStreamFactory.TAR, true, "UTF-8", FACTORY_UTF8, "encoding"),
+ new TestData("bla.tar", ArchiveStreamFactory.TAR, true, "ASCII", FACTORY_ASCII, "encoding"),
+ new TestData("bla.tar", ArchiveStreamFactory.TAR, true, "UTF-8", FACTORY_SET_UTF8, "encoding"),
+ new TestData("bla.tar", ArchiveStreamFactory.TAR, true, "ASCII", FACTORY_SET_ASCII, "encoding"),
+
+ new TestData("bla.jar", ArchiveStreamFactory.JAR, true, JAR_DEFAULT, FACTORY, "encoding"),
+ new TestData("bla.jar", ArchiveStreamFactory.JAR, true, "UTF-8", FACTORY_UTF8, "encoding"),
+ new TestData("bla.jar", ArchiveStreamFactory.JAR, true, "ASCII", FACTORY_ASCII, "encoding"),
+ new TestData("bla.jar", ArchiveStreamFactory.JAR, true, "UTF-8", FACTORY_SET_UTF8, "encoding"),
+ new TestData("bla.jar", ArchiveStreamFactory.JAR, true, "ASCII", FACTORY_SET_ASCII, "encoding"),
+
+ new TestData("bla.zip", ArchiveStreamFactory.ZIP, true, ZIP_DEFAULT, FACTORY, "encoding"),
+ new TestData("bla.zip", ArchiveStreamFactory.ZIP, true, "UTF-8", FACTORY_UTF8, "encoding"),
+ new TestData("bla.zip", ArchiveStreamFactory.ZIP, true, "ASCII", FACTORY_ASCII, "encoding"),
+ new TestData("bla.zip", ArchiveStreamFactory.ZIP, true, "UTF-8", FACTORY_SET_UTF8, "encoding"),
+ new TestData("bla.zip", ArchiveStreamFactory.ZIP, true, "ASCII", FACTORY_SET_ASCII, "encoding"),
+ };
+
+ @Test
+ public void testEncodingInputStreamAutodetect() throws Exception {
+ int failed = 0;
+ for(int i = 1; i <= TESTS.length; i++) {
+ TestData test = TESTS[i-1];
+ ArchiveInputStream ais = getInputStreamFor(test.testFile, test.fac);
+ final String field = getField(ais,test.fieldName);
+ if (!eq(test.expectedEncoding,field)) {
+ System.out.println("Failed test " + i + ". expected: " + test.expectedEncoding + " actual: " + field + " type: " + test.type);
+ failed++;
+ }
+ }
+ if (failed > 0) {
+ fail("Tests failed: " + failed);
+ }
+ }
+
+ @Test
+ public void testEncodingInputStream() throws Exception {
+ int failed = 0;
+ for(int i = 1; i <= TESTS.length; i++) {
+ TestData test = TESTS[i-1];
+ ArchiveInputStream ais = getInputStreamFor(test.type, test.testFile, test.fac);
+ final String field = getField(ais,test.fieldName);
+ if (!eq(test.expectedEncoding,field)) {
+ System.out.println("Failed test " + i + ". expected: " + test.expectedEncoding + " actual: " + field + " type: " + test.type);
+ failed++;
+ }
+ }
+ if (failed > 0) {
+ fail("Tests failed: " + failed);
+ }
+ }
+
+ @Test
+ public void testEncodingOutputStream() throws Exception {
+ int failed = 0;
+ for(int i = 1; i <= TESTS.length; i++) {
+ TestData test = TESTS[i-1];
+ if (test.hasOutputStream) {
+ ArchiveOutputStream ais = getOutputStreamFor(test.type, test.fac);
+ final String field = getField(ais, test.fieldName);
+ if (!eq(test.expectedEncoding, field)) {
+ System.out.println("Failed test " + i + ". expected: " + test.expectedEncoding + " actual: " + field + " type: " + test.type);
+ failed++;
+ }
+ }
+ }
+ if (failed > 0) {
+ fail("Tests failed: " + failed);
+ }
+ }
+
+ // equals allowing null
+ private static boolean eq(String exp, String act) {
+ if (exp == null) {
+ return act == null;
+ }
+ return exp.equals(act);
+ }
+
+ private static String getField(Object instance, String name) {
+ Class<?> cls = instance.getClass();
+ Field fld;
+ try {
+ fld = cls.getDeclaredField(name);
+ } catch (NoSuchFieldException nsfe) {
+ try {
+ fld = cls.getSuperclass().getDeclaredField(name);
+ } catch (NoSuchFieldException e) {
+ System.out.println("Cannot find " + name + " in class " + instance.getClass().getSimpleName());
+ return "??";
+ }
+ }
+ boolean isAccessible = fld.isAccessible();
+ try {
+ if (!isAccessible) {
+ fld.setAccessible(true);
+ }
+ final Object object = fld.get(instance);
+ if (object instanceof String || object == null) {
+ return (String) object;
+ } else {
+ System.out.println("Wrong type: " + object.getClass().getCanonicalName() + " for " + name + " in class " + instance.getClass().getSimpleName());
+ return "??";
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ return "??";
+ } finally {
+ if (!isAccessible) {
+ fld.setAccessible(isAccessible);
+ }
+ }
+ }
+
+ private ArchiveInputStream getInputStreamFor(String resource, ArchiveStreamFactory factory)
+ throws IOException, ArchiveException {
+ return factory.createArchiveInputStream(
+ new BufferedInputStream(new FileInputStream(
+ getFile(resource))));
+ }
+
+ private ArchiveInputStream getInputStreamFor(String type, String resource, ArchiveStreamFactory factory)
+ throws IOException, ArchiveException {
+ return factory.createArchiveInputStream(
+ type,
+ new BufferedInputStream(new FileInputStream(
+ getFile(resource))));
+ }
+
+ private ArchiveOutputStream getOutputStreamFor(String type, ArchiveStreamFactory factory)
+ throws IOException, ArchiveException {
+ return factory.createArchiveOutputStream(type, new ByteArrayOutputStream());
+ }
}