/*
* Copyright 2011 Warren Falk
* This program is distributed under the terms of the GNU General Public License (LGPL)
*
* This file is part of lzma-java
*
* lzma-java is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* See https://bitbucket.org/warren/lzma-java for the latest version
*/
package warrenfalk.lzma.test;
import static org.junit.Assert.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.util.Random;
import org.junit.Before;
import org.junit.Test;
import SevenZip.Compression.LZMA.Decoder;
import warrenfalk.lzma.LzmaInputStream;
import warrenfalk.lzma.LzmaOutputStream;
import warrenfalk.util.BinCoder;
public class LzmaStreamTest {
File out;
File frand;
File fnonrand;
@Before
public void setup() throws IOException {
createTestData();
}
@Test
public void testEncodeDecode() throws IOException {
File test = new File("/dev/shm", fnonrand.getName() + ".lzma");
File fin = new File("/dev/shm", fnonrand.getName() + ".final");
long start = System.nanoTime();
FileOutputStream fos = new FileOutputStream(test);
FileInputStream fis = new FileInputStream(fnonrand);
LzmaOutputStream los = new LzmaOutputStream(fos, -1, new byte[4096], 1 << 22, 3, 0, 2, 1 << 0x20);
byte[] buffer = new byte[4096];
int len;
while (-1 != (len = fis.read(buffer, 0, buffer.length))) {
los.write(buffer, 0, len);
}
fis.close();
los.close();
long end = System.nanoTime();
System.out.println("" + ((double)(end - start) / 1000000000.0) + " seconds");
start = System.nanoTime();
fos = new FileOutputStream(fin);
fis = new FileInputStream(test);
LzmaInputStream lis = new LzmaInputStream(fis);
while (-1 != (len = lis.read(buffer, 0, buffer.length))) {
fos.write(buffer, 0, len);
}
lis.close();
fos.close();
end = System.nanoTime();
System.out.println("" + ((double)(end - start) / 1000000000.0) + " seconds");
}
@Test(expected=IOException.class)
public void testEncodeWithError() throws IOException {
File test = new File("/dev/shm", fnonrand.getName() + ".lzma");
long start = System.nanoTime();
FileOutputStream fos = new FileOutputStream(test);
InputStream fis = new FailInputStream(fnonrand);
LzmaOutputStream los = new LzmaOutputStream(fos, -1, new byte[4096], 1 << 22, 3, 0, 2, 1 << 0x20);
byte[] buffer = new byte[4096];
int len;
while (-1 != (len = fis.read(buffer, 0, buffer.length))) {
los.write(buffer, 0, len);
}
fis.close();
los.close();
long end = System.nanoTime();
System.out.println("" + ((double)(end - start) / 1000000000.0) + " seconds");
}
public static class FailInputStream extends FileInputStream {
long remain;
public FailInputStream(File file) throws FileNotFoundException {
super(file);
remain = file.length() / 2; // fail halfway through
}
@Override
public int read() throws IOException {
int n = super.read();
remain--;
if (remain == 0)
throw new IOException("failed on purpose");
return n;
}
@Override
public int read(byte[] b) throws IOException {
int n = super.read(b);
remain -= n;
if (remain <= 0)
throw new IOException("failed on purpose");
return n;
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
int n = super.read(b, off, len);
remain -= n;
if (remain <= 0)
throw new IOException("failed on purpose");
return n;
}
}
public void createTestData() throws IOException {
// First create a directory for our test files
out = new File("testdata");
if (!out.isDirectory())
out.mkdirs();
// Now generate some files.
// Begin with random data
long size = 20 * 1024 * 1024;
/*
frand = new File(out, "random");
if (!frand.isFile() || size != frand.length()) {
if (frand.isFile())
frand.delete();
FileOutputStream fos = new FileOutputStream(frand);
long remain = size;
Random r = new Random(12345);
byte[] buffer = new byte[4096];
while (remain > 0) {
r.nextBytes(buffer);
long len = (remain < buffer.length) ? remain : buffer.length;
fos.write(buffer, 0 , (int)len);
remain -= len;
}
fos.close();
}
*/
// then create less random data
fnonrand = new File(out, "nonrand");
if (!fnonrand.isFile() || size != fnonrand.length()) {
if (fnonrand.isFile())
fnonrand.delete();
Random r = new Random(12345);
byte[][] segments = new byte[512][];
for (int i = 0; i < segments.length; i++) {
int seglen = r.nextInt(15) + 3;
byte[] seg = new byte[seglen];
for (int j = 0; j < seglen; j++)
seg[j] = (byte)('a' + r.nextInt(26));
segments[i] = seg;
}
long remain = size;
FileOutputStream fos = new FileOutputStream(fnonrand);
while (remain > 0) {
int i = r.nextInt(segments.length);
byte[] seg = segments[i];
long len = (remain < seg.length) ? remain : seg.length;
fos.write(seg, 0, (int)len);
remain -= seg.length;
}
fos.close();
}
}
}