/* * Copyright (C) 2010 Brockmann Consult GmbH (info@brockmann-consult.de) * * This program 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/ */ package com.bc.ceres.binio.internal; import com.bc.ceres.binio.*; import static com.bc.ceres.binio.TypeBuilder.*; import com.bc.ceres.binio.smos.SmosProduct; import com.bc.ceres.binio.util.ByteArrayIOHandler; import com.bc.ceres.binio.util.ImageIOHandler; import junit.framework.TestCase; import javax.imageio.stream.ImageInputStream; import javax.imageio.stream.MemoryCacheImageInputStream; import javax.imageio.stream.MemoryCacheImageOutputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.ByteOrder; public class InstanceTest extends TestCase { public void testGeneratedInstanceTypes() throws IOException { final byte[] byteData = SmosProduct.createTestProductData(SmosProduct.MIR_SCLF1C_FORMAT.getByteOrder()); final TracingIOHandler ioHandler = new TracingIOHandler(new ByteArrayIOHandler(byteData)); final DataContext context = SmosProduct.MIR_SCLF1C_FORMAT.createContext(ioHandler); final CompoundData mirSclf1cData = context.getData(); final SequenceData snapshotList = mirSclf1cData.getSequence("Snapshot_List"); final CompoundData snapshotData = snapshotList.getCompound(0); final SequenceData gridPointList = mirSclf1cData.getSequence("Grid_Point_List"); final CompoundData gridPointData = gridPointList.getCompound(0); final SequenceData btDataList = gridPointData.getSequence("Bt_Data_List"); final CompoundData btData = btDataList.getCompound(0); assertSame(VarCompound.class, mirSclf1cData.getClass()); assertSame(FixSequenceOfFixCollections.class, snapshotList.getClass()); assertSame(FixCompound.class, snapshotData.getClass()); assertSame(FixSequenceOfVarCollections.class, gridPointList.getClass()); assertSame(VarCompound.class, gridPointData.getClass()); assertSame(FixSequenceOfFixCollections.class, btDataList.getClass()); assertSame(FixCompound.class, btData.getClass()); } public void testFixSequenceOfSimples() throws IOException { final ByteArrayOutputStream baos = new ByteArrayOutputStream(); MemoryCacheImageOutputStream ios = new MemoryCacheImageOutputStream(baos); ios.setByteOrder(ByteOrder.LITTLE_ENDIAN); ios.writeInt(2134); ios.writeInt(45); ios.writeInt(36134); ios.close(); final ImageInputStream iis = new MemoryCacheImageInputStream(new ByteArrayInputStream(baos.toByteArray())); final DataContext context = new DataFormat(COMPOUND("UNDEFINED"), ByteOrder.LITTLE_ENDIAN).createContext( new ImageIOHandler(iis)); SequenceType type = SEQUENCE(SimpleType.INT, 3); final FixSequenceOfSimples sequenceInstance = new FixSequenceOfSimples(context, null, type, 0); assertEquals(3, sequenceInstance.getElementCount()); assertEquals(3 * 4, sequenceInstance.getSize()); assertEquals(false, sequenceInstance.isDataAccessible()); sequenceInstance.makeDataAccessible(); assertEquals(true, sequenceInstance.isDataAccessible()); assertEquals(2134, sequenceInstance.getInt(0)); assertEquals(45, sequenceInstance.getInt(1)); assertEquals(36134, sequenceInstance.getInt(2)); } public void testFixCompound() throws IOException { final ByteArrayOutputStream baos = new ByteArrayOutputStream(); MemoryCacheImageOutputStream ios = new MemoryCacheImageOutputStream(baos); ios.setByteOrder(ByteOrder.LITTLE_ENDIAN); ios.writeInt(33); ios.writeInt(55); ios.writeFloat(27.88f); ios.close(); CompoundType type = COMPOUND("compoundTestType", MEMBER("a", SimpleType.UINT), MEMBER("b", SimpleType.FLOAT)); assertFalse(FixCompound.isCompoundTypeWithinSizeLimit(type, 7)); assertTrue(FixCompound.isCompoundTypeWithinSizeLimit(type, 8)); assertTrue(FixCompound.isCompoundTypeWithinSizeLimit(type, 9)); final byte[] byteData = baos.toByteArray(); assertEquals(3 * 4, byteData.length); final DataContext context = new DataFormat(type, ByteOrder.LITTLE_ENDIAN).createContext( new ByteArrayIOHandler(byteData)); CompoundInstance compoundInstance = InstanceFactory.createCompound(context, null, type, 4, ByteOrder.LITTLE_ENDIAN); assertSame(FixCompound.class, compoundInstance.getClass()); assertEquals(2, compoundInstance.getElementCount()); assertEquals(2 * 4, compoundInstance.getSize()); assertEquals(4, compoundInstance.getPosition()); assertEquals(type, compoundInstance.getType()); assertEquals(true, compoundInstance.isSizeResolved()); assertEquals(55, compoundInstance.getInt(0)); assertEquals(27.88f, compoundInstance.getFloat(1), 0.00001f); } public void testFixCompoundOfFixCompounds() throws IOException { final ByteArrayOutputStream baos = new ByteArrayOutputStream(); MemoryCacheImageOutputStream ios = new MemoryCacheImageOutputStream(baos); ios.setByteOrder(ByteOrder.LITTLE_ENDIAN); ios.writeDouble(17.0); ios.writeDouble(11.0); ios.writeDouble(19.0); ios.writeDouble(67.0); ios.close(); final CompoundType complexType = COMPOUND("Complex", MEMBER("x", DOUBLE), MEMBER("y", DOUBLE)); CompoundType type = COMPOUND("compoundTestType", MEMBER("x", SimpleType.DOUBLE), MEMBER("y", SimpleType.DOUBLE), MEMBER("z", complexType)); assertFalse(FixCompound.isCompoundTypeWithinSizeLimit(type, 31)); assertTrue(FixCompound.isCompoundTypeWithinSizeLimit(type, 32)); assertTrue(FixCompound.isCompoundTypeWithinSizeLimit(type, 33)); final byte[] byteData = baos.toByteArray(); assertEquals(2 * 8 + 16, byteData.length); final DataContext context = new DataFormat(type, ByteOrder.LITTLE_ENDIAN).createContext( new ByteArrayIOHandler(byteData)); CompoundInstance compoundInstance = InstanceFactory.createCompound(context, null, type, 0, ByteOrder.LITTLE_ENDIAN); assertSame(FixCompound.class, compoundInstance.getClass()); assertEquals(3, compoundInstance.getElementCount()); assertEquals(2 * 8 + 16, compoundInstance.getSize()); assertEquals(0, compoundInstance.getPosition()); assertEquals(type, compoundInstance.getType()); assertEquals(true, compoundInstance.isSizeResolved()); assertEquals(11.0, compoundInstance.getDouble(1), 0.0); assertEquals(19.0, compoundInstance.getCompound(2).getDouble(0), 0.0); assertEquals(67.0, compoundInstance.getCompound(2).getDouble(1), 0.0); final CompoundData complexData = compoundInstance.getCompound(2); complexData.setDouble(0, 67.0); complexData.setDouble(0, 19.0); // todo - uncomment and make test run (rq-20091005) // compoundInstance.setCompound(2, complexData); // assertEquals(19.0, compoundInstance.getCompound(2).getDouble(0), 0.0); // assertEquals(67.0, compoundInstance.getCompound(2).getDouble(1), 0.0); } public void testVarCompound() throws Exception { final ByteArrayOutputStream baos = new ByteArrayOutputStream(); MemoryCacheImageOutputStream ios = new MemoryCacheImageOutputStream(baos); ios.setByteOrder(ByteOrder.BIG_ENDIAN); ios.writeInt(3); ios.writeDouble(111.1); ios.writeDouble(222.2); ios.writeDouble(333.3); ios.close(); CompoundType type = COMPOUND("compoundTestType", MEMBER("count", SimpleType.INT), MEMBER("list", VAR_SEQUENCE(SimpleType.DOUBLE, "count"))); DataFormat format = new DataFormat(type, ByteOrder.BIG_ENDIAN); assertFalse(FixCompound.isCompoundTypeWithinSizeLimit(type, 4)); assertFalse(FixCompound.isCompoundTypeWithinSizeLimit(type, 10)); assertFalse(FixCompound.isCompoundTypeWithinSizeLimit(type, 10000)); final byte[] byteData = baos.toByteArray(); assertEquals(4 + 3 * 8, byteData.length); final DataContext context = format.createContext(new ByteArrayIOHandler(byteData)); CompoundData compoundData = context.getData(); assertTrue(compoundData instanceof CompoundInstance); CompoundInstance compoundInstance = (CompoundInstance) compoundData; assertSame(VarCompound.class, compoundInstance.getClass()); assertEquals(2, compoundInstance.getMemberCount()); assertFalse(compoundInstance.isSizeResolved()); SequenceData sequenceData = compoundInstance.getSequence(1); assertSame(FixSequenceOfSimples.class, sequenceData.getClass()); compoundInstance.resolveSize(); assertTrue(compoundInstance.isSizeResolved()); assertTrue(compoundInstance.getSize() > 0); assertNotNull(sequenceData); assertEquals(3, sequenceData.getElementCount()); assertEquals(111.1, sequenceData.getDouble(0), 1e-10); assertEquals(222.2, sequenceData.getDouble(1), 1e-10); assertEquals(333.3, sequenceData.getDouble(2), 1e-10); } public void testFixSequenceOfFixCollections() throws IOException { final int n = 11; final CompoundType type = COMPOUND("U", MEMBER("A", INT), MEMBER("B", SEQUENCE( COMPOUND("P", MEMBER("X", DOUBLE), MEMBER("Y", DOUBLE)), n ) ), MEMBER("C", INT) ); assertTrue(type.isSizeKnown()); assertEquals(4 + n * (8 + 8) + 4, type.getSize()); final ByteArrayOutputStream baos = new ByteArrayOutputStream(type.getSize()); final MemoryCacheImageOutputStream ios = new MemoryCacheImageOutputStream(baos); ios.writeInt(12345678); for (int i = 0; i < n; i++) { ios.writeDouble(20.0 + 0.1 * i); ios.writeDouble(40.0 + 0.1 * i); } ios.writeInt(87654321); ios.close(); final byte[] byteData = baos.toByteArray(); assertEquals(4 + n * (8 + 8) + 4, byteData.length); final DataContext context = new DataFormat(type).createContext(new ByteArrayIOHandler(byteData)); final CompoundData compoundData = context.getData(); assertSame(FixCompound.class, compoundData.getClass()); assertSame(FixSequenceOfFixCollections.class, compoundData.getSequence(1).getClass()); assertSame(FixCompound.class, compoundData.getSequence(1).getCompound(0).getClass()); assertEquals(12345678, compoundData.getInt(0)); for (int i = 0; i < n; i++) { assertEquals("i=" + i, 20.0 + 0.1 * i, compoundData.getSequence(1).getCompound(i).getDouble(0), 1e-10); assertEquals("i=" + i, 40.0 + 0.1 * i, compoundData.getSequence(1).getCompound(i).getDouble(1), 1e-10); } assertEquals(87654321, compoundData.getInt(2)); } public void testFixSequenceOfVarCollections() throws IOException { final int ni = 2; final int nj = 3; final CompoundType pointType = COMPOUND("Point", MEMBER("X", DOUBLE), MEMBER("Y", DOUBLE)); final SequenceType seqType1 = _SEQ(pointType, ni); final SequenceType seqType2 = _SEQ(seqType1, nj); final CompoundType type = COMPOUND("C", MEMBER("M", seqType2)); final DataFormat format = new DataFormat(type, ByteOrder.BIG_ENDIAN); assertFalse(type.isSizeKnown()); assertEquals(-1, type.getSize()); final ByteArrayOutputStream baos = new ByteArrayOutputStream(ni * nj * (8 + 8)); final MemoryCacheImageOutputStream ios = new MemoryCacheImageOutputStream(baos); ios.setByteOrder(format.getByteOrder()); for (int j = 0; j < nj; j++) { for (int i = 0; i < ni; i++) { ios.writeDouble(20.0 + 0.1 * i + 0.2 * j); ios.writeDouble(40.0 + 0.1 * i + 0.2 * j); } } ios.close(); final byte[] byteData = baos.toByteArray(); assertEquals(ni * nj * 2 * 8, byteData.length); final DataContext context = format.createContext(new ByteArrayIOHandler(byteData)); final CompoundData compoundData = context.getData(); assertSame(VarCompound.class, compoundData.getClass()); assertSame(FixSequenceOfVarCollections.class, compoundData.getSequence(0).getClass()); assertSame(FixSequenceOfFixCollections.class, compoundData.getSequence(0).getSequence(0).getClass()); assertSame(FixCompound.class, compoundData.getSequence(0).getSequence(0).getCompound(0).getClass()); for (int j = 0; j < nj; j++) { for (int i = 0; i < ni; i++) { assertEquals("i=" + i + ",j=" + j, 20.0 + 0.1 * i + 0.2 * j, compoundData.getSequence(0).getSequence(j).getCompound(i).getDouble(0), 1e-10); assertEquals("i=" + i + ",j=" + j, 40.0 + 0.1 * i + 0.2 * j, compoundData.getSequence(0).getSequence(j).getCompound(i).getDouble(1), 1e-10); } } } public void testNestedFixSequenceOfVarCollections() throws IOException { final int ni = 4; final int nj = 2; final int nk = 3; final SequenceType seqType0 = _SEQ(DOUBLE, ni); final CompoundType pointType = COMPOUND("Point", MEMBER("Coords", seqType0)); final SequenceType seqType1 = _SEQ(pointType, nj); final SequenceType seqType2 = _SEQ(seqType1, nk); final CompoundType type = COMPOUND("Polygon", MEMBER("PointList", seqType2)); final DataFormat format = new DataFormat(type, ByteOrder.BIG_ENDIAN); assertFalse(type.isSizeKnown()); assertEquals(-1, type.getSize()); final ByteArrayOutputStream baos = new ByteArrayOutputStream(ni * nj * nk * 8); final MemoryCacheImageOutputStream ios = new MemoryCacheImageOutputStream(baos); ios.setByteOrder(format.getByteOrder()); for (int k = 0; k < nk; k++) { for (int j = 0; j < nj; j++) { for (int i = 0; i < ni; i++) { ios.writeDouble(10.0 * i + 0.1 * j + 0.2 * k); } } } ios.close(); final byte[] byteData = baos.toByteArray(); assertEquals(ni * nj * nk * 8, byteData.length); final DataContext context = format.createContext(new ByteArrayIOHandler(byteData)); final CompoundData compoundData = context.getData(); assertSame(VarCompound.class, compoundData.getClass()); final SequenceData pointListData = compoundData.getSequence("PointList"); assertSame(FixSequenceOfVarCollections.class, pointListData.getClass()); final SequenceData pointListDataSeq0 = pointListData.getSequence(0); assertSame(FixSequenceOfVarCollections.class, pointListDataSeq0.getClass()); final CompoundData pointListDataSeq0Comp0 = pointListDataSeq0.getCompound(0); assertSame(VarCompound.class, pointListDataSeq0Comp0.getClass()); final SequenceData pointListDataSeq0Comp0Coords = pointListDataSeq0Comp0.getSequence("Coords"); assertSame(FixSequenceOfSimples.class, pointListDataSeq0Comp0Coords.getClass()); for (int k = 0; k < nk; k++) { final SequenceData kData = pointListData.getSequence(k); for (int j = 0; j < nj; j++) { final CompoundData kjData = kData.getCompound(j); final SequenceData coordsData = kjData.getSequence("Coords"); for (int i = 0; i < ni; i++) { assertEquals("i=" + i + ",j=" + j + ",k=" + k, 10.0 * i + 0.1 * j + 0.2 * k, coordsData.getDouble(i), 1e-10); } } } } // create a pseudo VarSequenceType static VarSequenceType _SEQ(final Type elementType, final int elementCount) { return new VarElementCountSequenceType(elementType) { @Override protected int resolveElementCount(CollectionData parent) throws IOException { return elementCount; } }; } }