You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by bo...@apache.org on 2009/03/04 06:21:19 UTC

svn commit: r749907 - /commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java

Author: bodewig
Date: Wed Mar  4 05:21:19 2009
New Revision: 749907

URL: http://svn.apache.org/viewvc?rev=749907&view=rev
Log:
Add option to use UTF-8 for non-encodable file names.  SANDBOX-176

Modified:
    commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java

Modified: commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java
URL: http://svn.apache.org/viewvc/commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java?rev=749907&r1=749906&r2=749907&view=diff
==============================================================================
--- commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java (original)
+++ commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java Wed Mar  4 05:21:19 2009
@@ -229,6 +229,11 @@
     private boolean useEFS = true; 
 
     /**
+     * Whether to encode non-encodable file names as UTF-8.
+     */
+    private boolean fallbackToUTF8 = false;
+
+    /**
      * whether to create UnicodePathExtraField-s for each entry.
      */
     private UnicodeExtraFieldPolicy createUnicodeExtraFields =
@@ -324,6 +329,16 @@
     }
 
     /**
+     * Whether to fall back to UTF and the language encoding flag if
+     * the file name cannot be encoded using the specified encoding.
+     *
+     * <p>Defaults to false.</p>
+     */
+    public void setFallbackToUTF8(boolean b) {
+        fallbackToUTF8 = b;
+    }
+
+    /**
      * Finishs writing the contents and closes this as well as the
      * underlying stream.
      * @throws IOException on error
@@ -613,8 +628,13 @@
      */
     protected void writeLocalFileHeader(ZipArchiveEntry ze) throws IOException {
 
-        boolean encodable = this.zipEncoding.canEncode(ze.getName());
-        ByteBuffer name = this.zipEncoding.encode(ze.getName());
+        boolean encodable = zipEncoding.canEncode(ze.getName());
+        ByteBuffer name;
+        if (!encodable && fallbackToUTF8) {
+            name = ZipEncodingHelper.UTF8_ZIP_ENCODING.encode(ze.getName());
+        } else {
+            name = zipEncoding.encode(ze.getName());
+        }
 
         if (createUnicodeExtraFields != UnicodeExtraFieldPolicy.NEVER) {
 
@@ -651,7 +671,9 @@
         //store method in local variable to prevent multiple method calls
         final int zipMethod = ze.getMethod();
 
-        writeVersionNeededToExtractAndGeneralPurposeBits(zipMethod);
+        writeVersionNeededToExtractAndGeneralPurposeBits(zipMethod,
+                                                         !encodable
+                                                         && fallbackToUTF8);
         written += WORD;
 
         // compression method
@@ -732,7 +754,10 @@
         written += SHORT;
 
         final int zipMethod = ze.getMethod();
-        writeVersionNeededToExtractAndGeneralPurposeBits(zipMethod);
+        final boolean encodable = zipEncoding.canEncode(ze.getName());
+        writeVersionNeededToExtractAndGeneralPurposeBits(zipMethod,
+                                                         !encodable
+                                                         && fallbackToUTF8);
         written += WORD;
 
         // compression method
@@ -754,7 +779,12 @@
         // CheckStyle:MagicNumber ON
 
         // file name length
-        ByteBuffer name = this.zipEncoding.encode(ze.getName());
+        ByteBuffer name;
+        if (!encodable && fallbackToUTF8) {
+            name = ZipEncodingHelper.UTF8_ZIP_ENCODING.encode(ze.getName());
+        } else {
+            name = zipEncoding.encode(ze.getName());
+        }
         writeOut(ZipShort.getBytes(name.limit()));
         written += SHORT;
 
@@ -768,7 +798,12 @@
         if (comm == null) {
             comm = "";
         }
-        ByteBuffer commentB = this.zipEncoding.encode(comm);
+        ByteBuffer commentB;
+        if (!encodable && fallbackToUTF8) {
+            commentB = ZipEncodingHelper.UTF8_ZIP_ENCODING.encode(comm);
+        } else {
+            commentB = zipEncoding.encode(comm);
+        }
         writeOut(ZipShort.getBytes(commentB.limit()));
         written += SHORT;
 
@@ -913,12 +948,14 @@
     }
 
     private void writeVersionNeededToExtractAndGeneralPurposeBits(final int
-                                                                  zipMethod)
+                                                                  zipMethod,
+                                                                  final boolean
+                                                                  utfFallback)
         throws IOException {
 
         // CheckStyle:MagicNumber OFF
         int versionNeededToExtract = 10;
-        int generalPurposeFlag = useEFS ? EFS_FLAG : 0;
+        int generalPurposeFlag = (useEFS || utfFallback) ? EFS_FLAG : 0;
         if (zipMethod == DEFLATED && raf == null) {
             // requires version 2 as we are going to store length info
             // in the data descriptor