Author: bodewig Date: Sat Aug 10 17:04:41 2013 New Revision: 1512804 URL: http://svn.apache.org/r1512804 Log: Add encoding support to CPIO package - related to COMPRESS-180
Modified: commons/proper/compress/trunk/src/changes/changes.xml commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/ArchiveStreamFactory.java commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveInputStream.java commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveOutputStream.java commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/utils/ArchiveUtils.java Modified: commons/proper/compress/trunk/src/changes/changes.xml URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/changes/changes.xml?rev=1512804&r1=1512803&r2=1512804&view=diff ============================================================================== --- commons/proper/compress/trunk/src/changes/changes.xml (original) +++ commons/proper/compress/trunk/src/changes/changes.xml Sat Aug 10 17:04:41 2013 @@ -97,7 +97,11 @@ The <action> type attribute can be add,u </action> <action type="add" date="2013-08-10"> DumpArchiveInputStream now supports an encoding parameter that - can be used to specify the default encoding of file names. + can be used to specify the encoding of file names. + </action> + <action type="add" date="2013-08-10"> + The CPIO streams now support an encoding parameter that can be + used to specify the encoding of file names. </action> </release> <release version="1.5" date="2013-03-14" Modified: commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/ArchiveStreamFactory.java URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/ArchiveStreamFactory.java?rev=1512804&r1=1512803&r2=1512804&view=diff ============================================================================== --- commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/ArchiveStreamFactory.java (original) +++ commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/ArchiveStreamFactory.java Sat Aug 10 17:04:41 2013 @@ -116,8 +116,8 @@ public class ArchiveStreamFactory { private String entryEncoding = null; /** - * Returns the encoding to use for arj, zip, dump and tar files, - * or null for the default. + * Returns the encoding to use for arj, zip, dump, cpio and tar + * files, or null for the default. * * @return entry encoding, or null * @since 1.5 @@ -127,8 +127,8 @@ public class ArchiveStreamFactory { } /** - * Sets the encoding to use for arj, zip, dump and tar files. Use - * null for the default. + * Sets the encoding to use for arj, zip, dump, cpio and tar + * files. Use null for the default. * * @since 1.5 */ @@ -185,7 +185,11 @@ public class ArchiveStreamFactory { return new JarArchiveInputStream(in); } if (CPIO.equalsIgnoreCase(archiverName)) { - return new CpioArchiveInputStream(in); + if (entryEncoding != null) { + return new CpioArchiveInputStream(in, entryEncoding); + } else { + return new CpioArchiveInputStream(in); + } } if (DUMP.equalsIgnoreCase(archiverName)) { if (entryEncoding != null) { @@ -238,7 +242,11 @@ public class ArchiveStreamFactory { return new JarArchiveOutputStream(out); } if (CPIO.equalsIgnoreCase(archiverName)) { - return new CpioArchiveOutputStream(out); + if (entryEncoding != null) { + return new CpioArchiveOutputStream(out, entryEncoding); + } else { + return new CpioArchiveOutputStream(out); + } } throw new ArchiveException("Archiver: " + archiverName + " not found."); } Modified: commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveInputStream.java URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveInputStream.java?rev=1512804&r1=1512803&r2=1512804&view=diff ============================================================================== --- commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveInputStream.java (original) +++ commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveInputStream.java Sat Aug 10 17:04:41 2013 @@ -24,7 +24,10 @@ import java.io.InputStream; import org.apache.commons.compress.archivers.ArchiveEntry; import org.apache.commons.compress.archivers.ArchiveInputStream; +import org.apache.commons.compress.archivers.zip.ZipEncoding; +import org.apache.commons.compress.archivers.zip.ZipEncodingHelper; import org.apache.commons.compress.utils.ArchiveUtils; +import org.apache.commons.compress.utils.CharsetNames; /** * CPIOArchiveInputStream is a stream for reading cpio streams. All formats of @@ -85,19 +88,41 @@ public class CpioArchiveInputStream exte private final int blockSize; /** + * The encoding to use for filenames and labels. + */ + private final ZipEncoding encoding; + + /** * Construct the cpio input stream with a blocksize of {@link - * CpioConstants#BLOCK_SIZE BLOCK_SIZE}. + * CpioConstants#BLOCK_SIZE BLOCK_SIZE} and expecting ASCII file + * names. * * @param in * The cpio stream */ public CpioArchiveInputStream(final InputStream in) { - this(in, BLOCK_SIZE); + this(in, BLOCK_SIZE, CharsetNames.US_ASCII); } /** - * Construct the cpio input stream with a blocksize of {@link CpioConstants#BLOCK_SIZE BLOCK_SIZE}. - * Construct the cpio input stream. + * Construct the cpio input stream with a blocksize of {@link + * CpioConstants#BLOCK_SIZE BLOCK_SIZE}. + * + * @param in + * The cpio stream + * @param encoding + * The encoding of file names to expect - use null for + * the platform's default. + * @since 1.6 + */ + public CpioArchiveInputStream(final InputStream in, String encoding) { + this(in, BLOCK_SIZE, encoding); + } + + /** + * Construct the cpio input stream with a blocksize of {@link + * CpioConstants#BLOCK_SIZE BLOCK_SIZE} expecting ASCII file + * names. * * @param in * The cpio stream @@ -106,8 +131,25 @@ public class CpioArchiveInputStream exte * @since 1.5 */ public CpioArchiveInputStream(final InputStream in, int blockSize) { + this(in, blockSize, CharsetNames.US_ASCII); + } + + /** + * Construct the cpio input stream with a blocksize of {@link CpioConstants#BLOCK_SIZE BLOCK_SIZE}. + * + * @param in + * The cpio stream + * @param blockSize + * The block size of the archive. + * @param encoding + * The encoding of file names to expect - use null for + * the platform's default. + * @since 1.6 + */ + public CpioArchiveInputStream(final InputStream in, int blockSize, String encoding) { this.in = in; this.blockSize = blockSize; + this.encoding = ZipEncodingHelper.getZipEncoding(encoding); } /** @@ -405,9 +447,11 @@ public class CpioArchiveInputStream exte } private String readCString(final int length) throws IOException { - byte tmpBuffer[] = new byte[length]; + // don't include trailing NUL in file name to decode + byte tmpBuffer[] = new byte[length - 1]; readFully(tmpBuffer, 0, tmpBuffer.length); - return new String(tmpBuffer, 0, tmpBuffer.length - 1); // TODO default charset? + this.in.read(); + return encoding.decode(tmpBuffer); } /** Modified: commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveOutputStream.java URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveOutputStream.java?rev=1512804&r1=1512803&r2=1512804&view=diff ============================================================================== --- commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveOutputStream.java (original) +++ commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveOutputStream.java Sat Aug 10 17:04:41 2013 @@ -21,11 +21,15 @@ package org.apache.commons.compress.arch import java.io.File; import java.io.IOException; import java.io.OutputStream; +import java.nio.ByteBuffer; import java.util.HashMap; import org.apache.commons.compress.archivers.ArchiveEntry; import org.apache.commons.compress.archivers.ArchiveOutputStream; +import org.apache.commons.compress.archivers.zip.ZipEncoding; +import org.apache.commons.compress.archivers.zip.ZipEncodingHelper; import org.apache.commons.compress.utils.ArchiveUtils; +import org.apache.commons.compress.utils.CharsetNames; /** * CPIOArchiveOutputStream is a stream for writing CPIO streams. All formats of @@ -87,8 +91,14 @@ public class CpioArchiveOutputStream ext private long nextArtificalDeviceAndInode = 1; /** - * Construct the cpio output stream with a specified format and a - * blocksize of {@link CpioConstants#BLOCK_SIZE BLOCK_SIZE}. + * The encoding to use for filenames and labels. + */ + private final ZipEncoding encoding; + + /** + * Construct the cpio output stream with a specified format, a + * blocksize of {@link CpioConstants#BLOCK_SIZE BLOCK_SIZE} and + * using ASCII as the file name encoding. * * @param out * The cpio stream @@ -96,11 +106,12 @@ public class CpioArchiveOutputStream ext * The format of the stream */ public CpioArchiveOutputStream(final OutputStream out, final short format) { - this(out, format, BLOCK_SIZE); + this(out, format, BLOCK_SIZE, CharsetNames.US_ASCII); } /** - * Construct the cpio output stream with a specified format + * Construct the cpio output stream with a specified format using + * ASCII as the file name encoding. * * @param out * The cpio stream @@ -113,6 +124,27 @@ public class CpioArchiveOutputStream ext */ public CpioArchiveOutputStream(final OutputStream out, final short format, final int blockSize) { + this(out, format, blockSize, CharsetNames.US_ASCII); + } + + /** + * Construct the cpio output stream with a specified format using + * ASCII as the file name encoding. + * + * @param out + * The cpio stream + * @param format + * The format of the stream + * @param blockSize + * The block size of the archive. + * @param encoding + * The encoding of file names to write - use null for + * the platform's default. + * + * @since 1.6 + */ + public CpioArchiveOutputStream(final OutputStream out, final short format, + final int blockSize, final String encoding) { this.out = out; switch (format) { case FORMAT_NEW: @@ -126,11 +158,12 @@ public class CpioArchiveOutputStream ext } this.entryFormat = format; this.blockSize = blockSize; + this.encoding = ZipEncodingHelper.getZipEncoding(encoding); } /** * Construct the cpio output stream. The format for this CPIO stream is the - * "new" format + * "new" format using ASCII encoding for file names * * @param out * The cpio stream @@ -140,6 +173,21 @@ public class CpioArchiveOutputStream ext } /** + * Construct the cpio output stream. The format for this CPIO stream is the + * "new" format. + * + * @param out + * The cpio stream + * @param encoding + * The encoding of file names to write - use null for + * the platform's default. + * @since 1.6 + */ + public CpioArchiveOutputStream(final OutputStream out, String encoding) { + this(out, FORMAT_NEW, BLOCK_SIZE, encoding); + } + + /** * Check to make sure that this stream has not been closed * * @throws IOException @@ -485,10 +533,11 @@ public class CpioArchiveOutputStream ext * @throws IOException if the string couldn't be written */ private void writeCString(final String str) throws IOException { - byte[] b = ArchiveUtils.toAsciiBytes(str); - out.write(b); + ByteBuffer buf = encoding.encode(str); + final int len = buf.limit() - buf.position(); + out.write(buf.array(), buf.arrayOffset(), len); out.write('\0'); - count(b.length + 1); + count(len + 1); } /** Modified: commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/utils/ArchiveUtils.java URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/utils/ArchiveUtils.java?rev=1512804&r1=1512803&r2=1512804&view=diff ============================================================================== --- commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/utils/ArchiveUtils.java (original) +++ commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/utils/ArchiveUtils.java Sat Aug 10 17:04:41 2013 @@ -67,7 +67,7 @@ public class ArchiveUtils { String expected, byte[] buffer, int offset, int length){ byte[] buffer1; try { - buffer1 = expected.getBytes("ASCII"); + buffer1 = expected.getBytes(CharsetNames.US_ASCII); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); // Should not happen } @@ -94,7 +94,7 @@ public class ArchiveUtils { */ public static byte[] toAsciiBytes(String inputString){ try { - return inputString.getBytes("ASCII"); + return inputString.getBytes(CharsetNames.US_ASCII); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); // Should never happen } @@ -108,7 +108,7 @@ public class ArchiveUtils { */ public static String toAsciiString(final byte[] inputBytes){ try { - return new String(inputBytes, "ASCII"); + return new String(inputBytes, CharsetNames.US_ASCII); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); // Should never happen } @@ -124,7 +124,7 @@ public class ArchiveUtils { */ public static String toAsciiString(final byte[] inputBytes, int offset, int length){ try { - return new String(inputBytes, offset, length, "ASCII"); + return new String(inputBytes, offset, length, CharsetNames.US_ASCII); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); // Should never happen }