From 27b97736a928c018bf039dc4d47114acade04e3a Mon Sep 17 00:00:00 2001
From: brinn <brinn>
Date: Mon, 3 May 2010 06:52:33 +0000
Subject: [PATCH] add: methods for converting multi-dimensional arrays to byte
 arrays and vice versa

SVN: 15706
---
 .../cisd/base/convert/NativeTaggedArray.java  | 299 +++++++++++++++++-
 .../base/convert/NativeTaggedArrayTests.java  | 200 +++++++++++-
 2 files changed, 485 insertions(+), 14 deletions(-)

diff --git a/base/source/java/ch/systemsx/cisd/base/convert/NativeTaggedArray.java b/base/source/java/ch/systemsx/cisd/base/convert/NativeTaggedArray.java
index 08b1100776b..7af60beb905 100644
--- a/base/source/java/ch/systemsx/cisd/base/convert/NativeTaggedArray.java
+++ b/base/source/java/ch/systemsx/cisd/base/convert/NativeTaggedArray.java
@@ -23,6 +23,12 @@ 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;
+import ch.systemsx.cisd.base.mdarray.MDArray;
+import ch.systemsx.cisd.base.mdarray.MDDoubleArray;
+import ch.systemsx.cisd.base.mdarray.MDFloatArray;
+import ch.systemsx.cisd.base.mdarray.MDIntArray;
+import ch.systemsx.cisd.base.mdarray.MDLongArray;
+import ch.systemsx.cisd.base.mdarray.MDShortArray;
 
 /**
  * A utility class that supports encoding and decoding of arrays of primitive number types to byte
@@ -62,7 +68,7 @@ public class NativeTaggedArray
     }
 
     /**
-     * Converts <var>data</var> into a tagged array in native byte order.
+     * Converts <var>data</var> into a tagged array in given byte order.
      */
     public static byte[] toByteArray(float[] data, ByteOrder byteOrder)
     {
@@ -79,6 +85,34 @@ public class NativeTaggedArray
         return byteArr;
     }
 
+    /**
+     * Converts <var>data</var> into a tagged array in native byte order.
+     */
+    public static byte[] toByteArray(MDFloatArray data)
+    {
+        return toByteArray(data, NATIVE_BYTE_ORDER);
+    }
+
+    /**
+     * Converts <var>data</var> into a tagged array in given byte order.
+     */
+    public static byte[] toByteArray(MDFloatArray data, ByteOrder byteOrder)
+    {
+        final byte[] magic =
+                NativeArrayEncoding.tryGetFloatEncoding(byteOrder, (byte) FLOAT_SIZE).getMagic();
+        assert magic.length == MAGIC_SIZE;
+        final byte rank = (byte) data.rank();
+        final int headerSize = MAGIC_SIZE + RANK_SIZE + rank * LENGTH_SIZE;
+        final float[] flatDataArray = data.getAsFlatArray();
+        final byte[] byteArr = new byte[headerSize + FLOAT_SIZE * flatDataArray.length];
+        System.arraycopy(magic, 0, byteArr, 0, MAGIC_SIZE);
+        byteArr[RANK_INDEX] = rank;
+        NativeData.copyIntToByte(data.dimensions(), 0, byteArr, LENGTH_INDEX, rank, byteOrder);
+        NativeData.copyFloatToByte(flatDataArray, 0, byteArr, headerSize, flatDataArray.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.
@@ -107,6 +141,33 @@ public class NativeTaggedArray
         return floatData;
     }
 
+    /**
+     * Returns the tagged array <var>data</var> as a {@link MDFloatArray} or <code>null</code>, if
+     * <var>data</var> is not a tagged (multi-dimensional) float array.
+     */
+    public static MDFloatArray tryToFloatArray(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];
+        final int[] dimensions = new int[rank];
+        NativeData.copyByteToInt(data, LENGTH_INDEX, dimensions, 0, rank, encoding.getByteOrder());
+        final int length = MDArray.getLength(dimensions);
+        final int headerSize = LENGTH_INDEX + rank * LENGTH_SIZE;
+        if (length * FLOAT_SIZE + headerSize != data.length)
+        {
+            return null;
+        }
+        final float[] intData = new float[length];
+        NativeData.copyByteToFloat(data, headerSize, intData, 0, intData.length, encoding
+                .getByteOrder());
+        return new MDFloatArray(intData, dimensions);
+    }
+
     //
     // Double
     //
@@ -120,7 +181,7 @@ public class NativeTaggedArray
     }
 
     /**
-     * Converts <var>data</var> into a tagged array in native byte order.
+     * Converts <var>data</var> into a tagged array in given byte order.
      */
     public static byte[] toByteArray(double[] data, ByteOrder byteOrder)
     {
@@ -137,6 +198,34 @@ public class NativeTaggedArray
         return byteArr;
     }
 
+    /**
+     * Converts <var>data</var> into a tagged array in native byte order.
+     */
+    public static byte[] toByteArray(MDDoubleArray data)
+    {
+        return toByteArray(data, NATIVE_BYTE_ORDER);
+    }
+
+    /**
+     * Converts <var>data</var> into a tagged array in given byte order.
+     */
+    public static byte[] toByteArray(MDDoubleArray data, ByteOrder byteOrder)
+    {
+        final byte[] magic =
+                NativeArrayEncoding.tryGetFloatEncoding(byteOrder, (byte) DOUBLE_SIZE).getMagic();
+        assert magic.length == MAGIC_SIZE;
+        final byte rank = (byte) data.rank();
+        final int headerSize = MAGIC_SIZE + RANK_SIZE + rank * LENGTH_SIZE;
+        final double[] flatDataArray = data.getAsFlatArray();
+        final byte[] byteArr = new byte[headerSize + DOUBLE_SIZE * flatDataArray.length];
+        System.arraycopy(magic, 0, byteArr, 0, MAGIC_SIZE);
+        byteArr[RANK_INDEX] = rank;
+        NativeData.copyIntToByte(data.dimensions(), 0, byteArr, LENGTH_INDEX, rank, byteOrder);
+        NativeData.copyDoubleToByte(flatDataArray, 0, byteArr, headerSize, flatDataArray.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.
@@ -165,6 +254,33 @@ public class NativeTaggedArray
         return doubleData;
     }
 
+    /**
+     * Returns the tagged array <var>data</var> as a {@link MDDoubleArray} or <code>null</code>, if
+     * <var>data</var> is not a tagged (multi-dimensional) double array.
+     */
+    public static MDDoubleArray tryToDoubleArray(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];
+        final int[] dimensions = new int[rank];
+        NativeData.copyByteToInt(data, LENGTH_INDEX, dimensions, 0, rank, encoding.getByteOrder());
+        final int length = MDArray.getLength(dimensions);
+        final int headerSize = LENGTH_INDEX + rank * LENGTH_SIZE;
+        if (length * DOUBLE_SIZE + headerSize != data.length)
+        {
+            return null;
+        }
+        final double[] intData = new double[length];
+        NativeData.copyByteToDouble(data, headerSize, intData, 0, intData.length, encoding
+                .getByteOrder());
+        return new MDDoubleArray(intData, dimensions);
+    }
+
     //
     // Short
     //
@@ -178,7 +294,7 @@ public class NativeTaggedArray
     }
 
     /**
-     * Converts <var>data</var> into a tagged array in native byte order.
+     * Converts <var>data</var> into a tagged array in given byte order.
      */
     public static byte[] toByteArray(short[] data, ByteOrder byteOrder)
     {
@@ -195,6 +311,34 @@ public class NativeTaggedArray
         return byteArr;
     }
 
+    /**
+     * Converts <var>data</var> into a tagged array in native byte order.
+     */
+    public static byte[] toByteArray(MDShortArray data)
+    {
+        return toByteArray(data, NATIVE_BYTE_ORDER);
+    }
+
+    /**
+     * Converts <var>data</var> into a tagged array in given byte order.
+     */
+    public static byte[] toByteArray(MDShortArray data, ByteOrder byteOrder)
+    {
+        final byte[] magic =
+                NativeArrayEncoding.tryGetIntEncoding(byteOrder, (byte) SHORT_SIZE).getMagic();
+        assert magic.length == MAGIC_SIZE;
+        final byte rank = (byte) data.rank();
+        final int headerSize = MAGIC_SIZE + RANK_SIZE + rank * LENGTH_SIZE;
+        final short[] flatDataArray = data.getAsFlatArray();
+        final byte[] byteArr = new byte[headerSize + SHORT_SIZE * flatDataArray.length];
+        System.arraycopy(magic, 0, byteArr, 0, MAGIC_SIZE);
+        byteArr[RANK_INDEX] = rank;
+        NativeData.copyIntToByte(data.dimensions(), 0, byteArr, LENGTH_INDEX, rank, byteOrder);
+        NativeData.copyShortToByte(flatDataArray, 0, byteArr, headerSize, flatDataArray.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.
@@ -224,6 +368,33 @@ public class NativeTaggedArray
         return shortData;
     }
 
+    /**
+     * Returns the tagged array <var>data</var> as a {@link MDShortArray} or <code>null</code>, if
+     * <var>data</var> is not a tagged (multi-dimensional) short array.
+     */
+    public static MDShortArray tryToShortArray(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];
+        final int[] dimensions = new int[rank];
+        NativeData.copyByteToInt(data, LENGTH_INDEX, dimensions, 0, rank, encoding.getByteOrder());
+        final int length = MDArray.getLength(dimensions);
+        final int headerSize = LENGTH_INDEX + rank * LENGTH_SIZE;
+        if (length * SHORT_SIZE + headerSize != data.length)
+        {
+            return null;
+        }
+        final short[] intData = new short[length];
+        NativeData.copyByteToShort(data, headerSize, intData, 0, intData.length, encoding
+                .getByteOrder());
+        return new MDShortArray(intData, dimensions);
+    }
+
     //
     // Int
     //
@@ -237,7 +408,7 @@ public class NativeTaggedArray
     }
 
     /**
-     * Converts <var>data</var> into a tagged array in native byte order.
+     * Converts <var>data</var> into a tagged array in given byte order.
      */
     public static byte[] toByteArray(int[] data, ByteOrder byteOrder)
     {
@@ -254,6 +425,34 @@ public class NativeTaggedArray
         return byteArr;
     }
 
+    /**
+     * Converts <var>data</var> into a tagged array in native byte order.
+     */
+    public static byte[] toByteArray(MDIntArray data)
+    {
+        return toByteArray(data, NATIVE_BYTE_ORDER);
+    }
+
+    /**
+     * Converts <var>data</var> into a tagged array in given byte order.
+     */
+    public static byte[] toByteArray(MDIntArray data, ByteOrder byteOrder)
+    {
+        final byte[] magic =
+                NativeArrayEncoding.tryGetIntEncoding(byteOrder, (byte) INT_SIZE).getMagic();
+        assert magic.length == MAGIC_SIZE;
+        final byte rank = (byte) data.rank();
+        final int headerSize = MAGIC_SIZE + RANK_SIZE + rank * LENGTH_SIZE;
+        final int[] flatDataArray = data.getAsFlatArray();
+        final byte[] byteArr = new byte[headerSize + INT_SIZE * flatDataArray.length];
+        System.arraycopy(magic, 0, byteArr, 0, MAGIC_SIZE);
+        byteArr[RANK_INDEX] = rank;
+        NativeData.copyIntToByte(data.dimensions(), 0, byteArr, LENGTH_INDEX, rank, byteOrder);
+        NativeData.copyIntToByte(flatDataArray, 0, byteArr, headerSize, flatDataArray.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.
@@ -282,6 +481,33 @@ public class NativeTaggedArray
         return intData;
     }
 
+    /**
+     * Returns the tagged array <var>data</var> as a {@link MDIntArray} or <code>null</code>, if
+     * <var>data</var> is not a tagged (multi-dimensional) int array.
+     */
+    public static MDIntArray tryToIntArray(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];
+        final int[] dimensions = new int[rank];
+        NativeData.copyByteToInt(data, LENGTH_INDEX, dimensions, 0, rank, encoding.getByteOrder());
+        final int length = MDArray.getLength(dimensions);
+        final int headerSize = LENGTH_INDEX + rank * LENGTH_SIZE;
+        if (length * INT_SIZE + headerSize != data.length)
+        {
+            return null;
+        }
+        final int[] intData = new int[length];
+        NativeData.copyByteToInt(data, headerSize, intData, 0, intData.length, encoding
+                .getByteOrder());
+        return new MDIntArray(intData, dimensions);
+    }
+
     //
     // Long
     //
@@ -295,7 +521,7 @@ public class NativeTaggedArray
     }
 
     /**
-     * Converts <var>data</var> into a tagged array in native byte order.
+     * Converts <var>data</var> into a tagged array in given byte order.
      */
     public static byte[] toByteArray(long[] data, ByteOrder byteOrder)
     {
@@ -312,6 +538,34 @@ public class NativeTaggedArray
         return byteArr;
     }
 
+    /**
+     * Converts <var>data</var> into a tagged array in native byte order.
+     */
+    public static byte[] toByteArray(MDLongArray data)
+    {
+        return toByteArray(data, NATIVE_BYTE_ORDER);
+    }
+
+    /**
+     * Converts <var>data</var> into a tagged array in given byte order.
+     */
+    public static byte[] toByteArray(MDLongArray data, ByteOrder byteOrder)
+    {
+        final byte[] magic =
+                NativeArrayEncoding.tryGetIntEncoding(byteOrder, (byte) LONG_SIZE).getMagic();
+        assert magic.length == MAGIC_SIZE;
+        final byte rank = (byte) data.rank();
+        final int headerSize = MAGIC_SIZE + RANK_SIZE + rank * LENGTH_SIZE;
+        final long[] flatDataArray = data.getAsFlatArray();
+        final byte[] byteArr = new byte[headerSize + LONG_SIZE * flatDataArray.length];
+        System.arraycopy(magic, 0, byteArr, 0, MAGIC_SIZE);
+        byteArr[RANK_INDEX] = rank;
+        NativeData.copyIntToByte(data.dimensions(), 0, byteArr, LENGTH_INDEX, rank, byteOrder);
+        NativeData.copyLongToByte(flatDataArray, 0, byteArr, headerSize, flatDataArray.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.
@@ -331,14 +585,41 @@ public class NativeTaggedArray
         }
         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)
+        if (dimensions[0] * LONG_SIZE + LENGTH_INDEX + 1 * LENGTH_SIZE != data.length)
         {
             return null;
         }
-        final long[] intData = new long[dimensions[0]];
-        NativeData.copyByteToLong(data, LENGTH_INDEX + LENGTH_SIZE, intData, 0, intData.length,
+        final long[] longData = new long[dimensions[0]];
+        NativeData.copyByteToLong(data, LENGTH_INDEX + LENGTH_SIZE, longData, 0, longData.length,
                 encoding.getByteOrder());
-        return intData;
+        return longData;
+    }
+
+    /**
+     * Returns the tagged array <var>data</var> as a {@link MDLongArray} or <code>null</code>, if
+     * <var>data</var> is not a tagged (multi-dimensional) long array.
+     */
+    public static MDLongArray tryToLongArray(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];
+        final int[] dimensions = new int[rank];
+        NativeData.copyByteToInt(data, LENGTH_INDEX, dimensions, 0, rank, encoding.getByteOrder());
+        final int length = MDArray.getLength(dimensions);
+        final int headerSize = LENGTH_INDEX + rank * LENGTH_SIZE;
+        if (length * LONG_SIZE + headerSize != data.length)
+        {
+            return null;
+        }
+        final long[] longData = new long[length];
+        NativeData.copyByteToLong(data, headerSize, longData, 0, longData.length, encoding
+                .getByteOrder());
+        return new MDLongArray(longData, dimensions);
     }
 
 }
diff --git a/base/sourceTest/java/ch/systemsx/cisd/base/convert/NativeTaggedArrayTests.java b/base/sourceTest/java/ch/systemsx/cisd/base/convert/NativeTaggedArrayTests.java
index 6020274d7f5..5d8c49fd4ff 100644
--- a/base/sourceTest/java/ch/systemsx/cisd/base/convert/NativeTaggedArrayTests.java
+++ b/base/sourceTest/java/ch/systemsx/cisd/base/convert/NativeTaggedArrayTests.java
@@ -24,6 +24,11 @@ import org.testng.annotations.Test;
 
 import ch.systemsx.cisd.base.BuildAndEnvironmentInfo;
 import ch.systemsx.cisd.base.convert.NativeData.ByteOrder;
+import ch.systemsx.cisd.base.mdarray.MDDoubleArray;
+import ch.systemsx.cisd.base.mdarray.MDFloatArray;
+import ch.systemsx.cisd.base.mdarray.MDIntArray;
+import ch.systemsx.cisd.base.mdarray.MDLongArray;
+import ch.systemsx.cisd.base.mdarray.MDShortArray;
 
 import static org.testng.AssertJUnit.*;
 
@@ -65,13 +70,50 @@ public class NativeTaggedArrayTests
         final float[] convertedFloatArr = NativeTaggedArray.tryToFloatArray1D(taggedArr);
         final NativeArrayEncoding encoding = NativeArrayEncoding.tryGetEncoding(taggedArr);
         assertNotNull(encoding);
-        assertEquals(ByteOrder.BIG_ENDIAN, encoding.getByteOrder());
+        assertEquals(nonNativeByteOrder, encoding.getByteOrder());
         assertEquals(4, encoding.getSizeInBytes());
         assertTrue(encoding.isFloatingPoint());
         assertFalse(encoding.isInteger());
         assertTrue(Arrays.equals(floatArr, convertedFloatArr));
     }
 
+    @Test
+    public static void testFloat2DArrayNativeByteOrder()
+    {
+        final MDFloatArray floatArr = new MDFloatArray(new float[]
+            { 1, 2, 3, 4 }, new int[] { 2, 2 });
+        final byte[] taggedArr = NativeTaggedArray.toByteArray(floatArr);
+        assertEquals(4 * 4 + 2 * 4 + 4, taggedArr.length);
+        final MDFloatArray convertedFloatArr = NativeTaggedArray.tryToFloatArray(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(floatArr.equals(convertedFloatArr));
+    }
+
+    @Test
+    public static void testFloat2DArrayNonNativeByteOrder()
+    {
+        final MDFloatArray floatArr = new MDFloatArray(new float[]
+            { 1, 2, 3, 4 }, new int[] { 2, 2 });
+        final ByteOrder nonNativeByteOrder =
+            (NativeData.getNativeByteOrder() == ByteOrder.LITTLE_ENDIAN) ? ByteOrder.BIG_ENDIAN
+                    : ByteOrder.LITTLE_ENDIAN;
+        final byte[] taggedArr = NativeTaggedArray.toByteArray(floatArr, nonNativeByteOrder);
+        assertEquals(4 * 4 + 2 * 4 + 4, taggedArr.length);
+        final MDFloatArray convertedFloatArr = NativeTaggedArray.tryToFloatArray(taggedArr);
+        final NativeArrayEncoding encoding = NativeArrayEncoding.tryGetEncoding(taggedArr);
+        assertNotNull(encoding);
+        assertEquals(nonNativeByteOrder, encoding.getByteOrder());
+        assertEquals(4, encoding.getSizeInBytes());
+        assertTrue(encoding.isFloatingPoint());
+        assertFalse(encoding.isInteger());
+        assertTrue(floatArr.equals(convertedFloatArr));
+    }
+
     @Test
     public static void testDouble1DArrayNativeByteOrder()
     {
@@ -102,13 +144,50 @@ public class NativeTaggedArrayTests
         final double[] convertedDoubleArr = NativeTaggedArray.tryToDoubleArray1D(taggedArr);
         final NativeArrayEncoding encoding = NativeArrayEncoding.tryGetEncoding(taggedArr);
         assertNotNull(encoding);
-        assertEquals(ByteOrder.BIG_ENDIAN, encoding.getByteOrder());
+        assertEquals(nonNativeByteOrder, encoding.getByteOrder());
         assertEquals(8, encoding.getSizeInBytes());
         assertTrue(encoding.isFloatingPoint());
         assertFalse(encoding.isInteger());
         assertTrue(Arrays.equals(doubleArr, convertedDoubleArr));
     }
 
+    @Test
+    public static void testDouble2DArrayNativeByteOrder()
+    {
+        final MDDoubleArray doubleArr = new MDDoubleArray(new double[]
+            { 1, 2, 3, 4 }, new int[] { 2, 2 });
+        final byte[] taggedArr = NativeTaggedArray.toByteArray(doubleArr);
+        assertEquals(4 * 8 + 2 * 4 + 4, taggedArr.length);
+        final MDDoubleArray convertedDoubleArr = NativeTaggedArray.tryToDoubleArray(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(doubleArr.equals(convertedDoubleArr));
+    }
+
+    @Test
+    public static void testDouble2DArrayNonNativeByteOrder()
+    {
+        final MDDoubleArray doubleArr = new MDDoubleArray(new double[]
+            { 1, 2, 3, 4 }, new int[] { 2, 2 });
+        final ByteOrder nonNativeByteOrder =
+            (NativeData.getNativeByteOrder() == ByteOrder.LITTLE_ENDIAN) ? ByteOrder.BIG_ENDIAN
+                    : ByteOrder.LITTLE_ENDIAN;
+        final byte[] taggedArr = NativeTaggedArray.toByteArray(doubleArr, nonNativeByteOrder);
+        assertEquals(4 * 8 + 2 * 4 + 4, taggedArr.length);
+        final MDDoubleArray convertedDoubleArr = NativeTaggedArray.tryToDoubleArray(taggedArr);
+        final NativeArrayEncoding encoding = NativeArrayEncoding.tryGetEncoding(taggedArr);
+        assertNotNull(encoding);
+        assertEquals(nonNativeByteOrder, encoding.getByteOrder());
+        assertEquals(8, encoding.getSizeInBytes());
+        assertTrue(encoding.isFloatingPoint());
+        assertFalse(encoding.isInteger());
+        assertTrue(doubleArr.equals(convertedDoubleArr));
+    }
+
     @Test
     public static void testShort1DArrayNativeByteOrder()
     {
@@ -139,13 +218,50 @@ public class NativeTaggedArrayTests
         final short[] convertedShortArr = NativeTaggedArray.tryToShortArray1D(taggedArr);
         final NativeArrayEncoding encoding = NativeArrayEncoding.tryGetEncoding(taggedArr);
         assertNotNull(encoding);
-        assertEquals(ByteOrder.BIG_ENDIAN, encoding.getByteOrder());
+        assertEquals(nonNativeByteOrder, encoding.getByteOrder());
         assertEquals(2, encoding.getSizeInBytes());
         assertFalse(encoding.isFloatingPoint());
         assertTrue(encoding.isInteger());
         assertTrue(Arrays.equals(shortArr, convertedShortArr));
     }
 
+    @Test
+    public static void testShort2DArrayNativeByteOrder()
+    {
+        final MDShortArray shortArr = new MDShortArray(new short[]
+            { 1, 2, 3, 4 }, new int[] { 2, 2 });
+        final byte[] taggedArr = NativeTaggedArray.toByteArray(shortArr);
+        assertEquals(4 * 2 + 2 * 4 + 4, taggedArr.length);
+        final MDShortArray convertedShortArr = NativeTaggedArray.tryToShortArray(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(shortArr.equals(convertedShortArr));
+    }
+
+    @Test
+    public static void testShort2DArrayNonNativeByteOrder()
+    {
+        final MDShortArray shortArr = new MDShortArray(new short[]
+            { 1, 2, 3, 4 }, new int[] { 2, 2 });
+        final ByteOrder nonNativeByteOrder =
+            (NativeData.getNativeByteOrder() == ByteOrder.LITTLE_ENDIAN) ? ByteOrder.BIG_ENDIAN
+                    : ByteOrder.LITTLE_ENDIAN;
+        final byte[] taggedArr = NativeTaggedArray.toByteArray(shortArr, nonNativeByteOrder);
+        assertEquals(4 * 2 + 2 * 4 + 4, taggedArr.length);
+        final MDShortArray convertedShortArr = NativeTaggedArray.tryToShortArray(taggedArr);
+        final NativeArrayEncoding encoding = NativeArrayEncoding.tryGetEncoding(taggedArr);
+        assertNotNull(encoding);
+        assertEquals(nonNativeByteOrder, encoding.getByteOrder());
+        assertEquals(2, encoding.getSizeInBytes());
+        assertFalse(encoding.isFloatingPoint());
+        assertTrue(encoding.isInteger());
+        assertTrue(shortArr.equals(convertedShortArr));
+    }
+
     @Test
     public static void testInt1DArrayNativeByteOrder()
     {
@@ -176,13 +292,50 @@ public class NativeTaggedArrayTests
         final int[] convertedIntArr = NativeTaggedArray.tryToIntArray1D(taggedArr);
         final NativeArrayEncoding encoding = NativeArrayEncoding.tryGetEncoding(taggedArr);
         assertNotNull(encoding);
-        assertEquals(ByteOrder.BIG_ENDIAN, encoding.getByteOrder());
+        assertEquals(nonNativeByteOrder, encoding.getByteOrder());
         assertEquals(4, encoding.getSizeInBytes());
         assertFalse(encoding.isFloatingPoint());
         assertTrue(encoding.isInteger());
         assertTrue(Arrays.equals(intArr, convertedIntArr));
     }
 
+    @Test
+    public static void testInt2DArrayNativeByteOrder()
+    {
+        final MDIntArray intArr = new MDIntArray(new int[]
+            { 1, 2, 3, 4 }, new int[] { 2, 2 });
+        final byte[] taggedArr = NativeTaggedArray.toByteArray(intArr);
+        assertEquals(4 * 4 + 2 * 4 + 4, taggedArr.length);
+        final MDIntArray convertedIntArr = NativeTaggedArray.tryToIntArray(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(intArr.equals(convertedIntArr));
+    }
+
+    @Test
+    public static void testInt2DArrayNonNativeByteOrder()
+    {
+        final MDIntArray intArr = new MDIntArray(new int[]
+            { 1, 2, 3, 4 }, new int[] { 2, 2 });
+        final ByteOrder nonNativeByteOrder =
+            (NativeData.getNativeByteOrder() == ByteOrder.LITTLE_ENDIAN) ? ByteOrder.BIG_ENDIAN
+                    : ByteOrder.LITTLE_ENDIAN;
+        final byte[] taggedArr = NativeTaggedArray.toByteArray(intArr, nonNativeByteOrder);
+        assertEquals(4 * 4 + 2 * 4 + 4, taggedArr.length);
+        final MDIntArray convertedIntArr = NativeTaggedArray.tryToIntArray(taggedArr);
+        final NativeArrayEncoding encoding = NativeArrayEncoding.tryGetEncoding(taggedArr);
+        assertNotNull(encoding);
+        assertEquals(nonNativeByteOrder, encoding.getByteOrder());
+        assertEquals(4, encoding.getSizeInBytes());
+        assertFalse(encoding.isFloatingPoint());
+        assertTrue(encoding.isInteger());
+        assertTrue(intArr.equals(convertedIntArr));
+    }
+
     @Test
     public static void testLong1DArrayNativeByteOrder()
     {
@@ -213,13 +366,50 @@ public class NativeTaggedArrayTests
         final long[] convertedLongArr = NativeTaggedArray.tryToLongArray1D(taggedArr);
         final NativeArrayEncoding encoding = NativeArrayEncoding.tryGetEncoding(taggedArr);
         assertNotNull(encoding);
-        assertEquals(ByteOrder.BIG_ENDIAN, encoding.getByteOrder());
+        assertEquals(nonNativeByteOrder, encoding.getByteOrder());
         assertEquals(8, encoding.getSizeInBytes());
         assertFalse(encoding.isFloatingPoint());
         assertTrue(encoding.isInteger());
         assertTrue(Arrays.equals(longArr, convertedLongArr));
     }
 
+    @Test
+    public static void testLong2DArrayNativeByteOrder()
+    {
+        final MDLongArray longArr = new MDLongArray(new long[]
+            { 1, 2, 3, 4 }, new int[] { 2, 2 });
+        final byte[] taggedArr = NativeTaggedArray.toByteArray(longArr);
+        assertEquals(4 * 8 + 2 * 4 + 4, taggedArr.length);
+        final MDLongArray convertedLongArr = NativeTaggedArray.tryToLongArray(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(longArr.equals(convertedLongArr));
+    }
+
+    @Test
+    public static void testLong2DArrayNonNativeByteOrder()
+    {
+        final MDLongArray longArr = new MDLongArray(new long[]
+            { 1, 2, 3, 4 }, new int[] { 2, 2 });
+        final ByteOrder nonNativeByteOrder =
+            (NativeData.getNativeByteOrder() == ByteOrder.LITTLE_ENDIAN) ? ByteOrder.BIG_ENDIAN
+                    : ByteOrder.LITTLE_ENDIAN;
+        final byte[] taggedArr = NativeTaggedArray.toByteArray(longArr, nonNativeByteOrder);
+        assertEquals(4 * 8 + 2 * 4 + 4, taggedArr.length);
+        final MDLongArray convertedLongArr = NativeTaggedArray.tryToLongArray(taggedArr);
+        final NativeArrayEncoding encoding = NativeArrayEncoding.tryGetEncoding(taggedArr);
+        assertNotNull(encoding);
+        assertEquals(nonNativeByteOrder, encoding.getByteOrder());
+        assertEquals(8, encoding.getSizeInBytes());
+        assertFalse(encoding.isFloatingPoint());
+        assertTrue(encoding.isInteger());
+        assertTrue(longArr.equals(convertedLongArr));
+    }
+
     private void afterClass()
     {
     }
-- 
GitLab