/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Copyright by The HDF Group. * * Copyright by the Board of Trustees of the University of Illinois. * * All rights reserved. * * * * This file is part of HDF5. The full HDF5 copyright notice, including * * terms governing use, modification, and redistribution, is contained in * * the COPYING file, which can be found at the root of the source code * * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * * If you do not have access to either file, you may request a copy from * * help@hdfgroup.org. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ package hdf.hdf5lib; import hdf.hdf5lib.exceptions.HDF5Exception; import hdf.hdf5lib.exceptions.HDF5JavaException; import java.util.Arrays; /** * This is a class for handling multidimensional arrays for HDF. *
* The purpose is to allow the storage and retrieval of arbitrary array types * containing scientific data. *
* The methods support the conversion of an array to and from Java to a * one-dimensional array of bytes suitable for I/O by the C library. *
* This class heavily uses the HDFNativeData class to * convert between Java and C representations. */ public class HDFArray { private Object _theArray = null; private ArrayDescriptor _desc = null; private byte[] _barray = null; // public HDFArray() {} /** * The input must be a Java Array (possibly multidimensional) of primitive * numbers or sub-classes of Number. *
* The input is analysed to determine the number of dimensions and size of * each dimension, as well as the type of the elements. *
* The description is saved in private variables, and used to convert data. * * @param anArray * The array object. * * @exception hdf.hdf5lib.exceptions.HDF5Exception * object is not an array. */ public HDFArray(Object anArray) throws HDF5Exception { if (anArray == null) { HDF5JavaException ex = new HDF5JavaException( "HDFArray: array is null?: "); } Class tc = anArray.getClass(); if (tc.isArray() == false) { /* exception: not an array */ HDF5JavaException ex = new HDF5JavaException( "HDFArray: not an array?: "); throw (ex); } _theArray = anArray; _desc = new ArrayDescriptor(_theArray); /* extra error checking -- probably not needed */ if (_desc == null) { HDF5JavaException ex = new HDF5JavaException( "HDFArray: internal error: array description failed?: "); throw (ex); } } /** * Allocate a one-dimensional array of bytes sufficient to store the array. * * @return A one-D array of bytes, filled with zeroes. The bytes are * sufficient to hold the data of the Array passed to the * constructor. * @exception hdf.hdf5lib.exceptions.HDF5JavaException * Allocation failed. */ public byte[] emptyBytes() throws HDF5JavaException { byte[] b = null; if ((ArrayDescriptor.dims == 1) && (ArrayDescriptor.NT == 'B')) { b = (byte[]) _theArray; } else { b = new byte[ArrayDescriptor.totalSize]; } if (b == null) { HDF5JavaException ex = new HDF5JavaException( "HDFArray: emptyBytes: allocation failed"); throw (ex); } return (b); } /** * Given a Java array of numbers, convert it to a one-dimensional array of * bytes in correct native order. * * @return A one-D array of bytes, constructed from the Array passed to the * constructor. * @exception hdf.hdf5lib.exceptions.HDF5JavaException * the object not an array or other internal error. */ public byte[] byteify() throws HDF5JavaException { if (_barray != null) { return _barray; } if (_theArray == null) { /* exception: not an array */ HDF5JavaException ex = new HDF5JavaException( "HDFArray: byteify not an array?: "); throw (ex); } if (ArrayDescriptor.dims == 1) { /* special case */ if (ArrayDescriptor.NT == 'B') { /* really special case! */ _barray = (byte[]) _theArray; return _barray; } else { try { _barray = new byte[ArrayDescriptor.totalSize]; byte[] therow; if (ArrayDescriptor.NT == 'I') { therow = HDFNativeData.intToByte(0, ArrayDescriptor.dimlen[1], (int[]) _theArray); } else if (ArrayDescriptor.NT == 'S') { therow = HDFNativeData.shortToByte(0, ArrayDescriptor.dimlen[1], (short[]) _theArray); } else if (ArrayDescriptor.NT == 'F') { therow = HDFNativeData.floatToByte(0, ArrayDescriptor.dimlen[1], (float[]) _theArray); } else if (ArrayDescriptor.NT == 'J') { therow = HDFNativeData.longToByte(0, ArrayDescriptor.dimlen[1], (long[]) _theArray); } else if (ArrayDescriptor.NT == 'D') { therow = HDFNativeData .doubleToByte(0, ArrayDescriptor.dimlen[1], (double[]) _theArray); } else if (ArrayDescriptor.NT == 'L') { if (ArrayDescriptor.className.equals("java.lang.Byte")) { therow = ByteObjToByte((Byte[]) _theArray); } else if (ArrayDescriptor.className .equals("java.lang.Integer")) { therow = IntegerToByte((Integer[]) _theArray); } else if (ArrayDescriptor.className .equals("java.lang.Short")) { therow = ShortToByte((Short[]) _theArray); } else if (ArrayDescriptor.className .equals("java.lang.Float")) { therow = FloatObjToByte((Float[]) _theArray); } else if (ArrayDescriptor.className .equals("java.lang.Double")) { therow = DoubleObjToByte((Double[]) _theArray); } else if (ArrayDescriptor.className .equals("java.lang.Long")) { therow = LongObjToByte((Long[]) _theArray); } else { HDF5JavaException ex = new HDF5JavaException( "HDFArray: unknown type of Object?"); throw (ex); } } else { HDF5JavaException ex = new HDF5JavaException( "HDFArray: unknown type of data?"); throw (ex); } System .arraycopy( therow, 0, _barray, 0, (ArrayDescriptor.dimlen[1] * ArrayDescriptor.NTsize)); return _barray; } catch (OutOfMemoryError err) { HDF5JavaException ex = new HDF5JavaException( "HDFArray: byteify array too big?"); throw (ex); } } } try { _barray = new byte[ArrayDescriptor.totalSize]; } catch (OutOfMemoryError err) { HDF5JavaException ex = new HDF5JavaException( "HDFArray: byteify array too big?"); throw (ex); } Object oo = _theArray; int n = 0; /* the current byte */ int index = 0; int i; while (n < ArrayDescriptor.totalSize) { oo = ArrayDescriptor.objs[0]; index = n / ArrayDescriptor.bytetoindex[0]; index %= ArrayDescriptor.dimlen[0]; for (i = 0; i < (ArrayDescriptor.dims); i++) { index = n / ArrayDescriptor.bytetoindex[i]; index %= ArrayDescriptor.dimlen[i]; if (index == ArrayDescriptor.currentindex[i]) { /* then use cached copy */ oo = ArrayDescriptor.objs[i]; } else { /* check range of index */ if (index > (ArrayDescriptor.dimlen[i] - 1)) { throw new java.lang.IndexOutOfBoundsException( "HDFArray: byteify index OOB?"); } oo = java.lang.reflect.Array.get(oo, index); ArrayDescriptor.currentindex[i] = index; ArrayDescriptor.objs[i] = oo; } } /* byte-ify */ byte arow[]; try { if (ArrayDescriptor.NT == 'J') { arow = HDFNativeData .longToByte( 0, ArrayDescriptor.dimlen[ArrayDescriptor.dims], (long[]) ArrayDescriptor.objs[ArrayDescriptor.dims - 1]); arow = HDFNativeData .longToByte( 0, ArrayDescriptor.dimlen[ArrayDescriptor.dims], (long[]) ArrayDescriptor.objs[ArrayDescriptor.dims - 1]); } else if (ArrayDescriptor.NT == 'I') { arow = HDFNativeData .intToByte( 0, ArrayDescriptor.dimlen[ArrayDescriptor.dims], (int[]) ArrayDescriptor.objs[ArrayDescriptor.dims - 1]); } else if (ArrayDescriptor.NT == 'S') { arow = HDFNativeData .shortToByte( 0, ArrayDescriptor.dimlen[ArrayDescriptor.dims], (short[]) ArrayDescriptor.objs[ArrayDescriptor.dims - 1]); } else if (ArrayDescriptor.NT == 'B') { arow = (byte[]) ArrayDescriptor.objs[ArrayDescriptor.dims - 1]; } else if (ArrayDescriptor.NT == 'F') { /* 32 bit float */ arow = HDFNativeData .floatToByte( 0, ArrayDescriptor.dimlen[ArrayDescriptor.dims], (float[]) ArrayDescriptor.objs[ArrayDescriptor.dims - 1]); } else if (ArrayDescriptor.NT == 'D') { /* 64 bit float */ arow = HDFNativeData .doubleToByte( 0, ArrayDescriptor.dimlen[ArrayDescriptor.dims], (double[]) ArrayDescriptor.objs[ArrayDescriptor.dims - 1]); } else if (ArrayDescriptor.NT == 'L') { if (ArrayDescriptor.className.equals("java.lang.Byte")) { arow = ByteObjToByte((Byte[]) ArrayDescriptor.objs[ArrayDescriptor.dims - 1]); } else if (ArrayDescriptor.className .equals("java.lang.Integer")) { arow = IntegerToByte((Integer[]) ArrayDescriptor.objs[ArrayDescriptor.dims - 1]); } else if (ArrayDescriptor.className .equals("java.lang.Short")) { arow = ShortToByte((Short[]) ArrayDescriptor.objs[ArrayDescriptor.dims - 1]); } else if (ArrayDescriptor.className .equals("java.lang.Float")) { arow = FloatObjToByte((Float[]) ArrayDescriptor.objs[ArrayDescriptor.dims - 1]); } else if (ArrayDescriptor.className .equals("java.lang.Double")) { arow = DoubleObjToByte((Double[]) ArrayDescriptor.objs[ArrayDescriptor.dims - 1]); } else if (ArrayDescriptor.className.equals("java.lang.Long")) { arow = LongObjToByte((Long[]) ArrayDescriptor.objs[ArrayDescriptor.dims - 1]); } else { HDF5JavaException ex = new HDF5JavaException( "HDFArray: byteify Object type not implemented?"); throw (ex); } } else { HDF5JavaException ex = new HDF5JavaException( "HDFArray: byteify unknown type not implemented?"); throw (ex); } System .arraycopy( arow, 0, _barray, n, (ArrayDescriptor.dimlen[ArrayDescriptor.dims] * ArrayDescriptor.NTsize)); n += ArrayDescriptor.bytetoindex[ArrayDescriptor.dims - 1]; } catch (OutOfMemoryError err) { HDF5JavaException ex = new HDF5JavaException( "HDFArray: byteify array too big?"); throw (ex); } } /* assert: the whole array is completed--currentindex should == len - 1 */ /* error checks */ if (n < ArrayDescriptor.totalSize) { throw new java.lang.InternalError(new String( "HDFArray::byteify: Panic didn't complete all input data: n= " + n + " size = " + ArrayDescriptor.totalSize)); } for (i = 0; i < ArrayDescriptor.dims; i++) { if (ArrayDescriptor.currentindex[i] != ArrayDescriptor.dimlen[i] - 1) { throw new java.lang.InternalError(new String( "Panic didn't complete all data: currentindex[" + i + "] = " + ArrayDescriptor.currentindex[i] + " (should be " + (ArrayDescriptor.dimlen[i] - 1) + " ?)")); } } return _barray; } /** * Given a one-dimensional array of bytes representing numbers, convert it * to a java array of the shape and size passed to the constructor. * * @param bytes * The bytes to construct the Array. * @return An Array (possibly multidimensional) of primitive or number * objects. * @exception hdf.hdf5lib.exceptions.HDF5JavaException * the object not an array or other internal error. */ public Object arrayify(byte[] bytes) throws HDF5JavaException { if (_theArray == null) { /* exception: not an array */ HDF5JavaException ex = new HDF5JavaException( "arrayify: not an array?: "); throw (ex); } if (java.lang.reflect.Array.getLength(bytes) != ArrayDescriptor.totalSize) { /* exception: array not right size */ HDF5JavaException ex = new HDF5JavaException( "arrayify: array is wrong size?: "); throw (ex); } _barray = bytes; /* hope that the bytes are correct.... */ if (ArrayDescriptor.dims == 1) { /* special case */ /* 2 data copies here! */ try { if (ArrayDescriptor.NT == 'I') { int[] x = HDFNativeData.byteToInt(_barray); System.arraycopy(x, 0, _theArray, 0, ArrayDescriptor.dimlen[1]); return _theArray; } else if (ArrayDescriptor.NT == 'S') { short[] x = HDFNativeData.byteToShort(_barray); System.arraycopy(x, 0, _theArray, 0, ArrayDescriptor.dimlen[1]); return _theArray; } else if (ArrayDescriptor.NT == 'F') { float x[] = HDFNativeData.byteToFloat(_barray); System.arraycopy(x, 0, _theArray, 0, ArrayDescriptor.dimlen[1]); return _theArray; } else if (ArrayDescriptor.NT == 'J') { long x[] = HDFNativeData.byteToLong(_barray); System.arraycopy(x, 0, _theArray, 0, ArrayDescriptor.dimlen[1]); return _theArray; } else if (ArrayDescriptor.NT == 'D') { double x[] = HDFNativeData.byteToDouble(_barray); System.arraycopy(x, 0, _theArray, 0, ArrayDescriptor.dimlen[1]); return _theArray; } else if (ArrayDescriptor.NT == 'B') { System.arraycopy(_barray, 0, _theArray, 0, ArrayDescriptor.dimlen[1]); return _theArray; } else if (ArrayDescriptor.NT == 'L') { if (ArrayDescriptor.className.equals("java.lang.Byte")) { Byte I[] = ByteToByteObj(_barray); System.arraycopy(I, 0, _theArray, 0, ArrayDescriptor.dimlen[1]); return _theArray; } else if (ArrayDescriptor.className .equals("java.lang.Integer")) { Integer I[] = ByteToInteger(_barray); System.arraycopy(I, 0, _theArray, 0, ArrayDescriptor.dimlen[1]); return _theArray; } else if (ArrayDescriptor.className .equals("java.lang.Short")) { Short I[] = ByteToShort(_barray); System.arraycopy(I, 0, _theArray, 0, ArrayDescriptor.dimlen[1]); return _theArray; } else if (ArrayDescriptor.className .equals("java.lang.Float")) { Float I[] = ByteToFloatObj(_barray); System.arraycopy(I, 0, _theArray, 0, ArrayDescriptor.dimlen[1]); return _theArray; } else if (ArrayDescriptor.className .equals("java.lang.Double")) { Double I[] = ByteToDoubleObj(_barray); System.arraycopy(I, 0, _theArray, 0, ArrayDescriptor.dimlen[1]); return _theArray; } else if (ArrayDescriptor.className.equals("java.lang.Long")) { Long I[] = ByteToLongObj(_barray); System.arraycopy(I, 0, _theArray, 0, ArrayDescriptor.dimlen[1]); return _theArray; } else { HDF5JavaException ex = new HDF5JavaException( "arrayify: Object type not implemented yet..."); throw (ex); } } else { HDF5JavaException ex = new HDF5JavaException( "arrayify: unknown type not implemented yet..."); throw (ex); } } catch (OutOfMemoryError err) { HDF5JavaException ex = new HDF5JavaException( "HDFArray: arrayify array too big?"); throw (ex); } } /* Assert dims >= 2 */ Object oo = _theArray; int n = 0; /* the current byte */ int m = 0; /* the current array index */ int index = 0; int i; Object flattenedArray = null; switch (ArrayDescriptor.NT) { case 'J': flattenedArray = (Object) HDFNativeData.byteToLong(_barray); break; case 'S': flattenedArray = (Object) HDFNativeData.byteToShort(_barray); break; case 'I': flattenedArray = (Object) HDFNativeData.byteToInt(_barray); break; case 'F': flattenedArray = (Object) HDFNativeData.byteToFloat(_barray); break; case 'D': flattenedArray = (Object) HDFNativeData.byteToDouble(_barray); break; case 'B': flattenedArray = (Object) _barray; break; case 'L': switch (ArrayDescriptor.className) { case "java.lang.Byte": flattenedArray = (Object) ByteToByteObj(_barray); break; case "java.lang.Short": flattenedArray = (Object) ByteToShort(_barray); break; case "java.lang.Integer": flattenedArray = (Object) ByteToInteger(_barray); break; case "java.lang.Long": flattenedArray = (Object) ByteToLongObj(_barray); break; case "java.lang.Float": flattenedArray = (Object) ByteToFloatObj(_barray); break; case "java.lang.Double": flattenedArray = (Object) ByteToDoubleObj(_barray); break; default: HDF5JavaException ex = new HDF5JavaException( "HDFArray: unsupported Object type: " + ArrayDescriptor.NT); throw (ex); } // end of switch statement for arrays of boxed objects default: HDF5JavaException ex = new HDF5JavaException( "HDFArray: unknown or unsupported type: " + ArrayDescriptor.NT); throw (ex); } // end of switch statement for arrays of primitives while (n < ArrayDescriptor.totalSize) { oo = ArrayDescriptor.objs[0]; index = n / ArrayDescriptor.bytetoindex[0]; index %= ArrayDescriptor.dimlen[0]; for (i = 0; i < (ArrayDescriptor.dims); i++) { index = n / ArrayDescriptor.bytetoindex[i]; index %= ArrayDescriptor.dimlen[i]; if (index == ArrayDescriptor.currentindex[i]) { /* then use cached copy */ oo = ArrayDescriptor.objs[i]; } else { /* check range of index */ if (index > (ArrayDescriptor.dimlen[i] - 1)) { System.out.println("out of bounds?"); return null; } oo = java.lang.reflect.Array.get(oo, index); ArrayDescriptor.currentindex[i] = index; ArrayDescriptor.objs[i] = oo; } } /* array-ify */ try { Object arow = null; int mm = m + ArrayDescriptor.dimlen[ArrayDescriptor.dims]; switch (ArrayDescriptor.NT) { case 'B': arow = (Object) Arrays.copyOfRange((byte[]) flattenedArray, m, mm); break; case 'S': arow = (Object) Arrays.copyOfRange((short[]) flattenedArray, m, mm); break; case 'I': arow = (Object) Arrays.copyOfRange((int[]) flattenedArray, m, mm); break; case 'J': arow = (Object) Arrays.copyOfRange((long[]) flattenedArray, m, mm); break; case 'F': arow = (Object) Arrays.copyOfRange((float[]) flattenedArray, m, mm); break; case 'D': arow = (Object) Arrays.copyOfRange((double[]) flattenedArray, m, mm); break; case 'L': switch (ArrayDescriptor.className) { case "java.lang.Byte": arow = (Object) Arrays.copyOfRange((Byte[])flattenedArray, m, mm); break; case "java.lang.Short": arow = (Object) Arrays.copyOfRange((Short[])flattenedArray, m, mm); break; case "java.lang.Integer": arow = (Object) Arrays.copyOfRange((Integer[])flattenedArray, m, mm); break; case "java.lang.Long": arow = (Object) Arrays.copyOfRange((Long[])flattenedArray, m, mm); break; case "java.lang.Float": arow = (Object) Arrays.copyOfRange((Float[])flattenedArray, m, mm); break; case "java.lang.Double": arow = (Object) Arrays.copyOfRange((Double[])flattenedArray, m, mm); break; } // end of switch statement for arrays of boxed numerics } // end of switch statement for arrays of primitives java.lang.reflect.Array.set( ArrayDescriptor.objs[ArrayDescriptor.dims - 2], (ArrayDescriptor.currentindex[ArrayDescriptor.dims - 1]), arow); n += ArrayDescriptor.bytetoindex[ArrayDescriptor.dims - 1]; ArrayDescriptor.currentindex[ArrayDescriptor.dims - 1]++; m = mm; } catch (OutOfMemoryError err) { HDF5JavaException ex = new HDF5JavaException( "HDFArray: arrayify array too big?"); throw (ex); } } /* assert: the whole array is completed--currentindex should == len - 1 */ /* error checks */ if (n < ArrayDescriptor.totalSize) { throw new java.lang.InternalError(new String( "HDFArray::arrayify Panic didn't complete all input data: n= " + n + " size = " + ArrayDescriptor.totalSize)); } for (i = 0; i <= ArrayDescriptor.dims - 2; i++) { if (ArrayDescriptor.currentindex[i] != ArrayDescriptor.dimlen[i] - 1) { throw new java.lang.InternalError(new String( "HDFArray::arrayify Panic didn't complete all data: currentindex[" + i + "] = " + ArrayDescriptor.currentindex[i] + " (should be " + (ArrayDescriptor.dimlen[i] - 1) + "?")); } } if (ArrayDescriptor.currentindex[ArrayDescriptor.dims - 1] != ArrayDescriptor.dimlen[ArrayDescriptor.dims - 1]) { throw new java.lang.InternalError(new String( "HDFArray::arrayify Panic didn't complete all data: currentindex[" + i + "] = " + ArrayDescriptor.currentindex[i] + " (should be " + (ArrayDescriptor.dimlen[i]) + "?")); } return _theArray; } private byte[] IntegerToByte(Integer in[]) { int nelems = java.lang.reflect.Array.getLength(in); int[] out = new int[nelems]; for (int i = 0; i < nelems; i++) { out[i] = in[i].intValue(); } return HDFNativeData.intToByte(0, nelems, out); } private Integer[] ByteToInteger(byte[] bin) { int in[] = HDFNativeData.byteToInt(bin); int nelems = java.lang.reflect.Array.getLength(in); Integer[] out = new Integer[nelems]; for (int i = 0; i < nelems; i++) { out[i] = new Integer(in[i]); } return out; } private Integer[] ByteToInteger(int start, int len, byte[] bin) { int in[] = HDFNativeData.byteToInt(start, len, bin); int nelems = java.lang.reflect.Array.getLength(in); Integer[] out = new Integer[nelems]; for (int i = 0; i < nelems; i++) { out[i] = new Integer(in[i]); } return out; } private byte[] ShortToByte(Short in[]) { int nelems = java.lang.reflect.Array.getLength(in); short[] out = new short[nelems]; for (int i = 0; i < nelems; i++) { out[i] = in[i].shortValue(); } return HDFNativeData.shortToByte(0, nelems, out); } private Short[] ByteToShort(byte[] bin) { short in[] = HDFNativeData.byteToShort(bin); int nelems = java.lang.reflect.Array.getLength((Object) in); Short[] out = new Short[nelems]; for (int i = 0; i < nelems; i++) { out[i] = new Short(in[i]); } return out; } private Short[] ByteToShort(int start, int len, byte[] bin) { short in[] = (short[]) HDFNativeData.byteToShort(start, len, bin); int nelems = java.lang.reflect.Array.getLength((Object) in); Short[] out = new Short[nelems]; for (int i = 0; i < nelems; i++) { out[i] = new Short(in[i]); } return out; } private byte[] ByteObjToByte(Byte in[]) { int nelems = java.lang.reflect.Array.getLength((Object) in); byte[] out = new byte[nelems]; for (int i = 0; i < nelems; i++) { out[i] = in[i].byteValue(); } return out; } private Byte[] ByteToByteObj(byte[] bin) { int nelems = java.lang.reflect.Array.getLength((Object) bin); Byte[] out = new Byte[nelems]; for (int i = 0; i < nelems; i++) { out[i] = new Byte(bin[i]); } return out; } private Byte[] ByteToByteObj(int start, int len, byte[] bin) { Byte[] out = new Byte[len]; for (int i = 0; i < len; i++) { out[i] = new Byte(bin[i]); } return out; } private byte[] FloatObjToByte(Float in[]) { int nelems = java.lang.reflect.Array.getLength((Object) in); float[] out = new float[nelems]; for (int i = 0; i < nelems; i++) { out[i] = in[i].floatValue(); } return HDFNativeData.floatToByte(0, nelems, out); } private Float[] ByteToFloatObj(byte[] bin) { float in[] = (float[]) HDFNativeData.byteToFloat(bin); int nelems = java.lang.reflect.Array.getLength((Object) in); Float[] out = new Float[nelems]; for (int i = 0; i < nelems; i++) { out[i] = new Float(in[i]); } return out; } private Float[] ByteToFloatObj(int start, int len, byte[] bin) { float in[] = (float[]) HDFNativeData.byteToFloat(start, len, bin); int nelems = java.lang.reflect.Array.getLength((Object) in); Float[] out = new Float[nelems]; for (int i = 0; i < nelems; i++) { out[i] = new Float(in[i]); } return out; } private byte[] DoubleObjToByte(Double in[]) { int nelems = java.lang.reflect.Array.getLength((Object) in); double[] out = new double[nelems]; for (int i = 0; i < nelems; i++) { out[i] = in[i].doubleValue(); } return HDFNativeData.doubleToByte(0, nelems, out); } private Double[] ByteToDoubleObj(byte[] bin) { double in[] = (double[]) HDFNativeData.byteToDouble(bin); int nelems = java.lang.reflect.Array.getLength((Object) in); Double[] out = new Double[nelems]; for (int i = 0; i < nelems; i++) { out[i] = new Double(in[i]); } return out; } private Double[] ByteToDoubleObj(int start, int len, byte[] bin) { double in[] = (double[]) HDFNativeData.byteToDouble(start, len, bin); int nelems = java.lang.reflect.Array.getLength((Object) in); Double[] out = new Double[nelems]; for (int i = 0; i < nelems; i++) { out[i] = new Double(in[i]); } return out; } private byte[] LongObjToByte(Long in[]) { int nelems = java.lang.reflect.Array.getLength((Object) in); long[] out = new long[nelems]; for (int i = 0; i < nelems; i++) { out[i] = in[i].longValue(); } return HDFNativeData.longToByte(0, nelems, out); } private Long[] ByteToLongObj(byte[] bin) { long in[] = (long[]) HDFNativeData.byteToLong(bin); int nelems = java.lang.reflect.Array.getLength((Object) in); Long[] out = new Long[nelems]; for (int i = 0; i < nelems; i++) { out[i] = new Long(in[i]); } return out; } private Long[] ByteToLongObj(int start, int len, byte[] bin) { long in[] = (long[]) HDFNativeData.byteToLong(start, len, bin); int nelems = java.lang.reflect.Array.getLength((Object) in); Long[] out = new Long[nelems]; for (int i = 0; i < nelems; i++) { out[i] = new Long(in[i]); } return out; } } /** * This private class is used by HDFArray to discover the shape and type of an * arbitrary array. *
* We use java.lang.reflection here. */ class ArrayDescriptor { static String theType = ""; static Class theClass = null; static int[] dimlen = null; static int[] dimstart = null; static int[] currentindex = null; static int[] bytetoindex = null; static int totalSize = 0; static int totalElements = 0; static Object[] objs = null; static char NT = ' '; /* must be B,S,I,L,F,D, else error */ static int NTsize = 0; static int dims = 0; static String className; public ArrayDescriptor(Object anArray) throws HDF5Exception { Class tc = anArray.getClass(); if (tc.isArray() == false) { /* exception: not an array */ HDF5Exception ex = new HDF5JavaException( "ArrayDescriptor: not an array?: "); throw (ex); } theClass = tc; /* * parse the type descriptor to discover the shape of the array */ String ss = tc.toString(); theType = ss; int n = 6; dims = 0; char c = ' '; while (n < ss.length()) { c = ss.charAt(n); n++; if (c == '[') { dims++; } } String css = ss.substring(ss.lastIndexOf('[') + 1); Class compC = tc.getComponentType(); String cs = compC.toString(); NT = c; /* must be B,S,I,L,F,D, else error */ if (NT == 'B') { NTsize = 1; } else if (NT == 'S') { NTsize = 2; } else if ((NT == 'I') || (NT == 'F')) { NTsize = 4; } else if ((NT == 'J') || (NT == 'D')) { NTsize = 8; } else if (css.startsWith("Ljava.lang.Byte")) { NT = 'L'; className = "java.lang.Byte"; NTsize = 1; } else if (css.startsWith("Ljava.lang.Short")) { NT = 'L'; className = "java.lang.Short"; NTsize = 2; } else if (css.startsWith("Ljava.lang.Integer")) { NT = 'L'; className = "java.lang.Integer"; NTsize = 4; } else if (css.startsWith("Ljava.lang.Float")) { NT = 'L'; className = "java.lang.Float"; NTsize = 4; } else if (css.startsWith("Ljava.lang.Double")) { NT = 'L'; className = "java.lang.Double"; NTsize = 8; } else if (css.startsWith("Ljava.lang.Long")) { NT = 'L'; className = "java.lang.Long"; NTsize = 8; } else if (css.startsWith("Ljava.lang.String")) { NT = 'L'; className = "java.lang.String"; NTsize = 1; throw new HDF5JavaException(new String( "ArrayDesciptor: Warning: String array not fully supported yet")); } else { /* * exception: not a numeric type */ throw new HDF5JavaException(new String( "ArrayDesciptor: Error: array is not numeric (type is " + css + ") ?")); } /* fill in the table */ dimlen = new int[dims + 1]; dimstart = new int[dims + 1]; currentindex = new int[dims + 1]; bytetoindex = new int[dims + 1]; objs = new Object[dims + 1]; Object o = anArray; objs[0] = o; dimlen[0] = 1; dimstart[0] = 0; currentindex[0] = 0; int elements = 1; int i; for (i = 1; i <= dims; i++) { dimlen[i] = java.lang.reflect.Array.getLength((Object) o); o = java.lang.reflect.Array.get((Object) o, 0); objs[i] = o; dimstart[i] = 0; currentindex[i] = 0; elements *= dimlen[i]; } totalElements = elements; int j; int dd; bytetoindex[dims] = NTsize; for (i = dims; i >= 0; i--) { dd = NTsize; for (j = i; j < dims; j++) { dd *= dimlen[j + 1]; } bytetoindex[i] = dd; } totalSize = bytetoindex[0]; } /** * Debug dump */ public void dumpInfo() { System.out.println("Type: " + theType); System.out.println("Class: " + theClass); System.out.println("NT: " + NT + " NTsize: " + NTsize); System.out.println("Array has " + dims + " dimensions (" + totalSize + " bytes, " + totalElements + " elements)"); int i; for (i = 0; i <= dims; i++) { Class tc = objs[i].getClass(); String ss = tc.toString(); System.out.println(i + ": start " + dimstart[i] + ": len " + dimlen[i] + " current " + currentindex[i] + " bytetoindex " + bytetoindex[i] + " object " + objs[i] + " otype " + ss); } } }