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