]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.fastlz/testcases/org/simantics/fastlz/FastLZBasicTests.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.fastlz / testcases / org / simantics / fastlz / FastLZBasicTests.java
index 572ee11890a095a461a46538c5e0c171498c146b..0d6325fa90f0c677437ef884aee5edccf633e071 100644 (file)
-/*******************************************************************************\r
-t * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
- * in Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- *     VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
+/*******************************************************************************
+t * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
 package org.simantics.fastlz;
 
-import static org.junit.Assert.fail;\r
-\r
-import java.io.BufferedInputStream;\r
-import java.io.BufferedOutputStream;\r
-import java.io.File;\r
-import java.io.FileInputStream;\r
-import java.io.FileOutputStream;\r
-import java.io.IOException;\r
-import java.io.InputStream;\r
-import java.io.OutputStream;\r
-import java.util.Arrays;\r
-\r
-import junit.framework.Assert;\r
-\r
-import org.junit.BeforeClass;\r
-import org.junit.Test;\r
-
-/**\r
- * @author Tuukka Lehtonen\r
- */\r
-@SuppressWarnings("deprecation")\r
-public class FastLZBasicTests {\r
-\r
-    static File testData1;\r
-    static File testData2;\r
-    static File testDataPrime;\r
-\r
-    @BeforeClass\r
-    public static void initialize() throws IOException {\r
-        FastLZ.initialize(null);\r
-\r
-        testData1 = new File("uncompressed.data");\r
-        writeTestData(testData1, 10000000);\r
-        testData2 = new File("uncompressed-small.data");\r
-        writeTestData(testData2, 100000);\r
-        testDataPrime = new File("uncompressed-prime.data");\r
-        writeTestData(testDataPrime, 1000);\r
-\r
-        System.out.println("test data directory: " + testData1.getAbsolutePath());\r
-\r
-//        File javaFlz = new File("compressed-prime.data.native.flz");\r
-//        for (int i = 0; i < 100; ++i) {\r
-//            compressFlzJava(testDataPrime, javaFlz);\r
-//        }\r
-    }\r
-\r
-    @Test\r
-    public void validateCompress() throws IOException {\r
-        validateCompress(testData1);\r
-    }\r
-\r
-    private void validateCompress(File testData) throws IOException {\r
-        System.out.println("==== validateCompress(" + testData.getName() + ") ====");\r
-\r
-        File nativeFlz = new File("compressed.data.native.flz");\r
-        long nativeCompressedSize = compressFlzNative(testData, nativeFlz);\r
-        System.out.println("native compressed size: " + nativeCompressedSize);\r
-\r
-        // Need to prime JVM JIT by performing multiple passes\r
-        File javaFlz = new File("compressed.data.java.flz");\r
-        long javaCompressedSize = compressFlzJava(testData, javaFlz);\r
-        System.out.println("java compressed size: " + javaCompressedSize);\r
-\r
-        Assert.assertEquals(nativeCompressedSize, javaCompressedSize);\r
-\r
-        System.out.println("Comparing compressed outputs...");\r
-        compareFiles(nativeFlz, javaFlz);\r
-        System.out.println("Compressed outputs match.");\r
-\r
-        File decompressedNativeFlz = new File("decompressed.data.native.flz");\r
-        File decompressedJavaFlz = new File("decompressed.data.java.flz");\r
-        decompressFlzNative(nativeFlz, decompressedNativeFlz);\r
-        decompressFlzNative(javaFlz, decompressedJavaFlz);\r
-        compareFiles(decompressedJavaFlz, decompressedNativeFlz);\r
-        compareFiles(decompressedNativeFlz, testData);\r
-    }\r
-\r
-//    @Test\r
-//    public void validateCompressSmall() throws IOException {\r
-//        File nativeFlz = new File("compressed-small.data.native.flz");\r
-//        long nativeCompressedSize = compressFlzNative(testData2, nativeFlz);\r
-//        System.out.println("native compressed size: " + nativeCompressedSize);\r
-//\r
-//        // Need to prime JVM JIT by performing multiple passes\r
-//        File javaFlz = new File("compressed-small.data.java.flz");\r
-//        long javaCompressedSize = compressFlzJava(testData2, javaFlz);\r
-//        System.out.println("java compressed size: " + javaCompressedSize);\r
-//\r
-//        Assert.assertEquals(nativeCompressedSize, javaCompressedSize);\r
-//\r
-//        System.out.println("Comparing compressed outputs...");\r
-//        compareFiles(nativeFlz, javaFlz);\r
-//        System.out.println("Compressed outputs match.");\r
-//    }\r
-\r
-//    @Test\r
-//    public void testNativeCompressPerformance() throws IOException {\r
-//        File javaFlz = new File("compressed.data.native.flz");\r
-//        for (int i = 0; i < 5; ++i) {\r
-//            compressFlzNative(testData1, javaFlz);\r
-//        }\r
-//    }\r
-//\r
-//    @Test\r
-//    public void testJavaCompressPerformance() throws IOException {\r
-//        // Need to prime JVM JIT by performing multiple passes\r
-//        File javaFlz = new File("compressed.data.java.flz");\r
-//        for (int i = 0; i < 5; ++i) {\r
-//            compressFlzJava(testData1, javaFlz);\r
-//        }\r
-//    }\r
-\r
-//    @Test\r
-//    public void testCompressNative() throws IOException {\r
-//        File flz = new File("compressed.data.native.flz");\r
-//        for (int i = 0; i < 5; ++i) {\r
-//            long compressedSize = compressFlzNative(testData1, flz);\r
-//            System.out.println("native compressed size: " + compressedSize);\r
-//        }\r
-//    }\r
-//\r
-//    @Test\r
-//    public void testCompressionJava() throws IOException {\r
-//        // Need to prime JVM JIT by performing multiple passes\r
-//        File flz = new File("compressed.data.java.flz");\r
-//        for (int i = 0; i < 5; ++i) {\r
-//            long compressedSize = compressFlzJava(testData1, flz);\r
-//            System.out.println("java compressed size: " + compressedSize);\r
-//        }\r
-//    }\r
-\r
-    @SuppressWarnings("unused")\r
-    @Test\r
-    public void testDecompress() throws IOException {\r
-        File nativeFlz = new File("compressed.data.native.flz");\r
-        long nativeCompressedSize = compressFlzNative(testData1, nativeFlz);\r
-        System.out.println("native compressed size: " + nativeCompressedSize);\r
-\r
-        // Need to prime JVM JIT by performing multiple passes\r
-        File javaFlz = new File("compressed.data.java.flz");\r
-        long javaCompressedSize = compressFlzJava(testData1, javaFlz);\r
-        System.out.println("java compressed size: " + javaCompressedSize);\r
-\r
-        Assert.assertEquals(nativeCompressedSize, javaCompressedSize);\r
-\r
-        System.out.println("Comparing compressed outputs...");\r
-        compareFiles(nativeFlz, javaFlz);\r
-        System.out.println("Compressed outputs match.");\r
-\r
-        File java1 = new File("java-compressed.data.decompressed-with-native");\r
-        long nativeDecompressedSize = decompressFlzNative(javaFlz, java1);\r
-        System.out.println("Comparing native-decompressed output...");\r
-        compareFiles(testData1, java1);\r
-        System.out.println("Native-decompressed output matches original.");\r
-\r
-        File java2 = new File("java-compressed.data.decompressed-with-java");\r
-        long javaDecompressedSize = decompressFlzJava(javaFlz, java2);\r
-        System.out.println("Comparing java-decompressed output...");\r
-        compareFiles(testData1, java2);\r
-        System.out.println("Java-decompressed output matches original.");\r
-\r
-        for (int i = 0; i < 5; ++i)\r
-            decompressFlz(javaFlz, FastLZ.read(javaFlz), java1, NullOutputStream.INSTANCE);\r
-        for (int i = 0; i < 5; ++i)\r
-            decompressFlz(javaFlz, FastLZJava.read(javaFlz), java2, NullOutputStream.INSTANCE);\r
-    }\r
-\r
+import static org.junit.Assert.fail;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Arrays;
+
+import junit.framework.Assert;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * @author Tuukka Lehtonen
+ */
+@SuppressWarnings("deprecation")
+public class FastLZBasicTests {
+
+    static File testData1;
+    static File testData2;
+    static File testDataPrime;
+
+    @BeforeClass
+    public static void initialize() throws IOException {
+        FastLZ.initialize(null);
+
+        testData1 = new File("uncompressed.data");
+        writeTestData(testData1, 10000000);
+        testData2 = new File("uncompressed-small.data");
+        writeTestData(testData2, 100000);
+        testDataPrime = new File("uncompressed-prime.data");
+        writeTestData(testDataPrime, 1000);
+
+        System.out.println("test data directory: " + testData1.getAbsolutePath());
+
+//        File javaFlz = new File("compressed-prime.data.native.flz");
+//        for (int i = 0; i < 100; ++i) {
+//            compressFlzJava(testDataPrime, javaFlz);
+//        }
+    }
+
+    @Test
+    public void validateCompress() throws IOException {
+        validateCompress(testData1);
+    }
+
+    private void validateCompress(File testData) throws IOException {
+        System.out.println("==== validateCompress(" + testData.getName() + ") ====");
+
+        File nativeFlz = new File("compressed.data.native.flz");
+        long nativeCompressedSize = compressFlzNative(testData, nativeFlz);
+        System.out.println("native compressed size: " + nativeCompressedSize);
+
+        // Need to prime JVM JIT by performing multiple passes
+        File javaFlz = new File("compressed.data.java.flz");
+        long javaCompressedSize = compressFlzJava(testData, javaFlz);
+        System.out.println("java compressed size: " + javaCompressedSize);
+
+        Assert.assertEquals(nativeCompressedSize, javaCompressedSize);
+
+        System.out.println("Comparing compressed outputs...");
+        compareFiles(nativeFlz, javaFlz);
+        System.out.println("Compressed outputs match.");
+
+        File decompressedNativeFlz = new File("decompressed.data.native.flz");
+        File decompressedJavaFlz = new File("decompressed.data.java.flz");
+        decompressFlzNative(nativeFlz, decompressedNativeFlz);
+        decompressFlzNative(javaFlz, decompressedJavaFlz);
+        compareFiles(decompressedJavaFlz, decompressedNativeFlz);
+        compareFiles(decompressedNativeFlz, testData);
+    }
+
+//    @Test
+//    public void validateCompressSmall() throws IOException {
+//        File nativeFlz = new File("compressed-small.data.native.flz");
+//        long nativeCompressedSize = compressFlzNative(testData2, nativeFlz);
+//        System.out.println("native compressed size: " + nativeCompressedSize);
+//
+//        // Need to prime JVM JIT by performing multiple passes
+//        File javaFlz = new File("compressed-small.data.java.flz");
+//        long javaCompressedSize = compressFlzJava(testData2, javaFlz);
+//        System.out.println("java compressed size: " + javaCompressedSize);
+//
+//        Assert.assertEquals(nativeCompressedSize, javaCompressedSize);
+//
+//        System.out.println("Comparing compressed outputs...");
+//        compareFiles(nativeFlz, javaFlz);
+//        System.out.println("Compressed outputs match.");
+//    }
+
+//    @Test
+//    public void testNativeCompressPerformance() throws IOException {
+//        File javaFlz = new File("compressed.data.native.flz");
+//        for (int i = 0; i < 5; ++i) {
+//            compressFlzNative(testData1, javaFlz);
+//        }
+//    }
+//
+//    @Test
+//    public void testJavaCompressPerformance() throws IOException {
+//        // Need to prime JVM JIT by performing multiple passes
+//        File javaFlz = new File("compressed.data.java.flz");
+//        for (int i = 0; i < 5; ++i) {
+//            compressFlzJava(testData1, javaFlz);
+//        }
+//    }
+
+//    @Test
+//    public void testCompressNative() throws IOException {
+//        File flz = new File("compressed.data.native.flz");
+//        for (int i = 0; i < 5; ++i) {
+//            long compressedSize = compressFlzNative(testData1, flz);
+//            System.out.println("native compressed size: " + compressedSize);
+//        }
+//    }
+//
+//    @Test
+//    public void testCompressionJava() throws IOException {
+//        // Need to prime JVM JIT by performing multiple passes
+//        File flz = new File("compressed.data.java.flz");
+//        for (int i = 0; i < 5; ++i) {
+//            long compressedSize = compressFlzJava(testData1, flz);
+//            System.out.println("java compressed size: " + compressedSize);
+//        }
+//    }
+
+    @SuppressWarnings("unused")
+    @Test
+    public void testDecompress() throws IOException {
+        File nativeFlz = new File("compressed.data.native.flz");
+        long nativeCompressedSize = compressFlzNative(testData1, nativeFlz);
+        System.out.println("native compressed size: " + nativeCompressedSize);
+
+        // Need to prime JVM JIT by performing multiple passes
+        File javaFlz = new File("compressed.data.java.flz");
+        long javaCompressedSize = compressFlzJava(testData1, javaFlz);
+        System.out.println("java compressed size: " + javaCompressedSize);
+
+        Assert.assertEquals(nativeCompressedSize, javaCompressedSize);
+
+        System.out.println("Comparing compressed outputs...");
+        compareFiles(nativeFlz, javaFlz);
+        System.out.println("Compressed outputs match.");
+
+        File java1 = new File("java-compressed.data.decompressed-with-native");
+        long nativeDecompressedSize = decompressFlzNative(javaFlz, java1);
+        System.out.println("Comparing native-decompressed output...");
+        compareFiles(testData1, java1);
+        System.out.println("Native-decompressed output matches original.");
+
+        File java2 = new File("java-compressed.data.decompressed-with-java");
+        long javaDecompressedSize = decompressFlzJava(javaFlz, java2);
+        System.out.println("Comparing java-decompressed output...");
+        compareFiles(testData1, java2);
+        System.out.println("Java-decompressed output matches original.");
+
+        for (int i = 0; i < 5; ++i)
+            decompressFlz(javaFlz, FastLZ.read(javaFlz), java1, NullOutputStream.INSTANCE);
+        for (int i = 0; i < 5; ++i)
+            decompressFlz(javaFlz, FastLZJava.read(javaFlz), java2, NullOutputStream.INSTANCE);
+    }
+
     @Test
     public void testDecompressCluster() {
         fail("Not yet implemented");
     }
-\r
-    static void compareFiles(File file1, File file2) throws IOException {\r
-        InputStream in1 = new BufferedInputStream(new FileInputStream(file1));\r
-        InputStream in2 = new BufferedInputStream(new FileInputStream(file2));\r
-        try {\r
-            int offset = 0;\r
-            while (true) {\r
-                int b1 = in1.read();\r
-                int b2 = in2.read();\r
-                if (b1 == -1 && b2 == -1)\r
-                    return;\r
-                if (b1 == -1)\r
-                    fail("EOF reached in file1 " + file1.getName() + " but not in file2 " + file2.getName());\r
-                if (b2 == -1)\r
-                    fail("EOF reached in file1 " + file1.getName() + " but not in file2 " + file2.getName());\r
-                if (b1 != b2)\r
-                    fail("bytes at offset " + offset + " do not match: " + b1 + " vs. " + b2);\r
-                ++offset;\r
-            }\r
-        } finally {\r
-            in1.close();\r
-            in2.close();\r
-        }\r
-    }\r
-\r
-    public static void writeTestData(File file, int rows) throws IOException {\r
-        if (file.exists())\r
-            return;\r
-\r
-        System.out.println("writing test data...");\r
-        OutputStream stream = new FileOutputStream(file);\r
-        for (int i = 0; i < rows; ++i)\r
-            stream.write((Integer.toString(i) + "\n").getBytes());\r
-        stream.close();\r
-        System.out.println("wrote " + file.length() + " bytes of test data.");\r
-    }\r
-\r
-    /**\r
-     * @param source\r
-     * @param flz\r
-     * @return compressed size in bytes\r
-     * @throws IOException\r
-     */\r
-    static long compressFlzJava(File source, File flz) throws IOException {\r
-        return compressFlz(source, flz, FastLZJava.write(flz));\r
-    }\r
-\r
-    /**\r
-     * @param source\r
-     * @param flz\r
-     * @return compressed size in bytes\r
-     * @throws IOException\r
-     */\r
-    static long compressFlzNative(File source, File flz) throws IOException {\r
-        return compressFlz(source, flz, FastLZ.write(flz));\r
-    }\r
-\r
-    /**\r
-     * @param source\r
-     * @param flz\r
-     * @return compressed size in bytes\r
-     * @throws IOException\r
-     */\r
-    static long compressFlz(File source, File flz, OutputStream flzOutput) throws IOException {\r
-        System.out.println("compressFlz(" + source + ", " + flz + ")");\r
-        InputStream input = new BufferedInputStream(new FileInputStream(source));\r
-        copy(input, flzOutput);\r
-        input.close();\r
-        flzOutput.close();\r
-        long compressed = flz.length();\r
-        System.out.println("Wrote " + compressed + " compressed bytes");\r
-        return compressed;\r
-    }\r
-\r
-    /**\r
-     * @param source\r
-     * @param flz\r
-     * @return compressed size in bytes\r
-     * @throws IOException\r
-     */\r
-    static long decompressFlzJava(File flz, File dest) throws IOException {\r
-        return decompressFlz(flz, FastLZJava.read(flz), dest);\r
-    }\r
-\r
-    /**\r
-     * @param source\r
-     * @param flz\r
-     * @return compressed size in bytes\r
-     * @throws IOException\r
-     */\r
-    static long decompressFlzNative(File flz, File dest) throws IOException {\r
-        return decompressFlz(flz, FastLZ.read(flz), dest);\r
-    }\r
-\r
-    /**\r
-     * @param source\r
-     * @param flz\r
-     * @return compressed size in bytes\r
-     * @throws IOException\r
-     */\r
-    static long decompressFlz(File source, InputStream flzInput, File dest) throws IOException {\r
-        System.out.println("decompressFlz(" + source + ", " + dest + ")");\r
-        OutputStream output = new BufferedOutputStream(new FileOutputStream(dest));\r
-        copy(flzInput, output);\r
-        flzInput.close();\r
-        output.close();\r
-        long decompressed = dest.length();\r
-        System.out.println("Wrote " + decompressed + " decompressed bytes");\r
-        return decompressed;\r
-    }\r
-\r
-    /**\r
-     * @param source\r
-     * @param flz\r
-     * @return compressed size in bytes\r
-     * @throws IOException\r
-     */\r
-    static long decompressFlz(File source, InputStream flzInput, File dest, OutputStream destStream) throws IOException {\r
-        System.out.println("decompressFlz(" + source + ", " + dest + ")");\r
-        copy(flzInput, destStream);\r
-        flzInput.close();\r
-        destStream.close();\r
-        long decompressed = dest.length();\r
-        System.out.println("Wrote " + decompressed + " decompressed bytes");\r
-        return decompressed;\r
-    }\r
-\r
-    /**\r
-     * Copy the content of the input stream into the output stream, using a temporary\r
-     * byte array buffer whose size is defined by {@link #IO_BUFFER_SIZE}.\r
-     *\r
-     * @param in The input stream to copy from.\r
-     * @param out The output stream to copy to.\r
-     *\r
-     * @throws IOException If any error occurs during the copy.\r
-     */\r
-    private static final int IO_BUFFER_SIZE = 128 * 1024;\r
-\r
-    public static long copy(InputStream in, OutputStream out) throws IOException {\r
-        byte[] b = new byte[IO_BUFFER_SIZE];\r
-        int read;\r
-        long total = 0;\r
-        long start = System.nanoTime();\r
-        while (true) {\r
-            read = in.read(b);\r
-            if (read < 0)\r
-                break;\r
-            total += read;\r
-            //System.out.println("read " + read + " bytes, " + total + " bytes in total");\r
-            out.write(b, 0, read);\r
-        }\r
-\r
-        long end = System.nanoTime();\r
-        double totalmb = total/(1024.0*1024.0);\r
-        double time = (end-start)*1e-9;\r
-        double rate = totalmb / time;\r
-        System.out.format("Transferred %d bytes (%.3f Mbytes) in %f seconds (%.3f MB/s)\n", total, totalmb, time, rate);\r
-\r
-        return total;\r
-    }\r
-\r
-    @SuppressWarnings("unused")\r
-    private boolean checksumsEqual(File f1, File f2) throws IOException {\r
-        byte[] s1 = ChecksumUtil.computeSum(f1);\r
-        byte[] s2 = ChecksumUtil.computeSum(f2);\r
-        return Arrays.equals(s1, s2);\r
-    }\r
-\r
+
+    static void compareFiles(File file1, File file2) throws IOException {
+        InputStream in1 = new BufferedInputStream(new FileInputStream(file1));
+        InputStream in2 = new BufferedInputStream(new FileInputStream(file2));
+        try {
+            int offset = 0;
+            while (true) {
+                int b1 = in1.read();
+                int b2 = in2.read();
+                if (b1 == -1 && b2 == -1)
+                    return;
+                if (b1 == -1)
+                    fail("EOF reached in file1 " + file1.getName() + " but not in file2 " + file2.getName());
+                if (b2 == -1)
+                    fail("EOF reached in file1 " + file1.getName() + " but not in file2 " + file2.getName());
+                if (b1 != b2)
+                    fail("bytes at offset " + offset + " do not match: " + b1 + " vs. " + b2);
+                ++offset;
+            }
+        } finally {
+            in1.close();
+            in2.close();
+        }
+    }
+
+    public static void writeTestData(File file, int rows) throws IOException {
+        if (file.exists())
+            return;
+
+        System.out.println("writing test data...");
+        OutputStream stream = new FileOutputStream(file);
+        for (int i = 0; i < rows; ++i)
+            stream.write((Integer.toString(i) + "\n").getBytes());
+        stream.close();
+        System.out.println("wrote " + file.length() + " bytes of test data.");
+    }
+
+    /**
+     * @param source
+     * @param flz
+     * @return compressed size in bytes
+     * @throws IOException
+     */
+    static long compressFlzJava(File source, File flz) throws IOException {
+        return compressFlz(source, flz, FastLZJava.write(flz));
+    }
+
+    /**
+     * @param source
+     * @param flz
+     * @return compressed size in bytes
+     * @throws IOException
+     */
+    static long compressFlzNative(File source, File flz) throws IOException {
+        return compressFlz(source, flz, FastLZ.write(flz));
+    }
+
+    /**
+     * @param source
+     * @param flz
+     * @return compressed size in bytes
+     * @throws IOException
+     */
+    static long compressFlz(File source, File flz, OutputStream flzOutput) throws IOException {
+        System.out.println("compressFlz(" + source + ", " + flz + ")");
+        InputStream input = new BufferedInputStream(new FileInputStream(source));
+        copy(input, flzOutput);
+        input.close();
+        flzOutput.close();
+        long compressed = flz.length();
+        System.out.println("Wrote " + compressed + " compressed bytes");
+        return compressed;
+    }
+
+    /**
+     * @param source
+     * @param flz
+     * @return compressed size in bytes
+     * @throws IOException
+     */
+    static long decompressFlzJava(File flz, File dest) throws IOException {
+        return decompressFlz(flz, FastLZJava.read(flz), dest);
+    }
+
+    /**
+     * @param source
+     * @param flz
+     * @return compressed size in bytes
+     * @throws IOException
+     */
+    static long decompressFlzNative(File flz, File dest) throws IOException {
+        return decompressFlz(flz, FastLZ.read(flz), dest);
+    }
+
+    /**
+     * @param source
+     * @param flz
+     * @return compressed size in bytes
+     * @throws IOException
+     */
+    static long decompressFlz(File source, InputStream flzInput, File dest) throws IOException {
+        System.out.println("decompressFlz(" + source + ", " + dest + ")");
+        OutputStream output = new BufferedOutputStream(new FileOutputStream(dest));
+        copy(flzInput, output);
+        flzInput.close();
+        output.close();
+        long decompressed = dest.length();
+        System.out.println("Wrote " + decompressed + " decompressed bytes");
+        return decompressed;
+    }
+
+    /**
+     * @param source
+     * @param flz
+     * @return compressed size in bytes
+     * @throws IOException
+     */
+    static long decompressFlz(File source, InputStream flzInput, File dest, OutputStream destStream) throws IOException {
+        System.out.println("decompressFlz(" + source + ", " + dest + ")");
+        copy(flzInput, destStream);
+        flzInput.close();
+        destStream.close();
+        long decompressed = dest.length();
+        System.out.println("Wrote " + decompressed + " decompressed bytes");
+        return decompressed;
+    }
+
+    /**
+     * Copy the content of the input stream into the output stream, using a temporary
+     * byte array buffer whose size is defined by {@link #IO_BUFFER_SIZE}.
+     *
+     * @param in The input stream to copy from.
+     * @param out The output stream to copy to.
+     *
+     * @throws IOException If any error occurs during the copy.
+     */
+    private static final int IO_BUFFER_SIZE = 128 * 1024;
+
+    public static long copy(InputStream in, OutputStream out) throws IOException {
+        byte[] b = new byte[IO_BUFFER_SIZE];
+        int read;
+        long total = 0;
+        long start = System.nanoTime();
+        while (true) {
+            read = in.read(b);
+            if (read < 0)
+                break;
+            total += read;
+            //System.out.println("read " + read + " bytes, " + total + " bytes in total");
+            out.write(b, 0, read);
+        }
+
+        long end = System.nanoTime();
+        double totalmb = total/(1024.0*1024.0);
+        double time = (end-start)*1e-9;
+        double rate = totalmb / time;
+        System.out.format("Transferred %d bytes (%.3f Mbytes) in %f seconds (%.3f MB/s)\n", total, totalmb, time, rate);
+
+        return total;
+    }
+
+    @SuppressWarnings("unused")
+    private boolean checksumsEqual(File f1, File f2) throws IOException {
+        byte[] s1 = ChecksumUtil.computeSum(f1);
+        byte[] s2 = ChecksumUtil.computeSum(f2);
+        return Arrays.equals(s1, s2);
+    }
+
 }