/****************************************************************************
* NCSA HDF *
* National Comptational Science Alliance *
* University of Illinois at Urbana-Champaign *
* 605 E. Springfield, Champaign IL 61820 *
* *
* For conditions of distribution and use, see the accompanying *
* hdf/COPYING file. *
* *
****************************************************************************/
package ncsa.hdf.hdf5lib;
import java.lang.reflect.*;
import ncsa.hdf.hdf5lib.exceptions.*;
/**
* This is a class for handling multidimensional arrays for
* HDF.
* <p>
* The purpose is to allow the storage and retrieval of
* arbitrary array types containing scientific data.
* <p>
* 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.
* <p>
* This class heavily uses the <a href="./ncsa.hdf.hdf5lib.HDFNativeData.html">HDFNativeData</a>
* 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.
* <P>
* The input is analysed to determine the number of dimensions
* and size of each dimension, as well as the type of the elements.
* <P>
* The description is saved in private variables, and used to
* convert data.
*
* @exception ncsa.hdf.hdf5lib.exception.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 ncsa.hdf.hdf5lib.exception.HDF5JavaException Allocation failed.
*/
public byte[] emptyBytes()
throws HDF5Exception
{
byte[] b = new byte[_desc.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 ncsa.hdf.hdf5lib.exception.HDF5Exception thrown for errors in HDF5
* @exception ncsa.hdf.hdf5lib.exception.HDF5JavaException the object not an array or other internal error.
*/
public byte[] byteify() throws HDF5Exception
{
if (_barray != null) return _barray;
if (_theArray == null) {
/* exception: not an array */
HDF5JavaException ex = new HDF5JavaException("HDFArray: byteify not an array?: ");
throw(ex);
}
if (_desc.dims == 1) {
/* special case */
if (_desc.NT == 'B') {
/* really special case! */
_barray = (byte [])_theArray;
return _barray;
} else {
try {
_barray = new byte[_desc.totalSize];
byte [] therow;
if (_desc.NT == 'I') {
therow = HDFNativeData.intToByte(0,_desc.dimlen[1],(int [])_theArray);
} else if (_desc.NT == 'S') {
therow = HDFNativeData.shortToByte(0,_desc.dimlen[1],(short [])_theArray);
} else if (_desc.NT == 'F') {
therow = HDFNativeData.floatToByte(0,_desc.dimlen[1],(float [])_theArray);
} else if (_desc.NT == 'J') {
therow = HDFNativeData.longToByte(0,_desc.dimlen[1],(long [])_theArray);
} else if (_desc.NT == 'D') {
therow = HDFNativeData.doubleToByte(0,_desc.dimlen[1],(double [])_theArray);
} else if (_desc.NT == 'L') {
if (_desc.className.equals("java.lang.Byte")) {
therow = ByteObjToByte((Byte[])_theArray);
} else if (_desc.className.equals("java.lang.Integer")) {
therow = IntegerToByte((Integer[])_theArray);
} else if (_desc.className.equals("java.lang.Short")) {
therow = ShortToByte((Short[])_theArray);
} else if (_desc.className.equals("java.lang.Float")) {
therow = FloatObjToByte((Float[])_theArray);
} else if (_desc.className.equals("java.lang.Double")) {
therow = DoubleObjToByte((Double[])_theArray);
} else if (_desc.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,(_desc.dimlen[1] * _desc.NTsize));
return _barray;
} catch (OutOfMemoryError err) {
HDF5JavaException ex =
new HDF5JavaException("HDFArray: byteify array too big?");
throw(ex);
}
}
}
try {
_barray = new byte[_desc.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 < _desc.totalSize ) {
oo = _desc.objs[0];
index = n / _desc.bytetoindex[0];
index %= _desc.dimlen[0];
for (i = 0 ; i < (_desc.dims); i++) {
index = n / _desc.bytetoindex[i];
index %= _desc.dimlen[i];
if (index == _desc.currentindex[i]) {
/* then use cached copy */
oo = _desc.objs[i];
} else {
/* check range of index */
if (index > (_desc.dimlen[i] - 1)) {
throw new java.lang.IndexOutOfBoundsException("HDFArray: byteify index OOB?");
}
oo = java.lang.reflect.Array.get((Object) oo,index);
_desc.currentindex[i] = index;
_desc.objs[i] = oo;
}
}
/* byte-ify */
byte arow[];
try {
if (_desc.NT == 'J') {
arow = HDFNativeData.longToByte(0,_desc.dimlen[_desc.dims],(long [])_desc.objs[_desc.dims - 1]);
arow = HDFNativeData.longToByte(0,_desc.dimlen[_desc.dims],(long [])_desc.objs[_desc.dims - 1]);
} else if (_desc.NT == 'I') {
arow = HDFNativeData.intToByte(0,_desc.dimlen[_desc.dims],(int [])_desc.objs[_desc.dims - 1]);
} else if (_desc.NT == 'S') {
arow = HDFNativeData.shortToByte(0,_desc.dimlen[_desc.dims],(short [])_desc.objs[_desc.dims - 1]);
} else if (_desc.NT == 'B') {
arow = (byte [])_desc.objs[_desc.dims - 1];
} else if (_desc.NT == 'F') {
/* 32 bit float */
arow = HDFNativeData.floatToByte(0,_desc.dimlen[_desc.dims],(float [])_desc.objs[_desc.dims - 1]);
} else if (_desc.NT == 'D') {
/* 64 bit float */
arow = HDFNativeData.doubleToByte(0,_desc.dimlen[_desc.dims],(double [])_desc.objs[_desc.dims - 1]);
} else if (_desc.NT == 'L') {
if (_desc.className.equals("java.lang.Byte")) {
arow = ByteObjToByte((Byte[])_desc.objs[_desc.dims - 1]);
} else if (_desc.className.equals("java.lang.Integer")) {
arow = IntegerToByte((Integer[])_desc.objs[_desc.dims - 1]);
} else if (_desc.className.equals("java.lang.Short")) {
arow = ShortToByte((Short[])_desc.objs[_desc.dims - 1]);
} else if (_desc.className.equals("java.lang.Float")) {
arow = FloatObjToByte((Float[])_desc.objs[_desc.dims - 1]);
} else if (_desc.className.equals("java.lang.Double")) {
arow = DoubleObjToByte((Double[])_desc.objs[_desc.dims - 1]);
} else if (_desc.className.equals("java.lang.Long")) {
arow = LongObjToByte((Long[])_desc.objs[_desc.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,(_desc.dimlen[_desc.dims] * _desc.NTsize));
n += _desc.bytetoindex[_desc.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 < _desc.totalSize) {
throw new java.lang.InternalError(
new String("HDFArray::byteify: Panic didn't complete all input data: n= "+n+" size = "+_desc.totalSize));
}
for (i = 0;i < _desc.dims; i++) {
if (_desc.currentindex[i] != _desc.dimlen[i] - 1) {
throw new java.lang.InternalError(
new String("Panic didn't complete all data: currentindex["+i+"] = "+_desc.currentindex[i]+" (should be "+(_desc.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 ncsa.hdf.hdf5lib.exception.HDF5Exception thrown for errors in HDF5
* @exception ncsa.hdf.hdf5lib.exception.HDF5JavaException the object not an array or other internal error.
*/
public Object arrayify(byte[] bytes) throws HDF5Exception {
if (_theArray == null) {
/* exception: not an array */
HDF5JavaException ex =
new HDF5JavaException("arrayify: not an array?: ");
throw(ex);
}
if (java.lang.reflect.Array.getLength((Object) bytes) != _desc.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 (_desc.dims == 1) {
/* special case */
/* 2 data copies here! */
try {
if (_desc.NT == 'I') {
int [] x = (int [])HDFNativeData.byteToInt(_barray);
System.arraycopy(x,0,_theArray,0,_desc.dimlen[1]);
return _theArray;
} else if (_desc.NT == 'S') {
short [] x = HDFNativeData.byteToShort(_barray);
System.arraycopy(x,0,_theArray,0,_desc.dimlen[1]);
return _theArray;
} else if (_desc.NT == 'F') {
float x[] = HDFNativeData.byteToFloat(_barray);
System.arraycopy(x,0,_theArray,0,_desc.dimlen[1]);
return _theArray;
} else if (_desc.NT == 'J') {
long x[] = HDFNativeData.byteToLong(_barray);
System.arraycopy(x,0,_theArray,0,_desc.dimlen[1]);
return _theArray;
} else if (_desc.NT == 'D') {
double x[] = HDFNativeData.byteToDouble(_barray);
System.arraycopy(x,0,_theArray,0,_desc.dimlen[1]);
return _theArray;
} else if (_desc.NT == 'B') {
System.arraycopy(_barray,0,_theArray,0,_desc.dimlen[1]);
return _theArray;
} else if (_desc.NT == 'L') {
if (_desc.className.equals("java.lang.Byte")) {
Byte I[] = ByteToByteObj(_barray);
System.arraycopy(I,0,_theArray,0,_desc.dimlen[1]);
return _theArray;
} else if (_desc.className.equals("java.lang.Integer")) {
Integer I[] = ByteToInteger(_barray);
System.arraycopy(I,0,_theArray,0,_desc.dimlen[1]);
return _theArray;
} else if (_desc.className.equals("java.lang.Short")) {
Short I[] = ByteToShort(_barray);
System.arraycopy(I,0,_theArray,0,_desc.dimlen[1]);
return _theArray;
} else if (_desc.className.equals("java.lang.Float")) {
Float I[] = ByteToFloatObj(_barray);
System.arraycopy(I,0,_theArray,0,_desc.dimlen[1]);
return _theArray;
} else if (_desc.className.equals("java.lang.Double")) {
Double I[] = ByteToDoubleObj(_barray);
System.arraycopy(I,0,_theArray,0,_desc.dimlen[1]);
return _theArray;
} else if (_desc.className.equals("java.lang.Long")) {
Long I[] = ByteToLongObj(_barray);
System.arraycopy(I,0,_theArray,0,_desc.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 index = 0;
int i;
while ( n < _desc.totalSize ) {
oo = _desc.objs[0];
index = n / _desc.bytetoindex[0];
index %= _desc.dimlen[0];
for (i = 0 ; i < (_desc.dims); i++) {
index = n / _desc.bytetoindex[i];
index %= _desc.dimlen[i];
if (index == _desc.currentindex[i]) {
/* then use cached copy */
oo = _desc.objs[i];
} else {
/* check range of index */
if (index > (_desc.dimlen[i] - 1)) {
System.out.println("out of bounds?");
return null;
}
oo = java.lang.reflect.Array.get((Object) oo,index);
_desc.currentindex[i] = index;
_desc.objs[i] = oo;
}
}
/* array-ify */
try {
if (_desc.NT == 'J') {
long [] arow = HDFNativeData.byteToLong(n,_desc.dimlen[_desc.dims],_barray);
java.lang.reflect.Array.set(_desc.objs[_desc.dims - 2] ,
(_desc.currentindex[_desc.dims - 1]), (Object)arow);
n += _desc.bytetoindex[_desc.dims - 1];
_desc.currentindex[_desc.dims - 1]++;
} else if (_desc.NT == 'I') {
int [] arow = HDFNativeData.byteToInt(n,_desc.dimlen[_desc.dims],_barray);
java.lang.reflect.Array.set(_desc.objs[_desc.dims - 2] ,
(_desc.currentindex[_desc.dims - 1]), (Object)arow);
n += _desc.bytetoindex[_desc.dims - 1];
_desc.currentindex[_desc.dims - 1]++;
} else if (_desc.NT == 'S') {
short [] arow = HDFNativeData.byteToShort(n,_desc.dimlen[_desc.dims],_barray);
java.lang.reflect.Array.set(_desc.objs[_desc.dims - 2] ,
(_desc.currentindex[_desc.dims - 1]), (Object)arow);
n += _desc.bytetoindex[_desc.dims - 1];
_desc.currentindex[_desc.dims - 1]++;
} else if (_desc.NT == 'B') {
System.arraycopy( _barray, n, _desc.objs[_desc.dims - 1], 0, _desc.dimlen[_desc.dims]);
n += _desc.bytetoindex[_desc.dims - 1];
} else if (_desc.NT == 'F') {
float arow[] = HDFNativeData.byteToFloat(n,_desc.dimlen[_desc.dims],_barray);
java.lang.reflect.Array.set(_desc.objs[_desc.dims - 2] ,
(_desc.currentindex[_desc.dims - 1]), (Object)arow);
n += _desc.bytetoindex[_desc.dims - 1];
_desc.currentindex[_desc.dims - 1]++;
} else if (_desc.NT == 'D') {
double [] arow = HDFNativeData.byteToDouble(n,_desc.dimlen[_desc.dims],_barray);
java.lang.reflect.Array.set(_desc.objs[_desc.dims - 2] ,
(_desc.currentindex[_desc.dims - 1]), (Object)arow);
n += _desc.bytetoindex[_desc.dims - 1];
_desc.currentindex[_desc.dims - 1]++;
} else if (_desc.NT == 'L') {
if (_desc.className.equals("java.lang.Byte")) {
Byte I[] = ByteToByteObj(n,_desc.dimlen[_desc.dims],_barray);
java.lang.reflect.Array.set(_desc.objs[_desc.dims - 2] ,
(_desc.currentindex[_desc.dims - 1]),
(Object)I);
n += _desc.bytetoindex[_desc.dims - 1];
_desc.currentindex[_desc.dims - 1]++;
} else if (_desc.className.equals("java.lang.Integer")) {
Integer I[] = ByteToInteger(n,_desc.dimlen[_desc.dims],_barray);
java.lang.reflect.Array.set(_desc.objs[_desc.dims - 2] ,
(_desc.currentindex[_desc.dims - 1]),
(Object)I);
n += _desc.bytetoindex[_desc.dims - 1];
_desc.currentindex[_desc.dims - 1]++;
} else if (_desc.className.equals("java.lang.Short")) {
Short I[] = ByteToShort(n,_desc.dimlen[_desc.dims],_barray);
java.lang.reflect.Array.set(_desc.objs[_desc.dims - 2] ,
(_desc.currentindex[_desc.dims - 1]),
(Object)I);
n += _desc.bytetoindex[_desc.dims - 1];
_desc.currentindex[_desc.dims - 1]++;
} else if (_desc.className.equals("java.lang.Float")) {
Float I[] = ByteToFloatObj(n,_desc.dimlen[_desc.dims],_barray);
java.lang.reflect.Array.set(_desc.objs[_desc.dims - 2] ,
(_desc.currentindex[_desc.dims - 1]),
(Object)I);
n += _desc.bytetoindex[_desc.dims - 1];
_desc.currentindex[_desc.dims - 1]++;
} else if (_desc.className.equals("java.lang.Double")) {
Double I[] = ByteToDoubleObj(n,_desc.dimlen[_desc.dims],_barray);
java.lang.reflect.Array.set(_desc.objs[_desc.dims - 2] ,
(_desc.currentindex[_desc.dims - 1]),
(Object)I);
n += _desc.bytetoindex[_desc.dims - 1];
_desc.currentindex[_desc.dims - 1]++;
} else if (_desc.className.equals("java.lang.Long")) {
Long I[] = ByteToLongObj(n,_desc.dimlen[_desc.dims],_barray);
java.lang.reflect.Array.set(_desc.objs[_desc.dims - 2] ,
(_desc.currentindex[_desc.dims - 1]),
(Object)I);
n += _desc.bytetoindex[_desc.dims - 1];
_desc.currentindex[_desc.dims - 1]++;
} else {
HDF5JavaException ex =
new HDF5JavaException("HDFArray: unsupported Object type: "+_desc.NT);
throw(ex);
}
} else {
HDF5JavaException ex =
new HDF5JavaException("HDFArray: unknown or unsupported type: "+_desc.NT);
throw(ex);
}
} 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 < _desc.totalSize) {
throw new java.lang.InternalError(
new String("HDFArray::byteify Panic didn't complete all input data: n= "+n+" size = "+_desc.totalSize));
}
for (i = 0;i <= _desc.dims-2; i++) {
if (_desc.currentindex[i] != _desc.dimlen[i] - 1) {
throw new java.lang.InternalError(
new String("HDFArray::byteify Panic didn't complete all data: currentindex["+i+"] = "+_desc.currentindex[i]+" (should be "+(_desc.dimlen[i] - 1)+"?"));
}
}
if (_desc.NT != 'B') {
if (_desc.currentindex[_desc.dims - 1] != _desc.dimlen[_desc.dims - 1]) {
throw new java.lang.InternalError(
new String("HDFArray::byteify Panic didn't complete all data: currentindex["+i+"] = "+_desc.currentindex[i]+" (should be "+(_desc.dimlen[i])+"?"));
}
} else {
if (_desc.currentindex[_desc.dims - 1] != (_desc.dimlen[_desc.dims - 1] - 1)) {
throw new java.lang.InternalError(
new String("HDFArray::byteify Panic didn't complete all data: currentindex["+i+"] = "+_desc.currentindex[i]+" (should be "+(_desc.dimlen[i] - 1)+"?"));
}
}
return _theArray;
}
private byte[] IntegerToByte( Integer in[] ) {
int nelems = java.lang.reflect.Array.getLength((Object)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[] = (int [])HDFNativeData.byteToInt(bin);
int nelems = java.lang.reflect.Array.getLength((Object)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[] = (int [])HDFNativeData.byteToInt(start,len,bin);
int nelems = java.lang.reflect.Array.getLength((Object)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((Object)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[] = (short [])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.
* <p>
* 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 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();
/* To do: extend to deal with Integer, Short, etc. */
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")) {
throw new HDF5JavaException(new String("ArrayDesciptor: Error: String array not 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 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;
}
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)");
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);
}
}
}