You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@ant.apache.org by bo...@apache.org on 2009/03/02 18:17:09 UTC
svn commit: r749368 - in /ant/core/trunk/src: main/org/apache/tools/zip/
tests/junit/org/apache/tools/zip/
Author: bodewig
Date: Mon Mar 2 17:17:09 2009
New Revision: 749368
URL: http://svn.apache.org/viewvc?rev=749368&view=rev
Log:
improved zip-encoding support for JDK < 1.5, submitted by Wolfgang Glas, merge from commons-compress
Added:
ant/core/trunk/src/main/org/apache/tools/zip/FallbackZipEncoding.java (contents, props changed)
- copied, changed from r749343, commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/FallbackZipEncoding.java
ant/core/trunk/src/main/org/apache/tools/zip/NioZipEncoding.java (contents, props changed)
- copied, changed from r749343, commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/NioZipEncoding.java
ant/core/trunk/src/main/org/apache/tools/zip/Simple8BitZipEncoding.java
- copied, changed from r749344, commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/Simple8BitZipEncoding.java
ant/core/trunk/src/main/org/apache/tools/zip/ZipEncoding.java (contents, props changed)
- copied, changed from r749344, commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipEncoding.java
ant/core/trunk/src/tests/junit/org/apache/tools/zip/ZipEncodingTest.java
- copied, changed from r749345, commons/sandbox/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/TestZipEncodings.java
Modified:
ant/core/trunk/src/main/org/apache/tools/zip/AbstractUnicodeExtraField.java (contents, props changed)
ant/core/trunk/src/main/org/apache/tools/zip/UnicodeCommentExtraField.java (contents, props changed)
ant/core/trunk/src/main/org/apache/tools/zip/UnicodePathExtraField.java (contents, props changed)
ant/core/trunk/src/main/org/apache/tools/zip/ZipEncodingHelper.java (contents, props changed)
ant/core/trunk/src/main/org/apache/tools/zip/ZipFile.java (contents, props changed)
ant/core/trunk/src/main/org/apache/tools/zip/ZipOutputStream.java (contents, props changed)
ant/core/trunk/src/tests/junit/org/apache/tools/zip/UTF8ZipFilesTest.java (contents, props changed)
Modified: ant/core/trunk/src/main/org/apache/tools/zip/AbstractUnicodeExtraField.java
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/zip/AbstractUnicodeExtraField.java?rev=749368&r1=749367&r2=749368&view=diff
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/zip/AbstractUnicodeExtraField.java (original)
+++ ant/core/trunk/src/main/org/apache/tools/zip/AbstractUnicodeExtraField.java Mon Mar 2 17:17:09 2009
@@ -38,11 +38,25 @@
* encoding of the orginal zip entry.
*
* @param text The file name or comment.
- * @param zipEncoding The encoding of the filenames in the zip
- * file, usually <code>"CP437"</code>.
+ * @param bytes The encoded of the filename or comment in the zip
+ * file.
+ * @param off The offset of the encoded filename or comment in
+ * <code>bytes</code>.
+ * @param len The length of the encoded filename or commentin
+ * <code>bytes</code>.
*/
- protected AbstractUnicodeExtraField(String text, String zipEncoding) {
- this(text, ZipEncodingHelper.encodeName(text, zipEncoding));
+ protected AbstractUnicodeExtraField(String text, byte[] bytes, int off,
+ int len) {
+ CRC32 crc32 = new CRC32();
+ crc32.update(bytes, off, len);
+ nameCRC32 = crc32.getValue();
+
+ try {
+ unicodeName = text.getBytes("UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException("FATAL: UTF-8 encoding not supported.",
+ e);
+ }
}
/**
@@ -50,20 +64,12 @@
* encoding of the orginal zip entry.
*
* @param text The file name or comment.
- * @param zipEncoding The encoding of the filenames in the zip
- * file, usually <code>"CP437"</code>.
+ * @param bytes The encoded of the filename or comment in the zip
+ * file.
*/
protected AbstractUnicodeExtraField(String text, byte[] bytes) {
- CRC32 crc32 = new CRC32();
- crc32.update(bytes);
- nameCRC32 = crc32.getValue();
- try {
- unicodeName = text.getBytes("UTF-8");
- } catch (UnsupportedEncodingException e) {
- throw new RuntimeException("FATAL: UTF-8 encoding not supported.",
- e);
- }
+ this(text, bytes, 0, bytes.length);
}
private void assembleData() {
Propchange: ant/core/trunk/src/main/org/apache/tools/zip/AbstractUnicodeExtraField.java
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Mar 2 17:17:09 2009
@@ -1,2 +1,2 @@
/ant/core/trunk/src/main/org/apache/tools/zip/AbstractUnicodeExtraField.java:738844,739300,741089
-/commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/AbstractUnicodeExtraField.java:746933,748063,748133,748288
+/commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/AbstractUnicodeExtraField.java:746933,748063,748133,748288,749342
Copied: ant/core/trunk/src/main/org/apache/tools/zip/FallbackZipEncoding.java (from r749343, commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/FallbackZipEncoding.java)
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/zip/FallbackZipEncoding.java?p2=ant/core/trunk/src/main/org/apache/tools/zip/FallbackZipEncoding.java&p1=commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/FallbackZipEncoding.java&r1=749343&r2=749368&rev=749368&view=diff
==============================================================================
--- commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/FallbackZipEncoding.java (original)
+++ ant/core/trunk/src/main/org/apache/tools/zip/FallbackZipEncoding.java Mon Mar 2 17:17:09 2009
@@ -17,7 +17,7 @@
* under the License.
*/
-package org.apache.commons.compress.archivers.zip;
+package org.apache.tools.zip;
import java.io.IOException;
import java.nio.ByteBuffer;
@@ -62,7 +62,7 @@
/**
* @see
- * org.apache.commons.compress.archivers.zip.ZipEncoding#canEncode(java.lang.String)
+ * org.apache.tools.zip.ZipEncoding#canEncode(java.lang.String)
*/
public boolean canEncode(String name) {
return true;
@@ -70,7 +70,7 @@
/**
* @see
- * org.apache.commons.compress.archivers.zip.ZipEncoding#encode(java.lang.String)
+ * org.apache.tools.zip.ZipEncoding#encode(java.lang.String)
*/
public ByteBuffer encode(String name) throws IOException {
if (this.charset == null) {
@@ -82,7 +82,7 @@
/**
* @see
- * org.apache.commons.compress.archivers.zip.ZipEncoding#decode(byte[])
+ * org.apache.tools.zip.ZipEncoding#decode(byte[])
*/
public String decode(byte[] data) throws IOException {
if (this.charset == null) {
Propchange: ant/core/trunk/src/main/org/apache/tools/zip/FallbackZipEncoding.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: ant/core/trunk/src/main/org/apache/tools/zip/FallbackZipEncoding.java
------------------------------------------------------------------------------
--- svn:mergeinfo (added)
+++ svn:mergeinfo Mon Mar 2 17:17:09 2009
@@ -0,0 +1 @@
+/ant/core/trunk/src/main/org/apache/tools/zip/FallbackZipEncoding.java:738844,739300,741089
Copied: ant/core/trunk/src/main/org/apache/tools/zip/NioZipEncoding.java (from r749343, commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/NioZipEncoding.java)
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/zip/NioZipEncoding.java?p2=ant/core/trunk/src/main/org/apache/tools/zip/NioZipEncoding.java&p1=commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/NioZipEncoding.java&r1=749343&r2=749368&rev=749368&view=diff
==============================================================================
--- commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/NioZipEncoding.java (original)
+++ ant/core/trunk/src/main/org/apache/tools/zip/NioZipEncoding.java Mon Mar 2 17:17:09 2009
@@ -17,7 +17,7 @@
* under the License.
*/
-package org.apache.commons.compress.archivers.zip;
+package org.apache.tools.zip;
import java.io.IOException;
import java.nio.ByteBuffer;
@@ -52,7 +52,7 @@
/**
* @see
- * org.apache.commons.compress.archivers.zip.ZipEncoding#canEncode(java.lang.String)
+ * org.apache.tools.zip.ZipEncoding#canEncode(java.lang.String)
*/
public boolean canEncode(String name) {
CharsetEncoder enc = this.charset.newEncoder();
@@ -64,7 +64,7 @@
/**
* @see
- * org.apache.commons.compress.archivers.zip.ZipEncoding#encode(java.lang.String)
+ * org.apache.tools.zip.ZipEncoding#encode(java.lang.String)
*/
public ByteBuffer encode(String name) {
CharsetEncoder enc = this.charset.newEncoder();
@@ -111,7 +111,7 @@
/**
* @see
- * org.apache.commons.compress.archivers.zip.ZipEncoding#decode(byte[])
+ * org.apache.tools.zip.ZipEncoding#decode(byte[])
*/
public String decode(byte[] data) throws IOException {
return this.charset.newDecoder()
Propchange: ant/core/trunk/src/main/org/apache/tools/zip/NioZipEncoding.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: ant/core/trunk/src/main/org/apache/tools/zip/NioZipEncoding.java
------------------------------------------------------------------------------
--- svn:mergeinfo (added)
+++ svn:mergeinfo Mon Mar 2 17:17:09 2009
@@ -0,0 +1 @@
+/ant/core/trunk/src/main/org/apache/tools/zip/NioZipEncoding.java:738844,739300,741089
Copied: ant/core/trunk/src/main/org/apache/tools/zip/Simple8BitZipEncoding.java (from r749344, commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/Simple8BitZipEncoding.java)
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/zip/Simple8BitZipEncoding.java?p2=ant/core/trunk/src/main/org/apache/tools/zip/Simple8BitZipEncoding.java&p1=commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/Simple8BitZipEncoding.java&r1=749344&r2=749368&rev=749368&view=diff
==============================================================================
--- commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/Simple8BitZipEncoding.java (original)
+++ ant/core/trunk/src/main/org/apache/tools/zip/Simple8BitZipEncoding.java Mon Mar 2 17:17:09 2009
@@ -17,7 +17,7 @@
* under the License.
*/
-package org.apache.commons.compress.archivers.zip;
+package org.apache.tools.zip;
import java.io.IOException;
import java.nio.ByteBuffer;
@@ -200,7 +200,7 @@
/**
* @see
- * org.apache.commons.compress.archivers.zip.ZipEncoding#canEncode(java.lang.String)
+ * org.apache.tools.zip.ZipEncoding#canEncode(java.lang.String)
*/
public boolean canEncode(String name) {
@@ -218,7 +218,7 @@
/**
* @see
- * org.apache.commons.compress.archivers.zip.ZipEncoding#encode(java.lang.String)
+ * org.apache.tools.zip.ZipEncoding#encode(java.lang.String)
*/
public ByteBuffer encode(String name) {
ByteBuffer out = ByteBuffer.allocate(name.length()
@@ -245,7 +245,7 @@
/**
* @see
- * org.apache.commons.compress.archivers.zip.ZipEncoding#decode(byte[])
+ * org.apache.tools.zip.ZipEncoding#decode(byte[])
*/
public String decode(byte[] data) throws IOException {
char [] ret = new char[data.length];
Modified: ant/core/trunk/src/main/org/apache/tools/zip/UnicodeCommentExtraField.java
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/zip/UnicodeCommentExtraField.java?rev=749368&r1=749367&r2=749368&view=diff
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/zip/UnicodeCommentExtraField.java (original)
+++ ant/core/trunk/src/main/org/apache/tools/zip/UnicodeCommentExtraField.java Mon Mar 2 17:17:09 2009
@@ -42,15 +42,18 @@
}
/**
- * Assemble as unicode comment extension from the comment and
- * encoding of the orginal zip entry.
+ * Assemble as unicode comment extension from the name given as
+ * text as well as the encoded bytes actually written to the archive.
*
- * @param comment The file comment
- * @param zipEncoding The encoding of the comment in the zip file,
- * usually <code>"CP437"</code>.
+ * @param name The file name
+ * @param bytes the bytes actually written to the archive
+ * @param off The offset of the encoded comment in <code>bytes</code>.
+ * @param len The length of the encoded comment or comment in
+ * <code>bytes</code>.
*/
- public UnicodeCommentExtraField(String comment, String zipEncoding) {
- super(comment, zipEncoding);
+ public UnicodeCommentExtraField(String text, byte[] bytes, int off,
+ int len) {
+ super(text, bytes, off, len);
}
/**
Propchange: ant/core/trunk/src/main/org/apache/tools/zip/UnicodeCommentExtraField.java
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Mar 2 17:17:09 2009
@@ -1,2 +1,2 @@
/ant/core/trunk/src/main/org/apache/tools/zip/UnicodeCommentExtraField.java:738844,739300,741089
-/commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/UnicodeCommentExtraField.java:746933,748063,748133
+/commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/UnicodeCommentExtraField.java:746933,748063,748133,749342
Modified: ant/core/trunk/src/main/org/apache/tools/zip/UnicodePathExtraField.java
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/zip/UnicodePathExtraField.java?rev=749368&r1=749367&r2=749368&view=diff
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/zip/UnicodePathExtraField.java (original)
+++ ant/core/trunk/src/main/org/apache/tools/zip/UnicodePathExtraField.java Mon Mar 2 17:17:09 2009
@@ -42,20 +42,22 @@
}
/**
- * Assemble as unicode path extension from the name and encoding
- * of the orginal zip entry.
+ * Assemble as unicode path extension from the name given as
+ * text as well as the encoded bytes actually written to the archive.
*
* @param name The file name
- * @param zipEncoding The encoding of the filename in the zip
- * file, usually <code>"CP437"</code>.
+ * @param bytes the bytes actually written to the archive
+ * @param off The offset of the encoded filename in <code>bytes</code>.
+ * @param len The length of the encoded filename or comment in
+ * <code>bytes</code>.
*/
- public UnicodePathExtraField(String name, String zipEncoding) {
- super(name, zipEncoding);
+ public UnicodePathExtraField(String text, byte[] bytes, int off, int len) {
+ super(text, bytes, off, len);
}
/**
* Assemble as unicode path extension from the name given as
- * text as well as the bytes actually written to the archive.
+ * text as well as the encoded bytes actually written to the archive.
*
* @param name The file name
* @param bytes the bytes actually written to the archive
Propchange: ant/core/trunk/src/main/org/apache/tools/zip/UnicodePathExtraField.java
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Mar 2 17:17:09 2009
@@ -1,2 +1,2 @@
/ant/core/trunk/src/main/org/apache/tools/zip/UnicodePathExtraField.java:738844,739300,741089
-/commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/UnicodePathExtraField.java:746933,748063,748133
+/commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/UnicodePathExtraField.java:746933,748063,748133,749342
Copied: ant/core/trunk/src/main/org/apache/tools/zip/ZipEncoding.java (from r749344, commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipEncoding.java)
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/zip/ZipEncoding.java?p2=ant/core/trunk/src/main/org/apache/tools/zip/ZipEncoding.java&p1=commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipEncoding.java&r1=749344&r2=749368&rev=749368&view=diff
==============================================================================
--- commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipEncoding.java (original)
+++ ant/core/trunk/src/main/org/apache/tools/zip/ZipEncoding.java Mon Mar 2 17:17:09 2009
@@ -17,7 +17,7 @@
* under the License.
*/
-package org.apache.commons.compress.archivers.zip;
+package org.apache.tools.zip;
import java.io.IOException;
import java.nio.ByteBuffer;
Propchange: ant/core/trunk/src/main/org/apache/tools/zip/ZipEncoding.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: ant/core/trunk/src/main/org/apache/tools/zip/ZipEncoding.java
------------------------------------------------------------------------------
--- svn:mergeinfo (added)
+++ svn:mergeinfo Mon Mar 2 17:17:09 2009
@@ -0,0 +1 @@
+/ant/core/trunk/src/main/org/apache/tools/zip/ZipEncoding.java:738844,739300,741089
Modified: ant/core/trunk/src/main/org/apache/tools/zip/ZipEncodingHelper.java
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/zip/ZipEncodingHelper.java?rev=749368&r1=749367&r2=749368&view=diff
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/zip/ZipEncodingHelper.java (original)
+++ ant/core/trunk/src/main/org/apache/tools/zip/ZipEncodingHelper.java Mon Mar 2 17:17:09 2009
@@ -19,11 +19,10 @@
package org.apache.tools.zip;
import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
import java.nio.charset.Charset;
-import java.nio.charset.CharsetEncoder;
-import java.nio.charset.CoderResult;
-import java.nio.charset.CodingErrorAction;
+import java.nio.charset.UnsupportedCharsetException;
+import java.util.HashMap;
+import java.util.Map;
/**
* Static helper functions for robustly encoding filenames in zip files.
@@ -31,6 +30,109 @@
abstract class ZipEncodingHelper {
/**
+ * A class, which holds the high characters of a simple encoding
+ * and lazily instantiates a Simple8BitZipEncoding instance in a
+ * thread-safe manner.
+ */
+ private static class SimpleEncodingHolder {
+
+ private final char [] highChars;
+ private Simple8BitZipEncoding encoding;
+
+ /**
+ * Instantiate a simple encoding holder.
+ *
+ * @param highChars The characters for byte codes 128 to 255.
+ *
+ * @see Simple8BitZipEncoding#Simple8BitZipEncoding(char[])
+ */
+ SimpleEncodingHolder(char [] highChars) {
+ this.highChars = highChars;
+ }
+
+ /**
+ * @return The associated {@see Simple8BitZipEncoding}, which
+ * is instantiated if not done so far.
+ */
+ public synchronized Simple8BitZipEncoding getEncoding() {
+ if (this.encoding == null) {
+ this.encoding = new Simple8BitZipEncoding(this.highChars);
+ }
+ return this.encoding;
+ }
+ }
+
+ private static final Map simpleEncodings;
+
+ static {
+ simpleEncodings = new HashMap();
+
+ char[] cp437_high_chars =
+ new char[] { 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0,
+ 0x00e5, 0x00e7, 0x00ea, 0x00eb, 0x00e8, 0x00ef,
+ 0x00ee, 0x00ec, 0x00c4, 0x00c5, 0x00c9, 0x00e6,
+ 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9,
+ 0x00ff, 0x00d6, 0x00dc, 0x00a2, 0x00a3, 0x00a5,
+ 0x20a7, 0x0192, 0x00e1, 0x00ed, 0x00f3, 0x00fa,
+ 0x00f1, 0x00d1, 0x00aa, 0x00ba, 0x00bf, 0x2310,
+ 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb,
+ 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561,
+ 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557,
+ 0x255d, 0x255c, 0x255b, 0x2510, 0x2514, 0x2534,
+ 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f,
+ 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550,
+ 0x256c, 0x2567, 0x2568, 0x2564, 0x2565, 0x2559,
+ 0x2558, 0x2552, 0x2553, 0x256b, 0x256a, 0x2518,
+ 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580,
+ 0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3,
+ 0x00b5, 0x03c4, 0x03a6, 0x0398, 0x03a9, 0x03b4,
+ 0x221e, 0x03c6, 0x03b5, 0x2229, 0x2261, 0x00b1,
+ 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248,
+ 0x00b0, 0x2219, 0x00b7, 0x221a, 0x207f, 0x00b2,
+ 0x25a0, 0x00a0 };
+
+ SimpleEncodingHolder cp437 = new SimpleEncodingHolder(cp437_high_chars);
+
+ simpleEncodings.put("CP437",cp437);
+ simpleEncodings.put("Cp437",cp437);
+ simpleEncodings.put("cp437",cp437);
+ simpleEncodings.put("IBM437",cp437);
+ simpleEncodings.put("ibm437",cp437);
+
+ char[] cp850_high_chars =
+ new char[] { 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0,
+ 0x00e5, 0x00e7, 0x00ea, 0x00eb, 0x00e8, 0x00ef,
+ 0x00ee, 0x00ec, 0x00c4, 0x00c5, 0x00c9, 0x00e6,
+ 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9,
+ 0x00ff, 0x00d6, 0x00dc, 0x00f8, 0x00a3, 0x00d8,
+ 0x00d7, 0x0192, 0x00e1, 0x00ed, 0x00f3, 0x00fa,
+ 0x00f1, 0x00d1, 0x00aa, 0x00ba, 0x00bf, 0x00ae,
+ 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb,
+ 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00c1,
+ 0x00c2, 0x00c0, 0x00a9, 0x2563, 0x2551, 0x2557,
+ 0x255d, 0x00a2, 0x00a5, 0x2510, 0x2514, 0x2534,
+ 0x252c, 0x251c, 0x2500, 0x253c, 0x00e3, 0x00c3,
+ 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550,
+ 0x256c, 0x00a4, 0x00f0, 0x00d0, 0x00ca, 0x00cb,
+ 0x00c8, 0x0131, 0x00cd, 0x00ce, 0x00cf, 0x2518,
+ 0x250c, 0x2588, 0x2584, 0x00a6, 0x00cc, 0x2580,
+ 0x00d3, 0x00df, 0x00d4, 0x00d2, 0x00f5, 0x00d5,
+ 0x00b5, 0x00fe, 0x00de, 0x00da, 0x00db, 0x00d9,
+ 0x00fd, 0x00dd, 0x00af, 0x00b4, 0x00ad, 0x00b1,
+ 0x2017, 0x00be, 0x00b6, 0x00a7, 0x00f7, 0x00b8,
+ 0x00b0, 0x00a8, 0x00b7, 0x00b9, 0x00b3, 0x00b2,
+ 0x25a0, 0x00a0 };
+
+ SimpleEncodingHolder cp850 = new SimpleEncodingHolder(cp850_high_chars);
+
+ simpleEncodings.put("CP850",cp850);
+ simpleEncodings.put("Cp850",cp850);
+ simpleEncodings.put("cp850",cp850);
+ simpleEncodings.put("IBM850",cp850);
+ simpleEncodings.put("ibm850",cp850);
+ }
+
+ /**
* Grow a byte buffer, so it has a minimal capacity or at least
* the double capacity of the original buffer
*
@@ -53,7 +155,7 @@
return on;
}
-
+
/**
* The hexadecimal digits <code>0,...,9,A,...,F</code> encoded as
* ASCII bytes.
@@ -65,131 +167,79 @@
};
/**
- * Encode a filename or a comment to a byte array suitable for
- * storing it to a serialized zip entry.
+ * Append <code>%Uxxxx</code> to the given byte buffer.
+ * The caller must assure, that <code>bb.remaining()>=6</code>.
*
- * Examples (in pseudo-notation, right hand side is C-style notation):
- * <pre>
- * encodeName("\u20AC_for_Dollar.txt","CP437") = "%U20AC_for_Dollar.txt"
- * encodeName("\u00D6lf\u00E4sser.txt","CP437") = "\231lf\204sser.txt"
- * </pre>
- *
- * @param name The filename or comment with possible non-ASCII
- * unicode characters. Must not be null.
- * @param encoding A valid encoding name. The standard zip
- * encoding is <code>"CP437"</code>,
- * <code>"UTF-8"</code> is supported in ZIP file
- * version <code>6.3</code> or later. If null,
- * will use the platform's {@link
- * java.lang.String#getBytes default encoding}.
- * @return A byte array containing the mapped file
- * name. Unmappable characters or malformed character
- * sequences are mapped to a sequence of utf-16 words
- * encoded in the format <code>%Uxxxx</code>.
+ * @param bb The byte buffer to write to.
+ * @param c The character to write.
*/
- static final byte[] encodeName(String name, String encoding) {
- if (encoding == null) {
- return name.getBytes();
- }
+ static void appendSurrogate(ByteBuffer bb, char c) {
- Charset cs = Charset.forName(encoding);
- CharsetEncoder enc = cs.newEncoder();
+ bb.put((byte) '%');
+ bb.put((byte) 'U');
- enc.onMalformedInput(CodingErrorAction.REPORT);
- enc.onUnmappableCharacter(CodingErrorAction.REPORT);
-
- CharBuffer cb = CharBuffer.wrap(name);
- ByteBuffer out = ByteBuffer.allocate(name.length()
- + (name.length() + 1) / 2);
-
- while (cb.remaining() > 0) {
- CoderResult res = enc.encode(cb, out,true);
+ bb.put(HEX_DIGITS[(c >> 12)&0x0f]);
+ bb.put(HEX_DIGITS[(c >> 8)&0x0f]);
+ bb.put(HEX_DIGITS[(c >> 4)&0x0f]);
+ bb.put(HEX_DIGITS[c & 0x0f]);
+ }
- if (res.isUnmappable() || res.isMalformed()) {
- // write the unmappable characters in utf-16
- // pseudo-URL encoding style to ByteBuffer.
- if (res.length() * 6 > out.remaining()) {
- out = growBuffer(out,out.position() + res.length() * 6);
- }
+ /**
+ * name of the encoding UTF-8
+ */
+ static final String UTF8 = "UTF8";
- for (int i=0; i<res.length(); ++i) {
- out.put((byte) '%');
- out.put((byte) 'U');
+ /**
+ * name of the encoding UTF-8
+ */
+ static final ZipEncoding UTF8_ZIP_ENCODING = new FallbackZipEncoding(UTF8);
- char c = cb.get();
+ /**
+ * Instantiates a zip encoding.
+ *
+ * @param name The name of the zip encoding. Specify <code>null</code> for
+ * the platform's default encoding.
+ * @return A zip encoding for the given encoding name.
+ */
+ static ZipEncoding getZipEncoding(String name) {
+
+ // fallback encoding is good enough for utf-8.
+ if (isUTF8(name)) {
+ return UTF8_ZIP_ENCODING;
+ }
- out.put(HEX_DIGITS[(c >> 12)&0x0f]);
- out.put(HEX_DIGITS[(c >> 8)&0x0f]);
- out.put(HEX_DIGITS[(c >> 4)&0x0f]);
- out.put(HEX_DIGITS[c & 0x0f]);
- }
+ if (name == null) {
+ return new FallbackZipEncoding();
+ }
- } else if (res.isOverflow()) {
+ SimpleEncodingHolder h =
+ (SimpleEncodingHolder) simpleEncodings.get(name);
- out = growBuffer(out, 0);
+ if (h!=null) {
+ return h.getEncoding();
+ }
- } else if (res.isUnderflow()) {
+ try {
- enc.flush(out);
- break;
+ Charset cs = Charset.forName(name);
+ return new NioZipEncoding(cs);
- }
+ } catch (UnsupportedCharsetException e) {
+ return new FallbackZipEncoding(name);
}
-
- byte [] ret = new byte[out.position()];
- out.rewind();
- out.get(ret);
-
- return ret;
}
/**
- * Return, whether a filename or a comment may be encoded to a
- * byte array suitable for storing it to a serialized zip entry
- * without any losses.
- *
- * Examples (in pseudo-notation, right hand side is C-style notation):
- * <pre>
- * canEncodeName("\u20AC_for_Dollar.txt","CP437") = false
- * canEncodeName("\u20AC_for_Dollar.txt","UTF-8") = true
- * canEncodeName("\u00D6lf\u00E4sser.txt","CP437") = true
- * </pre>
- *
- * @param name The filename or comment with possible non-ASCII
- * unicode characters.
- * @param encoding A valid encoding name. The standard zip
- * encoding is <code>"CP437"</code>,
- * <code>"UTF-8"</code> is supported in ZIP file
- * version <code>6.3</code> or later.
- * @return Whether the given encoding may encode the given name.
+ * Whether a given encoding - or the platform's default encoding
+ * if the parameter is null - is UTF-8.
*/
- static final boolean canEncodeName(String name, String encoding) {
-
- Charset cs = Charset.forName(encoding);
-
- CharsetEncoder enc = cs.newEncoder();
- enc.onMalformedInput(CodingErrorAction.REPORT);
- enc.onUnmappableCharacter(CodingErrorAction.REPORT);
-
- return enc.canEncode(name);
- }
-
- /**
- * Decode a filename or a comment from a byte array.
- *
- * @param name The filename or comment.
- * @param encoding A valid encoding name. The standard zip
- * encoding is <code>"CP437"</code>,
- * <code>"UTF-8"</code> is supported in ZIP file
- * version <code>6.3</code> or later.
- */
- static final String decodeName(byte[] name, String encoding)
- throws java.nio.charset.CharacterCodingException {
- Charset cs = Charset.forName(encoding);
- return cs.newDecoder()
- .onMalformedInput(CodingErrorAction.REPORT)
- .onUnmappableCharacter(CodingErrorAction.REPORT)
- .decode(ByteBuffer.wrap(name)).toString();
+ static boolean isUTF8(String encoding) {
+ if (encoding == null) {
+ // check platform's default encoding
+ encoding = System.getProperty("file.encoding");
+ }
+ return UTF8.equalsIgnoreCase(encoding)
+ || "utf-8".equalsIgnoreCase(encoding);
}
}
Propchange: ant/core/trunk/src/main/org/apache/tools/zip/ZipEncodingHelper.java
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Mar 2 17:17:09 2009
@@ -1,2 +1,2 @@
/ant/core/trunk/src/main/org/apache/tools/zip/ZipEncodingHelper.java:738844,739300,741089
-/commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipEncodingHelper.java:746933,747841,748133
+/commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipEncodingHelper.java:746933,747841,748133,749342-749344
Modified: ant/core/trunk/src/main/org/apache/tools/zip/ZipFile.java
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/zip/ZipFile.java?rev=749368&r1=749367&r2=749368&view=diff
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/zip/ZipFile.java (original)
+++ ant/core/trunk/src/main/org/apache/tools/zip/ZipFile.java Mon Mar 2 17:17:09 2009
@@ -22,8 +22,6 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
-import java.io.UnsupportedEncodingException;
-import java.nio.charset.CharacterCodingException;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
@@ -99,6 +97,11 @@
private String encoding = null;
/**
+ * The zip encoding to use for filenames and the file comment.
+ */
+ private final ZipEncoding zipEncoding;
+
+ /**
* The actual data source.
*/
private RandomAccessFile archive;
@@ -164,15 +167,17 @@
* encoding for file names.
*
* @param f the archive.
- * @param encoding the encoding to use for file names
- * @param whether to use InfoZIP Unicode Extra Fields (if present)
- * to set the file names.
+ * @param encoding the encoding to use for file names, use null
+ * for the platform's default encoding
+ * @param useUnicodeExtraFields whether to use InfoZIP Unicode
+ * Extra Fields (if present) to set the file names.
*
* @throws IOException if an error occurs while reading the file.
*/
public ZipFile(File f, String encoding, boolean useUnicodeExtraFields)
throws IOException {
this.encoding = encoding;
+ this.zipEncoding = ZipEncodingHelper.getZipEncoding(encoding);
this.useUnicodeExtraFields = useUnicodeExtraFields;
archive = new RandomAccessFile(f, "r");
boolean success = false;
@@ -247,7 +252,8 @@
* @param ze the entry to get the stream for.
* @return a stream to read the entry from.
* @throws IOException if unable to create an input stream from the zipenty
- * @throws ZipException if the zipentry has an unsupported compression method
+ * @throws ZipException if the zipentry has an unsupported
+ * compression method
*/
public InputStream getInputStream(ZipEntry ze)
throws IOException, ZipException {
@@ -330,8 +336,8 @@
final int generalPurposeFlag = ZipShort.getValue(cfh, off);
final boolean hasEFS =
(generalPurposeFlag & ZipOutputStream.EFS_FLAG) != 0;
- final String entryEncoding =
- hasEFS ? ZipOutputStream.UTF8 : encoding;
+ final ZipEncoding entryEncoding =
+ hasEFS ? ZipEncodingHelper.UTF8_ZIP_ENCODING : zipEncoding;
off += SHORT;
@@ -373,7 +379,7 @@
byte[] fileName = new byte[fileNameLen];
archive.readFully(fileName);
- ze.setName(getString(fileName, entryEncoding));
+ ze.setName(entryEncoding.decode(fileName));
// LFH offset,
OffsetEntry offset = new OffsetEntry();
@@ -395,7 +401,7 @@
byte[] comment = new byte[commentLen];
archive.readFully(comment);
- ze.setComment(getString(comment, entryEncoding));
+ ze.setComment(entryEncoding.decode(comment));
archive.readFully(signatureBytes);
sig = ZipLong.getValue(signatureBytes);
@@ -529,7 +535,7 @@
+ SHORT + SHORT + fileNameLen + extraFieldLen));
*/
offsetEntry.dataOffset = offset + LFH_OFFSET_FOR_FILENAME_LENGTH
- + SHORT + SHORT + fileNameLen + extraFieldLen;
+ + SHORT + SHORT + fileNameLen + extraFieldLen;
if (entriesWithoutEFS.containsKey(ze)) {
setNameAndCommentFromExtraFields(ze,
@@ -576,37 +582,10 @@
* @throws ZipException if the encoding cannot be recognized.
*/
protected String getString(byte[] bytes) throws ZipException {
- return getString(bytes, encoding);
- }
-
- /**
- * Retrieve a String from the given bytes using the encoding set
- * for this ZipFile.
- *
- * @param bytes the byte array to transform
- * @return String obtained by using the given encoding
- * @throws ZipException if the encoding cannot be recognized.
- */
- protected String getString(byte[] bytes, String enc)
- throws ZipException {
- if (enc == null) {
- return new String(bytes);
- } else {
- try {
- try {
- return ZipEncodingHelper.decodeName(bytes, enc);
- } catch (CharacterCodingException ex) {
- throw new ZipException(ex.getMessage());
- }
- } catch (java.nio.charset.UnsupportedCharsetException ex) {
- // Java 1.4's NIO doesn't recognize a few names that
- // String.getBytes does
- try {
- return new String(bytes, enc);
- } catch (UnsupportedEncodingException uee) {
- throw new ZipException(uee.getMessage());
- }
- }
+ try {
+ return ZipEncodingHelper.getZipEncoding(encoding).decode(bytes);
+ } catch (IOException ex) {
+ throw new ZipException("Failed to decode name: " + ex.getMessage());
}
}
@@ -671,8 +650,8 @@
if (origCRC32 == f.getNameCRC32()) {
try {
return ZipEncodingHelper
- .decodeName(f.getUnicodeName(), ZipOutputStream.UTF8);
- } catch (CharacterCodingException ex) {
+ .UTF8_ZIP_ENCODING.decode(f.getUnicodeName());
+ } catch (IOException ex) {
// UTF-8 unsupported? should be impossible the
// Unicode*ExtraField must contain some bad bytes
Propchange: ant/core/trunk/src/main/org/apache/tools/zip/ZipFile.java
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Mar 2 17:17:09 2009
@@ -1 +1 @@
-/commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java:745920,746933,748133,748556
+/commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java:745920,746933,748133,748556,749342-749344
Modified: ant/core/trunk/src/main/org/apache/tools/zip/ZipOutputStream.java
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/zip/ZipOutputStream.java?rev=749368&r1=749367&r2=749368&view=diff
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/zip/ZipOutputStream.java (original)
+++ ant/core/trunk/src/main/org/apache/tools/zip/ZipOutputStream.java Mon Mar 2 17:17:09 2009
@@ -24,7 +24,7 @@
import java.io.IOException;
import java.io.OutputStream;
import java.io.RandomAccessFile;
-import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
@@ -92,9 +92,9 @@
public static final int STORED = java.util.zip.ZipEntry.STORED;
/**
- * name of the encoding UTF-8
+ * default encoding for file names and comment.
*/
- static final String UTF8 = "UTF8";
+ static final String DEFAULT_ENCODING = null;
/**
* General purpose flag, which indicates that filenames are
@@ -220,7 +220,16 @@
*/
private String encoding = null;
- // CheckStyle:VisibilityModifier OFF - bc
+ /**
+ * The zip encoding to use for filenames and the file comment.
+ *
+ * This field is of internal use and will be set in {@link
+ * #setEncoding(String)}.
+ */
+ private ZipEncoding zipEncoding =
+ ZipEncodingHelper.getZipEncoding(DEFAULT_ENCODING);
+
+ // CheckStyle:VisibilityModifier OFF - bc
/**
* This Deflater object is used for output.
@@ -301,8 +310,8 @@
}
/**
- * This method indicates whether this archive is writing to a seekable stream (i.e., to a random
- * access file).
+ * This method indicates whether this archive is writing to a
+ * seekable stream (i.e., to a random access file).
*
* <p>For seekable streams, you don't need to calculate the CRC or
* uncompressed size for {@link #STORED} entries before
@@ -325,7 +334,8 @@
*/
public void setEncoding(final String encoding) {
this.encoding = encoding;
- useEFS &= isUTF8(encoding);
+ this.zipEncoding = ZipEncodingHelper.getZipEncoding(encoding);
+ useEFS &= ZipEncodingHelper.isUTF8(encoding);
}
/**
@@ -346,7 +356,7 @@
* <p>Defaults to true.</p>
*/
public void setUseLanguageEncodingFlag(boolean b) {
- useEFS = b && isUTF8(encoding);
+ useEFS = b && ZipEncodingHelper.isUTF8(encoding);
}
/**
@@ -499,14 +509,15 @@
*
* <p>Default is Deflater.DEFAULT_COMPRESSION.</p>
* @param level the compression level.
- * @throws IllegalArgumentException if an invalid compression level is specified.
+ * @throws IllegalArgumentException if an invalid compression
+ * level is specified.
* @since 1.1
*/
public void setLevel(int level) {
if (level < Deflater.DEFAULT_COMPRESSION
|| level > Deflater.BEST_COMPRESSION) {
- throw new IllegalArgumentException(
- "Invalid compression level: " + level);
+ throw new IllegalArgumentException("Invalid compression level: "
+ + level);
}
hasCompressionLevelChanged = (this.level != level);
this.level = level;
@@ -654,13 +665,31 @@
*/
protected void writeLocalFileHeader(ZipEntry ze) throws IOException {
- byte[] name = getBytes(ze.getName());
+ boolean encodable = this.zipEncoding.canEncode(ze.getName());
+ ByteBuffer name = this.zipEncoding.encode(ze.getName());
+
if (createUnicodeExtraFields) {
- ze.addExtraField(new UnicodePathExtraField(ze.getName(), name));
+
+ /* if (!encodable) { -- FIXME decide what to*/
+ ze.addExtraField(new UnicodePathExtraField(ze.getName(),
+ name.array(),
+ name.arrayOffset(),
+ name.limit()));
+ /* } */
+
String comm = ze.getComment();
if (comm != null && !"".equals(comm)) {
- byte[] commentB = getBytes(comm);
- ze.addExtraField(new UnicodeCommentExtraField(comm, commentB));
+
+ boolean commentEncodable = this.zipEncoding.canEncode(comm);
+
+ /* if (!commentEncodable) { -- FIXME decide what to*/
+ ByteBuffer commentB = this.zipEncoding.encode(comm);
+ ze.addExtraField(new UnicodeCommentExtraField(comm,
+ commentB.array(),
+ commentB.arrayOffset(),
+ commentB.limit())
+ );
+ /* } */
}
}
@@ -701,7 +730,7 @@
// CheckStyle:MagicNumber ON
// file name length
- writeOut(ZipShort.getBytes(name.length));
+ writeOut(ZipShort.getBytes(name.limit()));
written += SHORT;
// extra field length
@@ -710,8 +739,8 @@
written += SHORT;
// file name
- writeOut(name);
- written += name.length;
+ writeOut(name.array(), name.arrayOffset(), name.limit());
+ written += name.limit();
// extra field
writeOut(extra);
@@ -779,8 +808,8 @@
// CheckStyle:MagicNumber ON
// file name length
- byte[] name = getBytes(ze.getName());
- writeOut(ZipShort.getBytes(name.length));
+ ByteBuffer name = this.zipEncoding.encode(ze.getName());
+ writeOut(ZipShort.getBytes(name.limit()));
written += SHORT;
// extra field length
@@ -793,8 +822,8 @@
if (comm == null) {
comm = "";
}
- byte[] commentB = getBytes(comm);
- writeOut(ZipShort.getBytes(commentB.length));
+ ByteBuffer commentB = this.zipEncoding.encode(comm);
+ writeOut(ZipShort.getBytes(commentB.limit()));
written += SHORT;
// disk number start
@@ -814,16 +843,16 @@
written += WORD;
// file name
- writeOut(name);
- written += name.length;
+ writeOut(name.array(), name.arrayOffset(), name.limit());
+ written += name.limit();
// extra field
writeOut(extra);
written += extra.length;
// file comment
- writeOut(commentB);
- written += commentB.length;
+ writeOut(commentB.array(), commentB.arrayOffset(), commentB.limit());
+ written += commentB.limit();
}
/**
@@ -849,9 +878,9 @@
writeOut(ZipLong.getBytes(cdOffset));
// ZIP file comment
- byte[] data = getBytes(comment);
- writeOut(ZipShort.getBytes(data.length));
- writeOut(data);
+ ByteBuffer data = this.zipEncoding.encode(comment);
+ writeOut(ZipShort.getBytes(data.limit()));
+ writeOut(data.array(), data.arrayOffset(), data.limit());
}
/**
@@ -908,20 +937,15 @@
* @since 1.3
*/
protected byte[] getBytes(String name) throws ZipException {
- if (encoding == null) {
- return name.getBytes();
- } else {
- try {
- return ZipEncodingHelper.encodeName(name, encoding);
- } catch (java.nio.charset.UnsupportedCharsetException ex) {
- // Java 1.4's NIO doesn't recognize a few names that
- // String.getBytes does
- try {
- return name.getBytes(encoding);
- } catch (UnsupportedEncodingException uee) {
- throw new ZipException(uee.getMessage());
- }
- }
+ try {
+ ByteBuffer b =
+ ZipEncodingHelper.getZipEncoding(encoding).encode(name);
+ byte[] result = new byte[b.limit()];
+ System.arraycopy(b.array(), b.arrayOffset(), result, 0,
+ result.length);
+ return result;
+ } catch (IOException ex) {
+ throw new ZipException("Failed to encode name: " + ex.getMessage());
}
}
@@ -975,19 +999,6 @@
}
}
- /**
- * Whether a given encoding - or the platform's default encoding
- * if the parameter is null - is UTF-8.
- */
- static boolean isUTF8(String encoding) {
- if (encoding == null) {
- // check platform's default encoding
- encoding = System.getProperty("file.encoding");
- }
- return UTF8.equalsIgnoreCase(encoding)
- || "utf-8".equalsIgnoreCase(encoding);
- }
-
private void writeVersionNeededToExtractAndGeneralPurposeBits(final int
zipMethod)
throws IOException {
Propchange: ant/core/trunk/src/main/org/apache/tools/zip/ZipOutputStream.java
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Mar 2 17:17:09 2009
@@ -1 +1 @@
-/commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java:745920,747810,747841,748063
+/commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java:745920,747810,747841,748063,749342
Modified: ant/core/trunk/src/tests/junit/org/apache/tools/zip/UTF8ZipFilesTest.java
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/tests/junit/org/apache/tools/zip/UTF8ZipFilesTest.java?rev=749368&r1=749367&r2=749368&view=diff
==============================================================================
--- ant/core/trunk/src/tests/junit/org/apache/tools/zip/UTF8ZipFilesTest.java (original)
+++ ant/core/trunk/src/tests/junit/org/apache/tools/zip/UTF8ZipFilesTest.java Mon Mar 2 17:17:09 2009
@@ -19,12 +19,14 @@
package org.apache.tools.zip;
import java.io.File;
-import java.io.FileInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
-import java.nio.charset.Charset;
-import java.nio.charset.UnsupportedCharsetException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.nio.ByteBuffer;
import java.util.Enumeration;
+import java.util.zip.CRC32;
import junit.framework.TestCase;
public class UTF8ZipFilesTest extends TestCase {
@@ -36,33 +38,70 @@
private static final String EURO_FOR_DOLLAR_TXT = "\u20AC_for_Dollar.txt";
private static final String OIL_BARREL_TXT = "\u00D6lf\u00E4sser.txt";
- public void testUtf8FileRoundtrip() throws IOException {
- testFileRoundtrip(UTF_8);
+ public void testUtf8FileRoundtripExplicitUnicodeExtra()
+ throws IOException {
+ testFileRoundtrip(UTF_8, true, true);
+ }
+
+ public void testUtf8FileRoundtripNoEFSExplicitUnicodeExtra()
+ throws IOException {
+ testFileRoundtrip(UTF_8, false, true);
+ }
+
+ public void testCP437FileRoundtripExplicitUnicodeExtra()
+ throws IOException {
+ testFileRoundtrip(CP437, false, true);
+ }
+
+ public void testASCIIFileRoundtripExplicitUnicodeExtra()
+ throws IOException {
+ testFileRoundtrip(US_ASCII, false, true);
}
+ public void testUtf8FileRoundtripImplicitUnicodeExtra()
+ throws IOException {
+ testFileRoundtrip(UTF_8, true, false);
+ }
- public void testCP437FileRoundtrip() throws IOException {
- testFileRoundtrip(CP437);
+ public void testUtf8FileRoundtripNoEFSImplicitUnicodeExtra()
+ throws IOException {
+ testFileRoundtrip(UTF_8, false, false);
}
- public void testASCIIFileRoundtrip() throws IOException {
- testFileRoundtrip(US_ASCII);
+ public void testCP437FileRoundtripImplicitUnicodeExtra()
+ throws IOException {
+ testFileRoundtrip(CP437, false, false);
}
- private static void testFileRoundtrip(String encoding)
+ public void testASCIIFileRoundtripImplicitUnicodeExtra()
throws IOException {
+ testFileRoundtrip(US_ASCII, false, false);
+ }
+ public void testZipFileReadsUnicodeFields() throws IOException {
+ File file = File.createTempFile("unicode-test", ".zip");
+ ZipFile zf = null;
try {
- Charset.forName(encoding);
- } catch (UnsupportedCharsetException use) {
- System.err.println("Skipping testFileRoundtrip for unsupported "
- + " encoding " + encoding);
- return;
+ createTestFile(file, US_ASCII, false, true);
+ zf = new ZipFile(file, US_ASCII, true);
+ assertNotNull(zf.getEntry(ASCII_TXT));
+ assertNotNull(zf.getEntry(EURO_FOR_DOLLAR_TXT));
+ assertNotNull(zf.getEntry(OIL_BARREL_TXT));
+ } finally {
+ ZipFile.closeQuietly(zf);
+ if (file.exists()) {
+ file.delete();
+ }
}
+ }
+
+ private static void testFileRoundtrip(String encoding, boolean withEFS,
+ boolean withExplicitUnicodeExtra)
+ throws IOException {
File file = File.createTempFile(encoding + "-test", ".zip");
try {
- createTestFile(file, encoding);
+ createTestFile(file, encoding, withEFS, withExplicitUnicodeExtra);
testFile(file, encoding);
} finally {
if (file.exists()) {
@@ -71,19 +110,30 @@
}
}
- private static void createTestFile(File file, String encoding)
+ private static void createTestFile(File file, String encoding,
+ boolean withEFS,
+ boolean withExplicitUnicodeExtra)
throws UnsupportedEncodingException, IOException {
+ ZipEncoding zipEncoding = ZipEncodingHelper.getZipEncoding(encoding);
+
ZipOutputStream zos = null;
try {
zos = new ZipOutputStream(file);
zos.setEncoding(encoding);
+ zos.setUseLanguageEncodingFlag(withEFS);
+ zos.setCreateUnicodeExtraFields(!withExplicitUnicodeExtra);
ZipEntry ze = new ZipEntry(OIL_BARREL_TXT);
- if (!ZipEncodingHelper.canEncodeName(ze.getName(),
- zos.getEncoding())) {
+ if (withExplicitUnicodeExtra
+ && !zipEncoding.canEncode(ze.getName())) {
+
+ ByteBuffer en = zipEncoding.encode(ze.getName());
+
ze.addExtraField(new UnicodePathExtraField(ze.getName(),
- zos.getEncoding()));
+ en.array(),
+ en.arrayOffset(),
+ en.limit()));
}
zos.putNextEntry(ze);
@@ -91,10 +141,15 @@
zos.closeEntry();
ze = new ZipEntry(EURO_FOR_DOLLAR_TXT);
- if (!ZipEncodingHelper.canEncodeName(ze.getName(),
- zos.getEncoding())) {
+ if (withExplicitUnicodeExtra
+ && !zipEncoding.canEncode(ze.getName())) {
+
+ ByteBuffer en = zipEncoding.encode(ze.getName());
+
ze.addExtraField(new UnicodePathExtraField(ze.getName(),
- zos.getEncoding()));
+ en.array(),
+ en.arrayOffset(),
+ en.limit()));
}
zos.putNextEntry(ze);
@@ -103,10 +158,15 @@
ze = new ZipEntry(ASCII_TXT);
- if (!ZipEncodingHelper.canEncodeName(ze.getName(),
- zos.getEncoding())) {
+ if (withExplicitUnicodeExtra
+ && !zipEncoding.canEncode(ze.getName())) {
+
+ ByteBuffer en = zipEncoding.encode(ze.getName());
+
ze.addExtraField(new UnicodePathExtraField(ze.getName(),
- zos.getEncoding()));
+ en.array(),
+ en.arrayOffset(),
+ en.limit()));
}
zos.putNextEntry(ze);
@@ -125,7 +185,7 @@
throws IOException {
ZipFile zf = null;
try {
- zf = new ZipFile(file, encoding);
+ zf = new ZipFile(file, encoding, false);
Enumeration e = zf.getEntries();
while (e.hasMoreElements()) {
@@ -147,14 +207,8 @@
}
private static UnicodePathExtraField findUniCodePath(ZipEntry ze) {
-
- ZipExtraField[] efs = ze.getExtraFields();
- for (int i = 0; i < efs.length; ++i) {
- if (efs[i].getHeaderId().equals(UnicodePathExtraField.UPATH_ID)) {
- return (UnicodePathExtraField) efs[i];
- }
- }
- return null;
+ return (UnicodePathExtraField)
+ ze.getExtraField(UnicodePathExtraField.UPATH_ID);
}
private static void assertUnicodeName(ZipEntry ze,
@@ -165,23 +219,17 @@
UnicodePathExtraField ucpf = findUniCodePath(ze);
assertNotNull(ucpf);
- UnicodePathExtraField ucpe = new UnicodePathExtraField(expectedName,
- encoding);
- assertEquals(ucpe.getNameCRC32(), ucpf.getNameCRC32());
+ ZipEncoding enc = ZipEncodingHelper.getZipEncoding(encoding);
+ ByteBuffer ne = enc.encode(ze.getName());
+
+ CRC32 crc = new CRC32();
+ crc.update(ne.array(),ne.arrayOffset(),ne.limit());
+
+ assertEquals(crc.getValue(), ucpf.getNameCRC32());
assertEquals(expectedName, new String(ucpf.getUnicodeName(),
UTF_8));
}
}
- /*
- public void testUtf8Interoperability() throws IOException {
- File file1 = super.getFile("utf8-7zip-test.zip");
- File file2 = super.getFile("utf8-winzip-test.zip");
-
- testFile(file1,CP437);
- testFile(file2,CP437);
-
- }
- */
}
Propchange: ant/core/trunk/src/tests/junit/org/apache/tools/zip/UTF8ZipFilesTest.java
------------------------------------------------------------------------------
--- svn:mergeinfo (added)
+++ svn:mergeinfo Mon Mar 2 17:17:09 2009
@@ -0,0 +1 @@
+/commons/sandbox/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/UTF8ZipFilesTest.java:749342-749344
Copied: ant/core/trunk/src/tests/junit/org/apache/tools/zip/ZipEncodingTest.java (from r749345, commons/sandbox/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/TestZipEncodings.java)
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/tests/junit/org/apache/tools/zip/ZipEncodingTest.java?p2=ant/core/trunk/src/tests/junit/org/apache/tools/zip/ZipEncodingTest.java&p1=commons/sandbox/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/TestZipEncodings.java&r1=749345&r2=749368&rev=749368&view=diff
==============================================================================
--- commons/sandbox/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/TestZipEncodings.java (original)
+++ ant/core/trunk/src/tests/junit/org/apache/tools/zip/ZipEncodingTest.java Mon Mar 2 17:17:09 2009
@@ -17,7 +17,7 @@
* under the License.
*/
-package org.apache.commons.compress.archivers.zip;
+package org.apache.tools.zip;
import java.io.IOException;
import java.nio.ByteBuffer;
@@ -27,7 +27,7 @@
/**
* Test zip encodings.
*/
-public class TestZipEncodings extends TestCase {
+public class ZipEncodingTest extends TestCase {
private static final String UNENC_STRING = "\u2016";
// stress test for internal grow method.