tikhomirov@575: /* tikhomirov@575: * Copyright (c) 2013 TMate Software Ltd tikhomirov@575: * tikhomirov@575: * This program is free software; you can redistribute it and/or modify tikhomirov@575: * it under the terms of the GNU General Public License as published by tikhomirov@575: * the Free Software Foundation; version 2 of the License. tikhomirov@575: * tikhomirov@575: * This program is distributed in the hope that it will be useful, tikhomirov@575: * but WITHOUT ANY WARRANTY; without even the implied warranty of tikhomirov@575: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the tikhomirov@575: * GNU General Public License for more details. tikhomirov@575: * tikhomirov@575: * For information on how to redistribute this software under tikhomirov@575: * the terms of a license other than GNU General Public License tikhomirov@575: * contact TMate Software at support@hg4j.com tikhomirov@575: */ tikhomirov@575: package org.tmatesoft.hg.test; tikhomirov@575: tikhomirov@575: import java.io.ByteArrayOutputStream; tikhomirov@575: import java.io.IOException; tikhomirov@575: import java.nio.ByteBuffer; tikhomirov@575: import java.util.zip.DeflaterOutputStream; tikhomirov@575: import java.util.zip.Inflater; tikhomirov@575: tikhomirov@576: import org.junit.Rule; tikhomirov@575: import org.junit.Test; tikhomirov@575: import org.tmatesoft.hg.internal.ByteArrayDataAccess; tikhomirov@575: import org.tmatesoft.hg.internal.DataAccess; tikhomirov@575: import org.tmatesoft.hg.internal.InflaterDataAccess; tikhomirov@575: tikhomirov@575: /** tikhomirov@575: * tikhomirov@575: * @author Artem Tikhomirov tikhomirov@575: * @author TMate Software Ltd. tikhomirov@575: */ tikhomirov@575: public class TestInflaterDataAccess { tikhomirov@576: @Rule tikhomirov@576: public final ErrorCollectorExt errorCollector = new ErrorCollectorExt(); tikhomirov@575: tikhomirov@575: private final byte[] testContent1 = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.".getBytes(); tikhomirov@575: tikhomirov@575: private DataAccess zip(byte[] source) throws IOException { tikhomirov@575: ByteArrayOutputStream bos = new ByteArrayOutputStream(); tikhomirov@575: DeflaterOutputStream dos = new DeflaterOutputStream(bos); tikhomirov@575: dos.write(source); tikhomirov@575: dos.flush(); tikhomirov@575: dos.close(); tikhomirov@575: return new ByteArrayDataAccess(bos.toByteArray()); tikhomirov@575: } tikhomirov@575: tikhomirov@575: @Test tikhomirov@575: public void testSeek() throws Exception { tikhomirov@575: DataAccess zip = zip(testContent1); tikhomirov@575: InflaterDataAccess ida = new InflaterDataAccess(zip, 0, zip.length(), -1, new Inflater(), new byte[25]); tikhomirov@575: ida.seek(20); tikhomirov@575: final int bufferCapacity = 10; tikhomirov@575: ByteBuffer chunk1 = ByteBuffer.allocate(bufferCapacity); tikhomirov@575: ida.readBytes(chunk1); tikhomirov@575: errorCollector.assertTrue(new ByteArraySlice(testContent1, 20, bufferCapacity).equalsTo(chunk1.array())); tikhomirov@575: ida.skip(-bufferCapacity); tikhomirov@575: ByteBuffer chunk2 = ByteBuffer.allocate(bufferCapacity); tikhomirov@575: ida.readBytes(chunk2); tikhomirov@575: errorCollector.assertEquals(chunk1, chunk2); tikhomirov@575: } tikhomirov@575: tikhomirov@575: @Test tikhomirov@575: public void testLength() throws Exception { tikhomirov@575: DataAccess zip = zip(testContent1); tikhomirov@575: InflaterDataAccess ida = new InflaterDataAccess(zip, 0, zip.length(), -1, new Inflater(), new byte[25]); tikhomirov@575: errorCollector.assertEquals("Plain #length()", testContent1.length, ida.length()); tikhomirov@575: // tikhomirov@575: ida = new InflaterDataAccess(zip, 0, zip.length(), -1, new Inflater(), new byte[25]); tikhomirov@575: byte[] dummy = new byte[30]; tikhomirov@575: ida.readBytes(dummy, 0, dummy.length); tikhomirov@575: errorCollector.assertEquals("#length() after readBytes()", testContent1.length, ida.length()); tikhomirov@575: // tikhomirov@575: ida = new InflaterDataAccess(zip, 0, zip.length(), -1, new Inflater(), new byte[25]); tikhomirov@575: // consume most of the stream, so that all original compressed data is already read tikhomirov@576: dummy = new byte[testContent1.length - 1]; tikhomirov@576: ida.readBytes(dummy, 0, dummy.length); tikhomirov@575: errorCollector.assertEquals("#length() after origin was completely read", testContent1.length, ida.length()); tikhomirov@576: // tikhomirov@576: errorCollector.assertFalse(ida.isEmpty()); // check InflaterDataAccess#available() positive tikhomirov@575: } tikhomirov@575: tikhomirov@575: @Test tikhomirov@575: public void testReadBytes() throws Exception { tikhomirov@575: DataAccess zip = zip(testContent1); tikhomirov@575: InflaterDataAccess ida = new InflaterDataAccess(zip, 0, zip.length(), -1, new Inflater(), new byte[25]); tikhomirov@575: ida.skip(10); tikhomirov@575: byte[] chunk1 = new byte[22]; tikhomirov@575: ida.readBytes(chunk1, 0, 20); tikhomirov@575: chunk1[20] = ida.readByte(); tikhomirov@575: chunk1[21] = ida.readByte(); tikhomirov@575: ida.skip(5); tikhomirov@575: byte[] chunk2 = new byte[12]; tikhomirov@575: chunk2[0] = ida.readByte(); tikhomirov@575: chunk2[1] = ida.readByte(); tikhomirov@575: ida.readBytes(chunk2, 2, 10); tikhomirov@575: errorCollector.assertTrue(new ByteArraySlice(testContent1, 10, 22).equalsTo(chunk1)); tikhomirov@575: errorCollector.assertTrue(new ByteArraySlice(testContent1, 10+22+5, 12).equalsTo(chunk2)); tikhomirov@576: int consumed = 10+22+5+12; tikhomirov@576: // tikhomirov@576: // check that even when original content is completely unpacked, leftovers in the outBuffer are recognized tikhomirov@576: ida.readBytes(ByteBuffer.allocate(testContent1.length - consumed - 2)); // unpack up to an end (almost) tikhomirov@576: errorCollector.assertFalse(ida.isEmpty()); // check InflaterDataAccess#available() positive tikhomirov@576: // tikhomirov@576: ByteBuffer chunk3 = ByteBuffer.allocate(10); tikhomirov@576: ida.readBytes(chunk3); tikhomirov@576: errorCollector.assertEquals(2, chunk3.flip().remaining()); tikhomirov@575: } tikhomirov@575: tikhomirov@575: private static class ByteArraySlice { tikhomirov@575: public final byte[] array; tikhomirov@575: public final int offset, length; tikhomirov@575: tikhomirov@575: public ByteArraySlice(byte[] array, int offset, int length) { tikhomirov@575: this.array = array; tikhomirov@575: this.offset = offset; tikhomirov@575: this.length = length; tikhomirov@575: } tikhomirov@575: tikhomirov@575: public boolean equalsTo(byte[] another) { tikhomirov@575: if (another == null || another.length != length) { tikhomirov@575: return false; tikhomirov@575: } tikhomirov@575: for (int i = 0; i < length; i++) { tikhomirov@575: if (array[offset + i] != another[i]) { tikhomirov@575: return false; tikhomirov@575: } tikhomirov@575: } tikhomirov@575: return true; tikhomirov@575: } tikhomirov@575: } tikhomirov@575: }