// Member of the utility package.
package nom.tam.util;
/* Copyright: Thomas McGlynn 1997-1998.
* This code may be used for any purpose, non-commercial
* or commercial so long as this copyright notice is retained
* in the source code or included in or referred to in any
* derived software.
*/
import java.lang.reflect.*;
/** This is a package of static functions which perform
* computations on arrays. Generally these routines attempt
* to complete without throwing errors by ignoring data
* they cannot understand.
*/
public class ArrayFuncs {
/** Compute the size of an object. Note that this only handles
* arrays or scalars of the primitive objects and Strings. It
* returns 0 for any object array element it does not understand.
*
* @param o The object whose size is desired.
*/
public static int computeSize(Object o) {
if (o == null) {
return 0;
}
int size = 0;
String classname = o.getClass().getName();
if (classname.substring(0, 2).equals("[[") ||
classname.equals("[Ljava.lang.String;") ||
classname.equals("[Ljava.lang.Object;")) {
for (int i=0; i<((Object[])o).length; i += 1) {
size += computeSize( ((Object[]) o)[i] );
}
return size;
}
if (classname.charAt(0) == '[' && classname.charAt(1) != 'L') {
switch (classname.charAt(1)) {
case 'I': return ((int[])o).length * 4;
case 'J': return ((long[])o).length * 8;
case 'F': return ((float[])o).length* 4;
case 'D': return ((double[])o).length*8;
case 'B': return ((byte[])o).length;
case 'C': return ((char[])o).length * 2;
case 'S': return ((short[])o).length* 2;
case 'Z': return ((boolean[])o).length;
default: return 0;
}
}
if (classname.substring(0,10).equals("java.lang.") ) {
classname = classname.substring(10, classname.length()-1);
if (classname.equals("Int") || classname.equals("Float")) {
return 4;
} else if (classname.equals("Double") || classname.equals("Long")) {
return 8;
} else if (classname.equals("Short") || classname.equals("Char")) {
return 2;
} else if (classname.equals("Byte") || classname.equals("Boolean")) {
return 1;
} else if (classname.equals("String") ) {
return ((String)o).length();
} else {
return 0;
}
}
return 0;
}
/** Try to create a deep clone of an Array or a standard clone of a scalar.
* The object may comprise arrays of
* any primitive type or any Object type which implements Cloneable.
* However, if the Object is some kind of collection, e.g., a Vector
* then only a shallow copy of that object is made. I.e., deep refers
* only to arrays.
*
* @param o The object to be copied.
*/
public static Object deepClone(Object o) {
if (o == null) {
return null;
}
String classname = o.getClass().getName();
// Is this an array?
if (classname.charAt(0) != '[') {
return genericClone(o);
}
// Check if this is a 1D primitive array.
if (classname.charAt(1) != '[' && classname.charAt(1) != 'L') {
try {
// Some compilers (SuperCede, e.g.) still
// think you have to catch this...
if (false) throw new CloneNotSupportedException();
switch( classname.charAt(1) ){
case 'B': return ((byte[])o).clone();
case 'Z': return ((boolean[])o).clone();
case 'C': return ((char[])o).clone();
case 'S': return ((short[])o).clone();
case 'I': return ((int[])o).clone();
case 'J': return ((long[])o).clone();
case 'F': return ((float[])o).clone();
case 'D': return ((double[])o).clone();
default: System.err.println("Unknown primtive array class:"+classname);
return null;
}
} catch (CloneNotSupportedException e) {}
}
// Get the base type.
int ndim = 1;
while (classname.charAt(ndim) == '[') {
ndim += 1;
}
Class baseClass;
if (classname.charAt(ndim) != 'L') {
baseClass = getBaseClass(o);
} else {
try {
baseClass = Class.forName(classname.substring(ndim+1, classname.length()-1));
} catch (ClassNotFoundException e) {
System.err.println("Internal error: class definition inconsistency: "+classname);
return null;
}
}
// Allocate the array but make all but the first dimension 0.
int[] dims = new int[ndim];
dims[0] = Array.getLength(o);
for (int i=1; i<ndim; i += 1) {
dims[i] = 0;
}
Object copy = Array.newInstance(baseClass, dims);
// Now fill in the next level down by recursion.
for (int i=0; i<dims[0]; i += 1) {
Array.set(copy, i, deepClone(Array.get(o, i)));
}
return copy;
}
/** Clone an Object if possible.
*
* This method returns an Object which is a clone of the
* input object. It checks if the method implements the
* Cloneable interface and then uses reflection to invoke
* the clone method. This can't be done directly since
* as far as the compiler is concerned the clone method for
* Object is protected and someone could implement Cloneable but
* leave the clone method protected. The cloning can fail in a
* variety of ways which are trapped so that it returns null instead.
* This method will generally create a shallow clone. If you
* wish a deep copy of an array the method deepClone should be used.
*
* @param o The object to be cloned.
*/
public static Object genericClone(Object o) {
if (! (o instanceof Cloneable) ) {
return null;
}
Class[] argTypes = new Class[0];
Object[] args = new Object[0];
try {
return o.getClass().getMethod("clone", argTypes).invoke(o,args);
} catch (Exception e) {
return null;
}
}
/** Copy one array into another.
* This function copies the contents of one array
* into a previously allocated array.
* The arrays must agree in type and size.
* @param original The array to be copied.
* @param copy The array to be copied into. This
* array must already be fully allocated.
*/
public static void copyArray(Object original, Object copy) {
String oname = original.getClass().getName();
String cname = copy.getClass().getName();
if (! oname.equals(cname)) {
return;
}
if (oname.charAt(0) != '[') {
return;
}
if (oname.charAt(1) == '[') {
Object[] x = (Object[]) original;
Object[] y = (Object[]) copy;
if (x.length != y.length) {
return;
}
for (int i=0; i<x.length; i += 1) {
copyArray(x,y);
}
}
int len = Array.getLength(original);
System.arraycopy(original, 0, copy, 0, len);
}
/** Find the dimensions of an object.
*
* This method returns an integer array with the dimensions
* of the object o which should usually be an array.
*
* It returns an array of dimension 0 for scalar objects
* and it returns -1 for dimension which have not been allocated,
* e.g., int[][][] x = new int[100][][]; should return [100,-1,-1].
*
* @param o The object to get the dimensions of.
*/
public static int[] getDimensions(Object o) {
if (o == null) {
return null;
}
String classname = o.getClass().getName();
int ndim=0;
while (classname.charAt(ndim) == '[') {
ndim += 1;
}
int[] dimens = new int[ndim];
for (int i=0; i<ndim; i += 1) {
dimens[i] = -1; // So that we can distinguish a null from a 0 length.
}
for (int i=0; i < ndim; i += 1) {
dimens[i] = java.lang.reflect.Array.getLength(o);
if (dimens[i] == 0) {
return dimens;
}
if (i != ndim-1) {
o = ((Object[])o)[0];
if (o == null) {
return dimens;
}
}
}
return dimens;
}
/** This routine returns the base class of an object. This is just
* the class of the object for non-arrays.
*/
public static Class getBaseClass(Object o) {
if (o == null) {
return Void.TYPE;
}
String className = o.getClass().getName();
int dims = 0;
while (className.charAt(dims) == '[') {
dims += 1;
}
if (dims == 0) {
return o.getClass();
}
switch (className.charAt(dims) ) {
case 'Z': return Boolean.TYPE;
case 'B': return Byte.TYPE;
case 'S': return Short.TYPE;
case 'C': return Character.TYPE;
case 'I': return Integer.TYPE;
case 'J': return Long.TYPE;
case 'F': return Float.TYPE;
case 'D': return Double.TYPE;
case 'L':
try {
return Class.forName(className.substring(dims+1, className.length()-1));
} catch (ClassNotFoundException e) {
return null;
}
default: return null;
}
}
/** This routine returns the size of the base element of an array.
* @param o The array object whose base length is desired.
* @return the size of the object in bytes, 0 if null, or
* -1 if not a primitive array.
*/
public static int getBaseLength(Object o) {
if (o == null) {
return 0;
}
String className = o.getClass().getName();
int dims = 0;
while (className.charAt(dims) == '[') {
dims += 1;
}
if (dims == 0) {
return -1;
}
switch (className.charAt(dims) ) {
case 'Z': return 1;
case 'B': return 1;
case 'S': return 2;
case 'C': return 2;
case 'I': return 4;
case 'J': return 8;
case 'F': return 4;
case 'D': return 8;
default: return -1;
}
}
/** Create an array and populate it with a test pattern.
*
* @param baseType The base type of the array. This is expected to
* be a numeric type, but this is not checked.
* @param dims The desired dimensions.
* @return An array object populated with a simple test pattern.
*/
public static Object generateArray(Class baseType, int[] dims) {
// Generate an array and populate it with a test pattern of
// data.
Object x = java.lang.reflect.Array.newInstance(baseType, dims);
testPattern(x,(byte)0);
return x;
}
/** Just create a simple pattern cycling through valid byte values.
* We use bytes because they can be cast to any other numeric type.
* @param o The array in which the test pattern is to be set.
* @param start The value for the first element.
*/
public static byte testPattern(Object o, byte start) {
int[] dims = getDimensions(o);
if (dims.length > 1) {
for (int i=0; i < ((Object[])o).length; i += 1) {
start = testPattern(((Object[]) o)[i], start);
}
} else if (dims.length == 1) {
for (int i=0; i < dims[0]; i += 1) {
java.lang.reflect.Array.setByte(o, i, start);
start += 1;
}
}
return start;
}
/** Generate a description of an array (presumed rectangular).
* @param o The array to be described.
*/
public static String arrayDescription(Object o) {
Class base = getBaseClass(o);
if (base == Void.TYPE) {
return "NULL";
}
int[] dims = getDimensions(o);
StringBuffer desc = new StringBuffer();
// Note that all instances Class describing a given class are
// the same so we can use == here.
if (base == Float.TYPE) {
desc.append("float");
} else if (base == Integer.TYPE) {
desc.append("int");
} else if (base == Double.TYPE) {
desc.append("double");
} else if (base == Short.TYPE) {
desc.append("short");
} else if (base == Long.TYPE) {
desc.append("long");
} else if (base == Character.TYPE) {
desc.append("char");
} else if (base == Byte.TYPE) {
desc.append("byte");
} else if (base == Boolean.TYPE) {
desc.append("boolean");
} else {
desc.append(base.getName());
}
if (dims != null) {
desc.append("[");
for (int i=0; i<dims.length; i += 1) {
desc.append(""+dims[i]);
if (i < dims.length-1) {
desc.append(",");
}
}
desc.append("]");
}
return new String(desc);
}
/** Examine the structure of an array in detail.
* @param o The array to be examined.
*/
public static void examinePrimitiveArray(Object o) {
String className = o.getClass().getName();
// If we have a two-d array, or if the array is a one-d array
// of Objects, then recurse over the next dimension. We handle
// Object specially because each element could itself be an array.
if (className.substring(0,2).equals("[[") ||
className.equals("[Ljava.lang.Object;") ) {
System.out.println("[");
for (int i=0; i< ((Object[])o).length; i += 1) {
examinePrimitiveArray(((Object[])o)[i]);
}
System.out.print("]");
} else if (className.charAt(0) != '[') {
System.out.println(className);
} else {
System.out.println("["+java.lang.reflect.Array.getLength(o)+"]"+
className.substring(1));
}
}
/** Given an array of arbitrary dimensionality return
* the array flattened into a single dimension.
* @param input The input array.
*/
public static Object flatten(Object input) {
int[] dimens = getDimensions(input);
if (dimens.length <= 1) {
return input;
}
int size=1;
for (int i=0; i<dimens.length; i += 1) {
size *= dimens[i];
}
Object flat = Array.newInstance(getBaseClass(input), size);
if (size == 0) {
return flat;
}
int offset = 0;
doFlatten(input, flat, offset);
return flat;
}
/** This routine does the actually flattening of multi-dimensional
* arrays.
* @param input The input array to be flattened.
* @param output The flattened array.
* @param offset The current offset within the output array.
* @return The number of elements within the array.
*/
protected static int doFlatten(Object input, Object output, int offset) {
String classname = input.getClass().getName();
if (classname.charAt(0) != '[') {
throw new RuntimeException("Attempt to flatten non-array");
}
int size = Array.getLength(input);
if (classname.charAt(1) != '[') {
System.arraycopy(input, 0, output, offset, size);
return size;
}
int total = 0;
Object[] xx = (Object[]) input;
for(int i=0; i < size; i += 1) {
int len = doFlatten(xx[i], output, offset+total);
total += len;
}
return total;
}
/** Curl an input array up into a multi-dimensional array.
*
* @param input The one dimensional array to be curled.
* @param dimens The desired dimensions
* @return The curled array.
*/
public static Object curl(Object input, int[] dimens) {
String classname= input.getClass().getName();
if (classname.charAt(0) != '[' || classname.charAt(1) == '[') {
throw new RuntimeException("Attempt to curl non-1D array");
}
int size = Array.getLength(input);
int test = 1;
for (int i=0; i<dimens.length; i += 1) {
test *= dimens[i];
}
if (test != size) {
throw new RuntimeException("Curled array does not fit desired dimensions");
}
Class base = getBaseClass(input);
Object newArray = Array.newInstance(base, dimens);
int offset = 0;
doCurl(input, newArray, dimens, offset);
return newArray;
}
/** Do the curling of the 1-d to multi-d array.
* @param input The 1-d array to be curled.
* @param output The multi-dimensional array to be filled.
* @param dimens The desired output dimensions.
* @param offset The current offset in the input array.
* @return The number of elements curled.
*/
protected static int doCurl(Object input, Object output,
int[] dimens, int offset) {
if (dimens.length == 1) {
System.arraycopy(input, offset, output, 0, dimens[0]);
return dimens[0];
}
int total = 0;
int[] xdimens = new int[dimens.length-1];
for (int i=1; i<dimens.length; i +=1) {
xdimens[i-1] = dimens[i];
}
for (int i=0; i<dimens[0]; i += 1) {
total += doCurl(input, ((Object[]) output)[i], xdimens, offset+total);
}
return total;
}
/** Convert an array to a specified type. This method supports conversions
* only among the primitive numeric types.
* @param array A possibly multidimensional array to be converted.
* @param newType The desired output type. This should be one of the
* class descriptors for primitive numeric data, e.g., double.type.
*/
public static Object convertArray(Object array, Class newType) {
String classname = array.getClass().getName();
if (classname.charAt(0) != '[') {
return null;
}
int dims = 1;
while (classname.charAt(dims) == '[') {
dims += 1;
}
Object converted;
if (dims > 1) {
Object[] xarray = (Object[]) array;
int[] dimens = new int[dims];
dimens[0] = xarray.length; // Leave other dimensions at 0.
converted = Array.newInstance(newType, dimens);
for (int i=0; i<xarray.length; i += 1) {
Object temp = convertArray(xarray[i], newType);
((Object[])converted)[i] = temp;
}
} else {
// We have to handle 49 cases below. Only
// the logical primitive type is ignored.
byte[] xbarr;
short[] xsarr;
char[] xcarr;
int[] xiarr;
long[] xlarr;
float[] xfarr;
double[] xdarr;
converted = null;
Class base = getBaseClass(array);
if (base == byte.class) {
byte[] barr = (byte[]) array;
if (newType == byte.class) {
xbarr = new byte[barr.length];
converted = xbarr;
for (int i=0; i<barr.length; i += 1) xbarr[i] = barr[i];
} else if (newType == short.class) {
xsarr = new short[barr.length];
converted = xsarr;
for (int i=0; i<barr.length; i += 1) xsarr[i] = barr[i];
} else if (newType == char.class) {
xcarr = new char[barr.length];
converted = xcarr;
for (int i=0; i<barr.length; i += 1) xcarr[i] = (char) barr[i];
} else if (newType == int.class) {
xiarr = new int[barr.length];
converted = xiarr;
for (int i=0; i<barr.length; i += 1) xiarr[i] = barr[i];
} else if (newType == long.class) {
xlarr = new long[barr.length];
converted = xlarr;
for (int i=0; i<barr.length; i += 1) xlarr[i] = barr[i];
} else if (newType == float.class) {
xfarr = new float[barr.length];
converted = xfarr;
for (int i=0; i<barr.length; i += 1) xfarr[i] = barr[i];
} else if (newType == double.class) {
xdarr = new double[barr.length];
converted = xdarr;
for (int i=0; i<barr.length; i += 1) xdarr[i] = barr[i];
}
} else if (base == short.class) {
short[] sarr = (short[]) array;
if (newType == byte.class) {
xbarr = new byte[sarr.length];
converted = xbarr;
for (int i=0; i<sarr.length; i += 1) xbarr[i] = (byte) sarr[i];
} else if (newType == short.class) {
xsarr = new short[sarr.length];
converted = xsarr;
for (int i=0; i<sarr.length; i += 1) xsarr[i] = sarr[i];
} else if (newType == char.class) {
xcarr = new char[sarr.length];
converted = xcarr;
for (int i=0; i<sarr.length; i += 1) xcarr[i] = (char) sarr[i];
} else if (newType == int.class) {
xiarr = new int[sarr.length];
converted = xiarr;
for (int i=0; i<sarr.length; i += 1) xiarr[i] = sarr[i];
} else if (newType == long.class) {
xlarr = new long[sarr.length];
converted = xlarr;
for (int i=0; i<sarr.length; i += 1) xlarr[i] = sarr[i];
} else if (newType == float.class) {
xfarr = new float[sarr.length];
converted = xfarr;
for (int i=0; i<sarr.length; i += 1) xfarr[i] = sarr[i];
} else if (newType == double.class) {
xdarr = new double[sarr.length];
converted = xdarr;
for (int i=0; i<sarr.length; i += 1) xdarr[i] = sarr[i];
}
} else if (base == char.class) {
char[] carr = (char[]) array;
if (newType == byte.class) {
xbarr = new byte[carr.length];
converted = xbarr;
for (int i=0; i<carr.length; i += 1) xbarr[i] = (byte) carr[i];
} else if (newType == short.class) {
xsarr = new short[carr.length];
converted = xsarr;
for (int i=0; i<carr.length; i += 1) xsarr[i] = (short) carr[i];
} else if (newType == char.class) {
xcarr = new char[carr.length];
converted = xcarr;
for (int i=0; i<carr.length; i += 1) xcarr[i] = carr[i];
} else if (newType == int.class) {
xiarr = new int[carr.length];
converted = xiarr;
for (int i=0; i<carr.length; i += 1) xiarr[i] = carr[i];
} else if (newType == long.class) {
xlarr = new long[carr.length];
converted = xlarr;
for (int i=0; i<carr.length; i += 1) xlarr[i] = carr[i];
} else if (newType == float.class) {
xfarr = new float[carr.length];
converted = xfarr;
for (int i=0; i<carr.length; i += 1) xfarr[i] = carr[i];
} else if (newType == double.class) {
xdarr = new double[carr.length];
converted = xdarr;
for (int i=0; i<carr.length; i += 1) xdarr[i] = carr[i];
}
} else if (base == int.class) {
int[] iarr = (int[]) array;
if (newType == byte.class) {
xbarr = new byte[iarr.length];
converted = xbarr;
for (int i=0; i<iarr.length; i += 1) xbarr[i] = (byte) iarr[i];
} else if (newType == short.class) {
xsarr = new short[iarr.length];
converted = xsarr;
for (int i=0; i<iarr.length; i += 1) xsarr[i] = (short) iarr[i];
} else if (newType == char.class) {
xcarr = new char[iarr.length];
converted = xcarr;
for (int i=0; i<iarr.length; i += 1) xcarr[i] = (char) iarr[i];
} else if (newType == int.class) {
xiarr = new int[iarr.length];
converted = xiarr;
for (int i=0; i<iarr.length; i += 1) xiarr[i] = iarr[i];
} else if (newType == long.class) {
xlarr = new long[iarr.length];
converted = xlarr;
for (int i=0; i<iarr.length; i += 1) xlarr[i] = iarr[i];
} else if (newType == float.class) {
xfarr = new float[iarr.length];
converted = xfarr;
for (int i=0; i<iarr.length; i += 1) xfarr[i] = iarr[i];
} else if (newType == double.class) {
xdarr = new double[iarr.length];
converted = xdarr;
for (int i=0; i<iarr.length; i += 1) xdarr[i] = iarr[i];
}
} else if (base == long.class) {
long[] larr = (long[]) array;
if (newType == byte.class) {
xbarr = new byte[larr.length];
converted = xbarr;
for (int i=0; i<larr.length; i += 1) xbarr[i] = (byte) larr[i];
} else if (newType == short.class) {
xsarr = new short[larr.length];
converted = xsarr;
for (int i=0; i<larr.length; i += 1) xsarr[i] = (short) larr[i];
} else if (newType == char.class) {
xcarr = new char[larr.length];
converted = xcarr;
for (int i=0; i<larr.length; i += 1) xcarr[i] = (char) larr[i];
} else if (newType == int.class) {
xiarr = new int[larr.length];
converted = xiarr;
for (int i=0; i<larr.length; i += 1) xiarr[i] = (int) larr[i];
} else if (newType == long.class) {
xlarr = new long[larr.length];
converted = xlarr;
for (int i=0; i<larr.length; i += 1) xlarr[i] = larr[i];
} else if (newType == float.class) {
xfarr = new float[larr.length];
converted = xfarr;
for (int i=0; i<larr.length; i += 1) xfarr[i] = (float) larr[i];
} else if (newType == double.class) {
xdarr = new double[larr.length];
converted = xdarr;
for (int i=0; i<larr.length; i += 1) xdarr[i] = (double) larr[i];
}
} else if (base == float.class) {
float[] farr = (float[]) array;
if (newType == byte.class) {
xbarr = new byte[farr.length];
converted = xbarr;
for (int i=0; i<farr.length; i += 1) xbarr[i] = (byte) farr[i];
} else if (newType == short.class) {
xsarr = new short[farr.length];
converted = xsarr;
for (int i=0; i<farr.length; i += 1) xsarr[i] = (short) farr[i];
} else if (newType == char.class) {
xcarr = new char[farr.length];
converted = xcarr;
for (int i=0; i<farr.length; i += 1) xcarr[i] = (char) farr[i];
} else if (newType == int.class) {
xiarr = new int[farr.length];
converted = xiarr;
for (int i=0; i<farr.length; i += 1) xiarr[i] = (int) farr[i];
} else if (newType == long.class) {
xlarr = new long[farr.length];
converted = xlarr;
for (int i=0; i<farr.length; i += 1) xlarr[i] = (long) farr[i];
} else if (newType == float.class) {
xfarr = new float[farr.length];
converted = xfarr;
for (int i=0; i<farr.length; i += 1) xfarr[i] = farr[i];
} else if (newType == double.class) {
xdarr = new double[farr.length];
converted = xdarr;
for (int i=0; i<farr.length; i += 1) xdarr[i] = farr[i];
}
} else if (base == double.class) {
double[] darr = (double[]) array;
if (newType == byte.class) {
xbarr = new byte[darr.length];
converted = xbarr;
for (int i=0; i<darr.length; i += 1) xbarr[i] = (byte) darr[i];
} else if (newType == short.class) {
xsarr = new short[darr.length];
converted = xsarr;
for (int i=0; i<darr.length; i += 1) xsarr[i] = (short) darr[i];
} else if (newType == char.class) {
xcarr = new char[darr.length];
converted = xcarr;
for (int i=0; i<darr.length; i += 1) xcarr[i] = (char) darr[i];
} else if (newType == int.class) {
xiarr = new int[darr.length];
converted = xiarr;
for (int i=0; i<darr.length; i += 1) xiarr[i] = (int) darr[i];
} else if (newType == long.class) {
xlarr = new long[darr.length];
converted = xlarr;
for (int i=0; i<darr.length; i += 1) xlarr[i] = (long) darr[i];
} else if (newType == float.class) {
xfarr = new float[darr.length];
converted = xfarr;
for (int i=0; i<darr.length; i += 1) xfarr[i] = (float) darr[i];
} else if (newType == double.class) {
xdarr = new double[darr.length];
converted = xdarr;
for (int i=0; i<darr.length; i += 1) xdarr[i] = darr[i];
}
}
}
return converted;
}
/** Test and demonstrate the ArrayFuncs methods.
* @param args Unused.
*/
public static void main(String[] args) {
int[][][] test1 = new int[10][9][8];
boolean[][] test2 = new boolean[4][];
test2[0] = new boolean[5];
test2[1] = new boolean[4];
test2[2] = new boolean[3];
test2[3] = new boolean[2];
double[][] test3 = new double[10][20];
StringBuffer[][] test4 = new StringBuffer[3][2];
System.out.println("getBaseClass: test1: Base type of integer array is:"+ getBaseClass(test1));
System.out.println("getBaseLength: test1: "+getBaseLength(test1));
System.out.println("arrayDescription: test1: "+arrayDescription(test1));
System.out.println("computeSize: test1: "+computeSize(test1));
System.out.println("getBaseClass: test2: Base type of boolean array is:"+ getBaseClass(test2));
System.out.println("getBaseLength: test2: "+getBaseLength(test2));
System.out.println("arrayDescription: test2: "+arrayDescription(test2));
System.out.println("computeSize: test2: "+computeSize(test2));
System.out.println("getBaseClass: test3: Base type of double array is: "+ getBaseClass(test3));
System.out.println("getBaseLength: test3: "+getBaseLength(test3));
System.out.println("arrayDescription: test1: "+arrayDescription(test3));
System.out.println("computeSize: test3: "+computeSize(test3));
System.out.println("getBaseClass: test4: Base type of StringBuffer array is: "+getBaseClass(test4));
System.out.println("getBaseLength: test4: "+getBaseLength(test4));
System.out.println("arrayDescription: test1: "+arrayDescription(test4));
System.out.println("computeSize: test4: "+computeSize(test4));
System.out.println("");
System.out.println("arrayDescription: test1: Print a simple description of an array:"+arrayDescription(test1));
System.out.println("arrayDescription: test2: doesn't handle non-rectangular arrays:"+arrayDescription(test2));
System.out.println("");
System.out.println("examinePrimitiveArray: test1");
examinePrimitiveArray(test1);
System.out.println("");
System.out.println("examinePrimitiveArray: test2");
examinePrimitiveArray(test2);
System.out.println("");
System.out.println(" NOTE: this should show that test2 is not a rectangular array");
System.out.println("");
System.out.println("Using aggregates:");
Object[] agg = new Object[4];
agg[0] = test1;
agg[1] = test2;
agg[2] = test3;
agg[3] = test4;
System.out.println("getBaseClass: agg: Base class of aggregate is:"+getBaseClass(agg));
System.out.println("Size of aggregate is:" + computeSize(agg));
System.out.println("This ignores the array of StringBuffers");
testPattern(test1,(byte)0);
System.out.println("testPattern:");
for (int i=0; i < test1.length; i += 1) {
for (int j=0; j <test1[0].length; j += 1) {
for(int k=0; k<test1[0][0].length; k += 1) {
System.out.print(" "+test1[i][j][k]);
}
System.out.println("");
}
System.out.println(""); // Double space....
}
int[][][] test5 = (int[][][]) deepClone(test1);
System.out.println("deepClone: copied array");
for (int i=0; i < test5.length; i += 1) {
for (int j=0; j <test5[0].length; j += 1) {
for(int k=0; k<test5[0][0].length; k += 1) {
System.out.print(" "+test5[i][j][k]);
}
System.out.println("");
}
System.out.println(""); // Double space....
}
test5[2][2][2] = 99;
System.out.println("Demonstrating that this is a deep clone:"
+test5[2][2][2]+" "+test1[2][2][2]);
System.out.println("Flatten an array:");
int[] test6 = (int[]) flatten(test1);
System.out.println(" arrayDescription: test6:"+arrayDescription(test6));
for (int i=0; i<test6.length; i += 1) {
System.out.print(" "+test6[i]);
if (i > 0 && i%10 == 0) System.out.println("");
}
System.out.println("");
System.out.println("Curl an array, we'll reformat test1's data");
int[] newdims = {8,9,10};
int[][][] test7 = (int[][][]) curl(test6, newdims);
for (int i=0; i < test5.length; i += 1) {
for (int j=0; j <test5[0].length; j += 1) {
for(int k=0; k<test5[0][0].length; k += 1) {
System.out.print(" "+test5[i][j][k]);
}
System.out.println("");
}
System.out.println(""); // Double space....
}
System.out.println("");
System.out.println("Test array conversions");
byte[][][] xtest1 = (byte[][][]) convertArray(test1, byte.class);
System.out.println(" xtest1 is of type:"+arrayDescription(xtest1));
System.out.println(" test1[3][3][3]="+test1[3][3][3]+" xtest1="+xtest1[3][3][3]);
System.out.println("Converting float[700][700] to byte at:"+new java.util.Date() );
float[][] big=new float[700][700];
byte[][] img = (byte[][]) convertArray(big, byte.class);
System.out.println(" img="+arrayDescription(img)+" at "+ new java.util.Date()) ;
System.out.println("End of tests");
}
}