Author: bodewig
Date: Wed Nov  2 16:13:41 2011
New Revision: 1196665

URL: http://svn.apache.org/viewvc?rev=1196665&view=rev
Log:
support for XZ compression format submitted by Lasse Collin.  COMPRESS-156

Added:
    
commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/xz/
    
commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/xz/XZCompressorInputStream.java
   (with props)
    
commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/xz/XZCompressorOutputStream.java
   (with props)
Modified:
    commons/proper/compress/trunk/pom.xml
    
commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/CompressorStreamFactory.java

Modified: commons/proper/compress/trunk/pom.xml
URL: 
http://svn.apache.org/viewvc/commons/proper/compress/trunk/pom.xml?rev=1196665&r1=1196664&r2=1196665&view=diff
==============================================================================
--- commons/proper/compress/trunk/pom.xml (original)
+++ commons/proper/compress/trunk/pom.xml Wed Nov  2 16:13:41 2011
@@ -56,6 +56,11 @@
       <version>4.10</version>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.tukaani</groupId>
+      <artifactId>xz</artifactId>
+      <version>1.0</version>
+    </dependency>
   </dependencies>
 
   <developers>

Modified: 
commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/CompressorStreamFactory.java
URL: 
http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/CompressorStreamFactory.java?rev=1196665&r1=1196664&r2=1196665&view=diff
==============================================================================
--- 
commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/CompressorStreamFactory.java
 (original)
+++ 
commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/CompressorStreamFactory.java
 Wed Nov  2 16:13:41 2011
@@ -26,6 +26,8 @@ import org.apache.commons.compress.compr
 import 
org.apache.commons.compress.compressors.bzip2.BZip2CompressorOutputStream;
 import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
 import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream;
+import org.apache.commons.compress.compressors.xz.XZCompressorInputStream;
+import org.apache.commons.compress.compressors.xz.XZCompressorOutputStream;
 import 
org.apache.commons.compress.compressors.pack200.Pack200CompressorInputStream;
 import 
org.apache.commons.compress.compressors.pack200.Pack200CompressorOutputStream;
 
@@ -62,6 +64,7 @@ public class CompressorStreamFactory {
      * @since Commons Compress 1.1
      */
     public static final String BZIP2 = "bzip2";
+
     /**
      * Constant used to identify the GZIP compression algorithm.
      * @since Commons Compress 1.1
@@ -74,6 +77,12 @@ public class CompressorStreamFactory {
     public static final String PACK200 = "pack200";
 
     /**
+     * Constant used to identify the XZ compression method.
+     * @since Commons Compress 1.4
+     */
+    public static final String XZ = "xz";
+
+    /**
      * Create an compressor input stream from an input stream, autodetecting
      * the compressor type from the first few bytes of the stream. The 
InputStream
      * must support marks, like BufferedInputStream.
@@ -108,6 +117,10 @@ public class CompressorStreamFactory {
                 return new GzipCompressorInputStream(in);
             }
 
+            if (XZCompressorInputStream.matches(signature, signatureLength)) {
+                return new XZCompressorInputStream(in);
+            }
+
             if (Pack200CompressorInputStream.matches(signature, 
signatureLength)) {
                 return new Pack200CompressorInputStream(in);
             }
@@ -122,7 +135,7 @@ public class CompressorStreamFactory {
     /**
      * Create a compressor input stream from a compressor name and an input 
stream.
      * 
-     * @param name of the compressor, i.e. "gz", "bzip2" or "pack200"
+     * @param name of the compressor, i.e. "gz", "bzip2", "xz", or "pack200"
      * @param in the input stream
      * @return compressor input stream
      * @throws CompressorException if the compressor name is not known
@@ -145,6 +158,10 @@ public class CompressorStreamFactory {
                 return new BZip2CompressorInputStream(in);
             }
 
+            if (XZ.equalsIgnoreCase(name)) {
+                return new XZCompressorInputStream(in);
+            }
+
             if (PACK200.equalsIgnoreCase(name)) {
                 return new Pack200CompressorInputStream(in);
             }
@@ -159,7 +176,7 @@ public class CompressorStreamFactory {
     /**
      * Create an compressor output stream from an compressor name and an input 
stream.
      * 
-     * @param name the compressor name, i.e. "gz", "bzip2" or "pack200"
+     * @param name the compressor name, i.e. "gz", "bzip2", "xz", or "pack200"
      * @param out the output stream
      * @return the compressor output stream
      * @throws CompressorException if the archiver name is not known
@@ -183,6 +200,10 @@ public class CompressorStreamFactory {
                 return new BZip2CompressorOutputStream(out);
             }
 
+            if (XZ.equalsIgnoreCase(name)) {
+                return new XZCompressorOutputStream(out);
+            }
+
             if (PACK200.equalsIgnoreCase(name)) {
                 return new Pack200CompressorOutputStream(out);
             }

Added: 
commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/xz/XZCompressorInputStream.java
URL: 
http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/xz/XZCompressorInputStream.java?rev=1196665&view=auto
==============================================================================
--- 
commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/xz/XZCompressorInputStream.java
 (added)
+++ 
commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/xz/XZCompressorInputStream.java
 Wed Nov  2 16:13:41 2011
@@ -0,0 +1,125 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.commons.compress.compressors.xz;
+
+import java.io.IOException;
+import java.io.InputStream;
+import org.tukaani.xz.XZ;
+import org.tukaani.xz.SingleXZInputStream;
+import org.tukaani.xz.XZInputStream;
+
+import org.apache.commons.compress.compressors.CompressorInputStream;
+
+/**
+ * XZ decompressor.
+ * @since Commons Compress 1.4
+ */
+public class XZCompressorInputStream extends CompressorInputStream {
+    private final InputStream in;
+
+    /**
+     * Checks if the signature matches what is expected for a .xz file.
+     *
+     * @param   signature     the bytes to check
+     * @param   length        the number of bytes to check
+     * @return  true if signature matches the .xz magic bytes, false otherwise
+     */
+    public static boolean matches(byte[] signature, int length) {
+        if (length < XZ.HEADER_MAGIC.length)
+            return false;
+
+        for (int i = 0; i < XZ.HEADER_MAGIC.length; ++i)
+            if (signature[i] != XZ.HEADER_MAGIC[i])
+                return false;
+
+        return true;
+    }
+
+    /**
+     * Creates a new input stream that decompresses XZ-compressed data
+     * from the specified input stream. This supports concatenated .xz files.
+     *
+     * @param       inputStream where to read the compressed data
+     *
+     * @throws      IOException if the input is not in the .xz format,
+     *                          the input is corrupt or truncated, the .xz
+     *                          headers specify options that are not supported
+     *                          by this implementation, or the underlying
+     *                          <code>inputStream</code> throws an exception
+     */
+    public XZCompressorInputStream(InputStream inputStream)
+            throws IOException {
+        this(inputStream, true);
+    }
+
+    /**
+     * Creates a new input stream that decompresses XZ-compressed data
+     * from the specified input stream.
+     *
+     * @param       inputStream where to read the compressed data
+     * @param       decompressConcatenated
+     *                          if true, decompress until the end of the
+     *                          input; if false, stop after the first .xz
+     *                          stream and leave the input position to point
+     *                          to the next byte after the .xz stream
+     *
+     * @throws      IOException if the input is not in the .xz format,
+     *                          the input is corrupt or truncated, the .xz
+     *                          headers specify options that are not supported
+     *                          by this implementation, or the underlying
+     *                          <code>inputStream</code> throws an exception
+     */
+    public XZCompressorInputStream(InputStream inputStream,
+                                   boolean decompressConcatenated)
+            throws IOException {
+        if (decompressConcatenated)
+            in = new XZInputStream(inputStream);
+        else
+            in = new SingleXZInputStream(inputStream);
+    }
+
+    /** {@inheritDoc} */
+    public int read() throws IOException {
+        int ret = in.read();
+        count(ret == -1 ? -1 : 1);
+        return ret;
+    }
+
+    /** {@inheritDoc} */
+    public int read(byte[] buf, int off, int len) throws IOException {
+        int ret = in.read(buf, off, len);
+        count(ret);
+        return ret;
+    }
+
+    /** {@inheritDoc} */
+    public long skip(long n) throws IOException {
+        return in.skip(n);
+    }
+
+    /** {@inheritDoc} */
+    public int available() throws IOException {
+        return in.available();
+    }
+
+    /** {@inheritDoc} */
+    public void close() throws IOException {
+        in.close();
+    }
+}

Propchange: 
commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/xz/XZCompressorInputStream.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/xz/XZCompressorOutputStream.java
URL: 
http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/xz/XZCompressorOutputStream.java?rev=1196665&view=auto
==============================================================================
--- 
commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/xz/XZCompressorOutputStream.java
 (added)
+++ 
commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/xz/XZCompressorOutputStream.java
 Wed Nov  2 16:13:41 2011
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.commons.compress.compressors.xz;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import org.tukaani.xz.LZMA2Options;
+import org.tukaani.xz.XZOutputStream;
+
+import org.apache.commons.compress.compressors.CompressorOutputStream;
+
+/**
+ * XZ compressor.
+ * @since Commons Compress 1.4
+ */
+public class XZCompressorOutputStream extends CompressorOutputStream {
+    private final XZOutputStream out;
+
+    /**
+     * Creates a new XZ compressor using the default LZMA2 options.
+     * This is equivalent to <code>XZCompressorOutputStream(6)</code>.
+     */
+    public XZCompressorOutputStream(OutputStream outputStream)
+            throws IOException {
+        out = new XZOutputStream(outputStream, new LZMA2Options());
+    }
+
+    /**
+     * Creates a new XZ compressor using the specified LZMA2 preset level.
+     * <p>
+     * The presets 0-3 are fast presets with medium compression.
+     * The presets 4-6 are fairly slow presets with high compression.
+     * The default preset is 6.
+     * <p>
+     * The presets 7-9 are like the preset 6 but use bigger dictionaries
+     * and have higher compressor and decompressor memory requirements.
+     * Unless the uncompressed size of the file exceeds 8&nbsp;MiB,
+     * 16&nbsp;MiB, or 32&nbsp;MiB, it is waste of memory to use the
+     * presets 7, 8, or 9, respectively.
+     */
+    public XZCompressorOutputStream(OutputStream outputStream, int preset)
+            throws IOException {
+        out = new XZOutputStream(outputStream, new LZMA2Options(preset));
+    }
+
+    /** {@inheritDoc} */
+    public void write(int b) throws IOException {
+        out.write(b);
+    }
+
+    /** {@inheritDoc} */
+    public void write(byte[] buf, int off, int len) throws IOException {
+        out.write(buf, off, len);
+    }
+
+    /**
+     * Flushes the encoder and calls <code>outputStream.flush()</code>.
+     * All buffered pending data will then be decompressible from
+     * the output stream. Calling this function very often may increase
+     * the compressed file size a lot.
+     */
+    public void flush() throws IOException {
+        out.flush();
+    }
+
+    /**
+     * Finishes compression without closing the underlying stream.
+     * No more data can be written to this stream after finishing.
+     */
+    public void finish() throws IOException {
+        out.finish();
+    }
+
+    /** {@inheritDoc} */
+    public void close() throws IOException {
+        out.close();
+    }
+}

Propchange: 
commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/xz/XZCompressorOutputStream.java
------------------------------------------------------------------------------
    svn:eol-style = native


Reply via email to