diff --git a/base/build/build.xml b/base/build/build.xml index 5c3d66618cbd56432f4b48112110cfcbbaf0b440..2b95d8e7e58e31a80c433bbc7be17ab16f32b215 100644 --- a/base/build/build.xml +++ b/base/build/build.xml @@ -135,7 +135,7 @@ <zipfileset src="${lib}/commons-lang/commons-lang.jar" /> <zipfileset src="${lib}/commons-io/commons-io.jar" /> <manifest> - <attribute name="Main-Class" value="ch.systemsx.cisd.base.unix.UnixTests" /> + <attribute name="Main-Class" value="ch.systemsx.cisd.base.AllTests" /> <attribute name="Version" value="${version.number}" /> <attribute name="Build-Number" value="${version.number} (r${revision.number},${clean.flag})" /> diff --git a/base/source/java/ch/systemsx/cisd/base/convert/NativeArrayEncoding.java b/base/source/java/ch/systemsx/cisd/base/convert/NativeArrayEncoding.java new file mode 100644 index 0000000000000000000000000000000000000000..26514c87fdcd7358900b9174444b8f4c22ed9b49 --- /dev/null +++ b/base/source/java/ch/systemsx/cisd/base/convert/NativeArrayEncoding.java @@ -0,0 +1,172 @@ +/* + * Copyright 2010 ETH Zuerich, CISD + * + * Licensed 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 ch.systemsx.cisd.base.convert; + +import ch.systemsx.cisd.base.convert.NativeData.ByteOrder; + +/** + * An enum for encoding array of numbers (integer or float) in native (host) format. + * + * @author Bernd Rinn + */ +enum NativeArrayEncoding +{ + INT8_NATIVE(false, (byte) 1, NativeData.ByteOrder.NATIVE), + + INT16_LITTLE_ENDIAN(false, (byte) 2, NativeData.ByteOrder.LITTLE_ENDIAN), + + INT32_LITTLE_ENDIAN(false, (byte) 4, NativeData.ByteOrder.LITTLE_ENDIAN), + + INT64_LITTLE_ENDIAN(false, (byte) 8, NativeData.ByteOrder.LITTLE_ENDIAN), + + INT16_BIG_ENDIAN(false, (byte) 2, NativeData.ByteOrder.BIG_ENDIAN), + + INT32_BIG_ENDIAN(false, (byte) 4, NativeData.ByteOrder.BIG_ENDIAN), + + INT64_BIG_ENDIAN(false, (byte) 8, NativeData.ByteOrder.BIG_ENDIAN), + + FLOAT32_LITTLE_ENDIAN(true, (byte) 4, NativeData.ByteOrder.LITTLE_ENDIAN), + + FLOAT64_LITTLE_ENDIAN(true, (byte) 8, NativeData.ByteOrder.LITTLE_ENDIAN), + + FLOAT32_BIG_ENDIAN(true, (byte) 4, NativeData.ByteOrder.BIG_ENDIAN), + + FLOAT64_BIG_ENDIAN(true, (byte) 8, NativeData.ByteOrder.BIG_ENDIAN), + + ; + + private static final int MIN_ENCODING_HEADER_SIZE = 8; + + private static final int CHAR_N = 78; + + private static final int CHAR_B = 66; + + private static final int CHAR_L = 76; + + private static final int CHAR_I = 73; + + private static final int CHAR_F = 70; + + NativeArrayEncoding(boolean floatingPoint, byte sizeInBytes, NativeData.ByteOrder byteOrder) + { + this.floatingPoint = floatingPoint; + this.byteOrder = byteOrder; + this.sizeInBytes = sizeInBytes; + this.magic = + new byte[] + { + (byte) (floatingPoint ? CHAR_F : CHAR_I), + (byte) ((byteOrder == ByteOrder.LITTLE_ENDIAN) ? CHAR_L + : (byteOrder == ByteOrder.BIG_ENDIAN) ? CHAR_B : CHAR_N), + sizeInBytes }; + } + + private boolean floatingPoint; + + private ByteOrder byteOrder; + + private byte sizeInBytes; + + private byte[] magic; + + boolean isFloatingPoint() + { + return floatingPoint; + } + + boolean isInteger() + { + return floatingPoint == false; + } + + NativeData.ByteOrder getByteOrder() + { + return byteOrder; + } + + byte getSizeInBytes() + { + return sizeInBytes; + } + + byte[] getMagic() + { + return magic; + } + + static NativeArrayEncoding tryGetIntEncoding(ByteOrder byteOrder, byte sizeInBytes) + { + assert byteOrder != null; + if (sizeInBytes == 1 && byteOrder == ByteOrder.NATIVE) + { + return INT8_NATIVE; + } else if (sizeInBytes == 2) + { + return (byteOrder == ByteOrder.LITTLE_ENDIAN) ? INT16_LITTLE_ENDIAN : INT16_BIG_ENDIAN; + } else if (sizeInBytes == 4) + { + return (byteOrder == ByteOrder.LITTLE_ENDIAN) ? INT32_LITTLE_ENDIAN : INT32_BIG_ENDIAN; + + } else if (sizeInBytes == 8) + { + return (byteOrder == ByteOrder.LITTLE_ENDIAN) ? INT64_LITTLE_ENDIAN : INT64_BIG_ENDIAN; + } + return null; + } + + static NativeArrayEncoding tryGetFloatEncoding(ByteOrder byteOrder, byte sizeInBytes) + { + assert byteOrder != null; + if (sizeInBytes == 4) + { + return (byteOrder == ByteOrder.LITTLE_ENDIAN) ? FLOAT32_LITTLE_ENDIAN + : FLOAT32_BIG_ENDIAN; + } else if (sizeInBytes == 8) + { + return (byteOrder == ByteOrder.LITTLE_ENDIAN) ? FLOAT64_LITTLE_ENDIAN + : FLOAT64_BIG_ENDIAN; + } + return null; + } + + /** + * Returns the encoding for the given <var>byteArr</var>, or <code>null</code>, if + * <var>byteArr</var> is not an encoded array. + */ + public static NativeArrayEncoding tryGetEncoding(byte[] byteArr) + { + if (byteArr.length < MIN_ENCODING_HEADER_SIZE) + { + return null; + } + final ByteOrder byteOrder = + (byteArr[1] == CHAR_L) ? ByteOrder.LITTLE_ENDIAN + : (byteArr[1] == CHAR_B) ? ByteOrder.BIG_ENDIAN : null; + if (byteOrder == null) + { + return null; + } + if (byteArr[0] == CHAR_F) + { + return tryGetFloatEncoding(byteOrder, byteArr[2]); + } else if (byteArr[0] == CHAR_I) + { + return tryGetIntEncoding(byteOrder, byteArr[2]); + } + return null; + } +} \ No newline at end of file diff --git a/base/source/java/ch/systemsx/cisd/base/convert/NativeTaggedArray.java b/base/source/java/ch/systemsx/cisd/base/convert/NativeTaggedArray.java new file mode 100644 index 0000000000000000000000000000000000000000..08b1100776bb57bc0461babf45d2051994b978b3 --- /dev/null +++ b/base/source/java/ch/systemsx/cisd/base/convert/NativeTaggedArray.java @@ -0,0 +1,344 @@ +/* + * Copyright 2010 ETH Zuerich, CISD + * + * Licensed 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 ch.systemsx.cisd.base.convert; + +import static ch.systemsx.cisd.base.convert.NativeData.FLOAT_SIZE; +import static ch.systemsx.cisd.base.convert.NativeData.DOUBLE_SIZE; +import static ch.systemsx.cisd.base.convert.NativeData.INT_SIZE; +import static ch.systemsx.cisd.base.convert.NativeData.LONG_SIZE; +import static ch.systemsx.cisd.base.convert.NativeData.SHORT_SIZE; + +import ch.systemsx.cisd.base.convert.NativeData.ByteOrder; + +/** + * A utility class that supports encoding and decoding of arrays of primitive number types to byte + * arrays such that the characteristics of the number type (float or integer, byte order, element + * size) and the dimensions are known and can be checked for correctness when converted back to the + * number type. + * + * @author Bernd Rinn + */ +public class NativeTaggedArray +{ + + private final static NativeData.ByteOrder NATIVE_BYTE_ORDER = NativeData.getNativeByteOrder(); + + private static final int MAGIC_SIZE = 3; + + private static final int RANK_SIZE = 1; + + private static final int RANK_INDEX = 3; + + private static final int LENGTH_SIZE = 4; + + private static final int LENGTH_INDEX = 4; + + private static final int RANK_1 = 1; + + // + // Float + // + + /** + * Converts <var>data</var> into a tagged array in native byte order. + */ + public static byte[] toByteArray(float[] data) + { + return toByteArray(data, NATIVE_BYTE_ORDER); + } + + /** + * Converts <var>data</var> into a tagged array in native byte order. + */ + public static byte[] toByteArray(float[] data, ByteOrder byteOrder) + { + final byte[] magic = + NativeArrayEncoding.tryGetFloatEncoding(byteOrder, (byte) FLOAT_SIZE).getMagic(); + assert magic.length == MAGIC_SIZE; + final int headerSize = MAGIC_SIZE + RANK_SIZE + 1 * LENGTH_SIZE; + final byte[] byteArr = new byte[headerSize + FLOAT_SIZE * data.length]; + System.arraycopy(magic, 0, byteArr, 0, MAGIC_SIZE); + byteArr[RANK_INDEX] = RANK_1; + NativeData.copyIntToByte(new int[] + { data.length }, 0, byteArr, LENGTH_INDEX, 1, byteOrder); + NativeData.copyFloatToByte(data, 0, byteArr, headerSize, data.length, byteOrder); + return byteArr; + } + + /** + * Returns the tagged array <var>data</var> as a float array or <code>null</code>, if + * <var>data</var> is not a tagged 1D float array. + */ + public static float[] tryToFloatArray1D(byte[] data) + { + final NativeArrayEncoding encoding = NativeArrayEncoding.tryGetEncoding(data); + if (encoding == null || encoding.isInteger() || encoding.getSizeInBytes() != FLOAT_SIZE) + { + return null; + } + final int rank = data[RANK_INDEX]; + if (rank != 1) + { + return null; + } + final int[] dimensions = new int[1]; + NativeData.copyByteToInt(data, LENGTH_INDEX, dimensions, 0, 1, encoding.getByteOrder()); + if (dimensions[0] * FLOAT_SIZE + LENGTH_INDEX + LENGTH_SIZE != data.length) + { + return null; + } + final float[] floatData = new float[dimensions[0]]; + NativeData.copyByteToFloat(data, LENGTH_INDEX + LENGTH_SIZE, floatData, 0, + floatData.length, encoding.getByteOrder()); + return floatData; + } + + // + // Double + // + + /** + * Converts <var>data</var> into a tagged array in native byte order. + */ + public static byte[] toByteArray(double[] data) + { + return toByteArray(data, NATIVE_BYTE_ORDER); + } + + /** + * Converts <var>data</var> into a tagged array in native byte order. + */ + public static byte[] toByteArray(double[] data, ByteOrder byteOrder) + { + final byte[] magic = + NativeArrayEncoding.tryGetFloatEncoding(byteOrder, (byte) DOUBLE_SIZE).getMagic(); + assert magic.length == MAGIC_SIZE; + final int headerSize = MAGIC_SIZE + RANK_SIZE + 1 * LENGTH_SIZE; + final byte[] byteArr = new byte[headerSize + DOUBLE_SIZE * data.length]; + System.arraycopy(magic, 0, byteArr, 0, MAGIC_SIZE); + byteArr[RANK_INDEX] = RANK_1; + NativeData.copyIntToByte(new int[] + { data.length }, 0, byteArr, LENGTH_INDEX, 1, byteOrder); + NativeData.copyDoubleToByte(data, 0, byteArr, headerSize, data.length, byteOrder); + return byteArr; + } + + /** + * Returns the tagged array <var>data</var> as a double array or <code>null</code>, if + * <var>data</var> is not a tagged 1D double array. + */ + public static double[] tryToDoubleArray1D(byte[] data) + { + final NativeArrayEncoding encoding = NativeArrayEncoding.tryGetEncoding(data); + if (encoding == null || encoding.isInteger() || encoding.getSizeInBytes() != DOUBLE_SIZE) + { + return null; + } + final int rank = data[RANK_INDEX]; + if (rank != 1) + { + return null; + } + final int[] dimensions = new int[1]; + NativeData.copyByteToInt(data, LENGTH_INDEX, dimensions, 0, 1, encoding.getByteOrder()); + if (dimensions[0] * DOUBLE_SIZE + LENGTH_INDEX + LENGTH_SIZE != data.length) + { + return null; + } + final double[] doubleData = new double[dimensions[0]]; + NativeData.copyByteToDouble(data, LENGTH_INDEX + LENGTH_SIZE, doubleData, 0, + doubleData.length, encoding.getByteOrder()); + return doubleData; + } + + // + // Short + // + + /** + * Converts <var>data</var> into a tagged array in native byte order. + */ + public static byte[] toByteArray(short[] data) + { + return toByteArray(data, NATIVE_BYTE_ORDER); + } + + /** + * Converts <var>data</var> into a tagged array in native byte order. + */ + public static byte[] toByteArray(short[] data, ByteOrder byteOrder) + { + final byte[] magic = + NativeArrayEncoding.tryGetIntEncoding(byteOrder, (byte) SHORT_SIZE).getMagic(); + assert magic.length == MAGIC_SIZE; + final int headerSize = MAGIC_SIZE + RANK_SIZE + 1 * LENGTH_SIZE; + final byte[] byteArr = new byte[headerSize + SHORT_SIZE * data.length]; + System.arraycopy(magic, 0, byteArr, 0, MAGIC_SIZE); + byteArr[RANK_INDEX] = RANK_1; + NativeData.copyIntToByte(new int[] + { data.length }, 0, byteArr, LENGTH_INDEX, 1, byteOrder); + NativeData.copyShortToByte(data, 0, byteArr, headerSize, data.length, byteOrder); + return byteArr; + } + + /** + * Returns the tagged array <var>data</var> as a short array or <code>null</code>, if + * <var>data</var> is not a tagged 1D short array. + */ + public static short[] tryToShortArray1D(byte[] data) + { + final NativeArrayEncoding encoding = NativeArrayEncoding.tryGetEncoding(data); + if (encoding == null || encoding.isFloatingPoint() + || encoding.getSizeInBytes() != SHORT_SIZE) + { + return null; + } + final int rank = data[RANK_INDEX]; + if (rank != 1) + { + return null; + } + final int[] dimensions = new int[1]; + NativeData.copyByteToInt(data, LENGTH_INDEX, dimensions, 0, 1, encoding.getByteOrder()); + if (dimensions[0] * SHORT_SIZE + LENGTH_INDEX + LENGTH_SIZE != data.length) + { + return null; + } + final short[] shortData = new short[dimensions[0]]; + NativeData.copyByteToShort(data, LENGTH_INDEX + LENGTH_SIZE, shortData, 0, + shortData.length, encoding.getByteOrder()); + return shortData; + } + + // + // Int + // + + /** + * Converts <var>data</var> into a tagged array in native byte order. + */ + public static byte[] toByteArray(int[] data) + { + return toByteArray(data, NATIVE_BYTE_ORDER); + } + + /** + * Converts <var>data</var> into a tagged array in native byte order. + */ + public static byte[] toByteArray(int[] data, ByteOrder byteOrder) + { + final byte[] magic = + NativeArrayEncoding.tryGetIntEncoding(byteOrder, (byte) INT_SIZE).getMagic(); + assert magic.length == MAGIC_SIZE; + final int headerSize = MAGIC_SIZE + RANK_SIZE + 1 * LENGTH_SIZE; + final byte[] byteArr = new byte[headerSize + INT_SIZE * data.length]; + System.arraycopy(magic, 0, byteArr, 0, MAGIC_SIZE); + byteArr[RANK_INDEX] = RANK_1; + NativeData.copyIntToByte(new int[] + { data.length }, 0, byteArr, LENGTH_INDEX, 1, byteOrder); + NativeData.copyIntToByte(data, 0, byteArr, headerSize, data.length, byteOrder); + return byteArr; + } + + /** + * Returns the tagged array <var>data</var> as an int array or <code>null</code>, if + * <var>data</var> is not a tagged 1D int array. + */ + public static int[] tryToIntArray1D(byte[] data) + { + final NativeArrayEncoding encoding = NativeArrayEncoding.tryGetEncoding(data); + if (encoding == null || encoding.isFloatingPoint() || encoding.getSizeInBytes() != INT_SIZE) + { + return null; + } + final int rank = data[RANK_INDEX]; + if (rank != 1) + { + return null; + } + final int[] dimensions = new int[1]; + NativeData.copyByteToInt(data, LENGTH_INDEX, dimensions, 0, 1, encoding.getByteOrder()); + if (dimensions[0] * INT_SIZE + LENGTH_INDEX + LENGTH_SIZE != data.length) + { + return null; + } + final int[] intData = new int[dimensions[0]]; + NativeData.copyByteToInt(data, LENGTH_INDEX + LENGTH_SIZE, intData, 0, intData.length, + encoding.getByteOrder()); + return intData; + } + + // + // Long + // + + /** + * Converts <var>data</var> into a tagged array in native byte order. + */ + public static byte[] toByteArray(long[] data) + { + return toByteArray(data, NATIVE_BYTE_ORDER); + } + + /** + * Converts <var>data</var> into a tagged array in native byte order. + */ + public static byte[] toByteArray(long[] data, ByteOrder byteOrder) + { + final byte[] magic = + NativeArrayEncoding.tryGetIntEncoding(byteOrder, (byte) LONG_SIZE).getMagic(); + assert magic.length == MAGIC_SIZE; + final int headerSize = MAGIC_SIZE + RANK_SIZE + 1 * LENGTH_SIZE; + final byte[] byteArr = new byte[headerSize + LONG_SIZE * data.length]; + System.arraycopy(magic, 0, byteArr, 0, MAGIC_SIZE); + byteArr[RANK_INDEX] = RANK_1; + NativeData.copyIntToByte(new int[] + { data.length }, 0, byteArr, LENGTH_INDEX, 1, byteOrder); + NativeData.copyLongToByte(data, 0, byteArr, headerSize, data.length, byteOrder); + return byteArr; + } + + /** + * Returns the tagged array <var>data</var> as a long array or <code>null</code>, if + * <var>data</var> is not a tagged 1D long array. + */ + public static long[] tryToLongArray1D(byte[] data) + { + final NativeArrayEncoding encoding = NativeArrayEncoding.tryGetEncoding(data); + if (encoding == null || encoding.isFloatingPoint() + || encoding.getSizeInBytes() != LONG_SIZE) + { + return null; + } + final int rank = data[RANK_INDEX]; + if (rank != 1) + { + return null; + } + final int[] dimensions = new int[1]; + NativeData.copyByteToInt(data, LENGTH_INDEX, dimensions, 0, 1, encoding.getByteOrder()); + if (dimensions[0] * LONG_SIZE + LENGTH_INDEX + LENGTH_SIZE != data.length) + { + return null; + } + final long[] intData = new long[dimensions[0]]; + NativeData.copyByteToLong(data, LENGTH_INDEX + LENGTH_SIZE, intData, 0, intData.length, + encoding.getByteOrder()); + return intData; + } + +} diff --git a/base/sourceTest/java/ch/systemsx/cisd/base/AllTests.java b/base/sourceTest/java/ch/systemsx/cisd/base/AllTests.java new file mode 100644 index 0000000000000000000000000000000000000000..f486b95131eed435b9ddba6eacb3fbea98a70636 --- /dev/null +++ b/base/sourceTest/java/ch/systemsx/cisd/base/AllTests.java @@ -0,0 +1,44 @@ +/* + * Copyright 2010 ETH Zuerich, CISD + * + * Licensed 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 ch.systemsx.cisd.base; + +import ch.systemsx.cisd.base.convert.NativeDataTests; +import ch.systemsx.cisd.base.convert.NativeTaggedArrayTests; +import ch.systemsx.cisd.base.unix.Unix; +import ch.systemsx.cisd.base.unix.UnixTests; + +/** + * Run all unit tests. + * + * @author Bernd Rinn + */ +public class AllTests +{ + + public static void main(String[] args) throws Throwable + { + if (Unix.isOperational()) + { + UnixTests.main(args); + } + System.out.println(); + NativeDataTests.main(args); + System.out.println(); + NativeTaggedArrayTests.main(args); + } + +} diff --git a/base/sourceTest/java/ch/systemsx/cisd/base/convert/NativeTaggedArrayTests.java b/base/sourceTest/java/ch/systemsx/cisd/base/convert/NativeTaggedArrayTests.java new file mode 100644 index 0000000000000000000000000000000000000000..6020274d7f58225fa3c887b85c28bf79b136fc75 --- /dev/null +++ b/base/sourceTest/java/ch/systemsx/cisd/base/convert/NativeTaggedArrayTests.java @@ -0,0 +1,276 @@ +/* + * Copyright 2010 ETH Zuerich, CISD + * + * Licensed 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 ch.systemsx.cisd.base.convert; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Arrays; + +import org.testng.annotations.Test; + +import ch.systemsx.cisd.base.BuildAndEnvironmentInfo; +import ch.systemsx.cisd.base.convert.NativeData.ByteOrder; + +import static org.testng.AssertJUnit.*; + +/** + * Test cases for {@link NativeTaggedArray}. + * + * @author Bernd Rinn + */ +public class NativeTaggedArrayTests +{ + + @Test + public static void testFloat1DArrayNativeByteOrder() + { + final float[] floatArr = new float[] + { 1.1f, -3.2f, 1001.5f }; + final byte[] taggedArr = NativeTaggedArray.toByteArray(floatArr); + assertEquals(3 * 4 + 4 + 4, taggedArr.length); + final float[] convertedFloatArr = NativeTaggedArray.tryToFloatArray1D(taggedArr); + final NativeArrayEncoding encoding = NativeArrayEncoding.tryGetEncoding(taggedArr); + assertNotNull(encoding); + assertEquals(NativeData.getNativeByteOrder(), encoding.getByteOrder()); + assertEquals(4, encoding.getSizeInBytes()); + assertTrue(encoding.isFloatingPoint()); + assertFalse(encoding.isInteger()); + assertTrue(Arrays.equals(floatArr, convertedFloatArr)); + } + + @Test + public static void testFloat1DArrayNonNativeByteOrder() + { + final float[] floatArr = new float[] + { 1.1f, -3.2f, 1001.5f }; + final ByteOrder nonNativeByteOrder = + (NativeData.getNativeByteOrder() == ByteOrder.LITTLE_ENDIAN) ? ByteOrder.BIG_ENDIAN + : ByteOrder.LITTLE_ENDIAN; + final byte[] taggedArr = NativeTaggedArray.toByteArray(floatArr, nonNativeByteOrder); + assertEquals(3 * 4 + 4 + 4, taggedArr.length); + final float[] convertedFloatArr = NativeTaggedArray.tryToFloatArray1D(taggedArr); + final NativeArrayEncoding encoding = NativeArrayEncoding.tryGetEncoding(taggedArr); + assertNotNull(encoding); + assertEquals(ByteOrder.BIG_ENDIAN, encoding.getByteOrder()); + assertEquals(4, encoding.getSizeInBytes()); + assertTrue(encoding.isFloatingPoint()); + assertFalse(encoding.isInteger()); + assertTrue(Arrays.equals(floatArr, convertedFloatArr)); + } + + @Test + public static void testDouble1DArrayNativeByteOrder() + { + final double[] doubleArr = new double[] + { 1.1, -3.2, 1001.5 }; + final byte[] taggedArr = NativeTaggedArray.toByteArray(doubleArr); + assertEquals(3 * 8 + 4 + 4, taggedArr.length); + final double[] convertedDoubleArr = NativeTaggedArray.tryToDoubleArray1D(taggedArr); + final NativeArrayEncoding encoding = NativeArrayEncoding.tryGetEncoding(taggedArr); + assertNotNull(encoding); + assertEquals(NativeData.getNativeByteOrder(), encoding.getByteOrder()); + assertEquals(8, encoding.getSizeInBytes()); + assertTrue(encoding.isFloatingPoint()); + assertFalse(encoding.isInteger()); + assertTrue(Arrays.equals(doubleArr, convertedDoubleArr)); + } + + @Test + public static void testDouble1DArrayNonNativeByteOrder() + { + final double[] doubleArr = new double[] + { 1.1, -3.2, 1001.5 }; + final ByteOrder nonNativeByteOrder = + (NativeData.getNativeByteOrder() == ByteOrder.LITTLE_ENDIAN) ? ByteOrder.BIG_ENDIAN + : ByteOrder.LITTLE_ENDIAN; + final byte[] taggedArr = NativeTaggedArray.toByteArray(doubleArr, nonNativeByteOrder); + assertEquals(3 * 8 + 4 + 4, taggedArr.length); + final double[] convertedDoubleArr = NativeTaggedArray.tryToDoubleArray1D(taggedArr); + final NativeArrayEncoding encoding = NativeArrayEncoding.tryGetEncoding(taggedArr); + assertNotNull(encoding); + assertEquals(ByteOrder.BIG_ENDIAN, encoding.getByteOrder()); + assertEquals(8, encoding.getSizeInBytes()); + assertTrue(encoding.isFloatingPoint()); + assertFalse(encoding.isInteger()); + assertTrue(Arrays.equals(doubleArr, convertedDoubleArr)); + } + + @Test + public static void testShort1DArrayNativeByteOrder() + { + final short[] shortArr = new short[] + { 1, -3, 1001 }; + final byte[] taggedArr = NativeTaggedArray.toByteArray(shortArr); + assertEquals(3 * 2 + 4 + 4, taggedArr.length); + final short[] convertedShortArr = NativeTaggedArray.tryToShortArray1D(taggedArr); + final NativeArrayEncoding encoding = NativeArrayEncoding.tryGetEncoding(taggedArr); + assertNotNull(encoding); + assertEquals(NativeData.getNativeByteOrder(), encoding.getByteOrder()); + assertEquals(2, encoding.getSizeInBytes()); + assertFalse(encoding.isFloatingPoint()); + assertTrue(encoding.isInteger()); + assertTrue(Arrays.equals(shortArr, convertedShortArr)); + } + + @Test + public static void testShort1DArrayNonNativeByteOrder() + { + final short[] shortArr = new short[] + { 1, -3, 1001 }; + final ByteOrder nonNativeByteOrder = + (NativeData.getNativeByteOrder() == ByteOrder.LITTLE_ENDIAN) ? ByteOrder.BIG_ENDIAN + : ByteOrder.LITTLE_ENDIAN; + final byte[] taggedArr = NativeTaggedArray.toByteArray(shortArr, nonNativeByteOrder); + assertEquals(3 * 2 + 4 + 4, taggedArr.length); + final short[] convertedShortArr = NativeTaggedArray.tryToShortArray1D(taggedArr); + final NativeArrayEncoding encoding = NativeArrayEncoding.tryGetEncoding(taggedArr); + assertNotNull(encoding); + assertEquals(ByteOrder.BIG_ENDIAN, encoding.getByteOrder()); + assertEquals(2, encoding.getSizeInBytes()); + assertFalse(encoding.isFloatingPoint()); + assertTrue(encoding.isInteger()); + assertTrue(Arrays.equals(shortArr, convertedShortArr)); + } + + @Test + public static void testInt1DArrayNativeByteOrder() + { + final int[] intArr = new int[] + { 1, -3, 1001 }; + final byte[] taggedArr = NativeTaggedArray.toByteArray(intArr); + assertEquals(3 * 4 + 4 + 4, taggedArr.length); + final int[] convertedIntArr = NativeTaggedArray.tryToIntArray1D(taggedArr); + final NativeArrayEncoding encoding = NativeArrayEncoding.tryGetEncoding(taggedArr); + assertNotNull(encoding); + assertEquals(NativeData.getNativeByteOrder(), encoding.getByteOrder()); + assertEquals(4, encoding.getSizeInBytes()); + assertFalse(encoding.isFloatingPoint()); + assertTrue(encoding.isInteger()); + assertTrue(Arrays.equals(intArr, convertedIntArr)); + } + + @Test + public static void testInt1DArrayNonNativeByteOrder() + { + final int[] intArr = new int[] + { 1, -3, 1001 }; + final ByteOrder nonNativeByteOrder = + (NativeData.getNativeByteOrder() == ByteOrder.LITTLE_ENDIAN) ? ByteOrder.BIG_ENDIAN + : ByteOrder.LITTLE_ENDIAN; + final byte[] taggedArr = NativeTaggedArray.toByteArray(intArr, nonNativeByteOrder); + assertEquals(3 * 4 + 4 + 4, taggedArr.length); + final int[] convertedIntArr = NativeTaggedArray.tryToIntArray1D(taggedArr); + final NativeArrayEncoding encoding = NativeArrayEncoding.tryGetEncoding(taggedArr); + assertNotNull(encoding); + assertEquals(ByteOrder.BIG_ENDIAN, encoding.getByteOrder()); + assertEquals(4, encoding.getSizeInBytes()); + assertFalse(encoding.isFloatingPoint()); + assertTrue(encoding.isInteger()); + assertTrue(Arrays.equals(intArr, convertedIntArr)); + } + + @Test + public static void testLong1DArrayNativeByteOrder() + { + final long[] longArr = new long[] + { 1, -3, 1001 }; + final byte[] taggedArr = NativeTaggedArray.toByteArray(longArr); + assertEquals(3 * 8 + 4 + 4, taggedArr.length); + final long[] convertedLongArr = NativeTaggedArray.tryToLongArray1D(taggedArr); + final NativeArrayEncoding encoding = NativeArrayEncoding.tryGetEncoding(taggedArr); + assertNotNull(encoding); + assertEquals(NativeData.getNativeByteOrder(), encoding.getByteOrder()); + assertEquals(8, encoding.getSizeInBytes()); + assertFalse(encoding.isFloatingPoint()); + assertTrue(encoding.isInteger()); + assertTrue(Arrays.equals(longArr, convertedLongArr)); + } + + @Test + public static void testLong1DArrayNonNativeByteOrder() + { + final long[] longArr = new long[] + { 1, -3, 1001 }; + final ByteOrder nonNativeByteOrder = + (NativeData.getNativeByteOrder() == ByteOrder.LITTLE_ENDIAN) ? ByteOrder.BIG_ENDIAN + : ByteOrder.LITTLE_ENDIAN; + final byte[] taggedArr = NativeTaggedArray.toByteArray(longArr, nonNativeByteOrder); + assertEquals(3 * 8 + 4 + 4, taggedArr.length); + final long[] convertedLongArr = NativeTaggedArray.tryToLongArray1D(taggedArr); + final NativeArrayEncoding encoding = NativeArrayEncoding.tryGetEncoding(taggedArr); + assertNotNull(encoding); + assertEquals(ByteOrder.BIG_ENDIAN, encoding.getByteOrder()); + assertEquals(8, encoding.getSizeInBytes()); + assertFalse(encoding.isFloatingPoint()); + assertTrue(encoding.isInteger()); + assertTrue(Arrays.equals(longArr, convertedLongArr)); + } + + private void afterClass() + { + } + + private void setUp() + { + } + + public static void main(String[] args) throws Throwable + { + System.out.println(BuildAndEnvironmentInfo.INSTANCE); + System.out.println(); + NativeData.ensureNativeLibIsLoaded(); + final NativeTaggedArrayTests test = new NativeTaggedArrayTests(); + try + { + for (Method m : NativeTaggedArrayTests.class.getMethods()) + { + final Test testAnnotation = m.getAnnotation(Test.class); + if (testAnnotation == null || m.getParameterTypes().length > 0) + { + continue; + } + System.out.println("Running " + m.getName()); + test.setUp(); + try + { + m.invoke(test); + } catch (InvocationTargetException wrapperThrowable) + { + final Throwable th = wrapperThrowable.getCause(); + boolean exceptionFound = false; + for (Class<?> expectedExClazz : testAnnotation.expectedExceptions()) + { + if (expectedExClazz == th.getClass()) + { + exceptionFound = true; + break; + } + } + if (exceptionFound == false) + { + throw th; + } + } + } + System.out.println("Tests OK!"); + } finally + { + test.afterClass(); + } + } + +}