// $Id: Accessor.java,v 1.3 2003-02-03 20:09:03 donm Exp $
/*
* Copyright 1997-2000 Unidata Program Center/University Corporation for
* Atmospheric Research, P.O. Box 3000, Boulder, CO 80307,
* support@unidata.ucar.edu.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at
* your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
* General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package ucar.multiarray;
import java.io.IOException;
/**
* Interface for multidimensional array data access.
* Given an index (array of integers), get or set the value
* at index.
* <p>
* Netcdf Variables implement this, but more general objects,
* such as java arrays, can be simply wrapped to provide
* this interface.
* <p>
* For lack of a better model, we use use naming conventions
* from java.lang.reflect.Array.
* In particular, we name the primitive specific "set" functions by type,
* rather than using overloading.
* This is symmetric with the "get" operations.
* <p>
* The primitive specific get and set methods are useful only if the
* the componentType is primitive (like java.lang.Double.TYPE).
* <p>
* Like java.lang.reflect.Array, classes that implement this
* interface should permit widening conversions to occur during a
* get or set operation, and throw IllegalArgumentException otherwise.
* Classes which implement this interface may be more lenient, however,
* only throwing the exception for narrowing conversions if
* the unconverted value is out of range for the target type.
* Implementations may throw UnsupportedOperationException,
* IllegalArgumentException, or ? for conversions to primitive
* which don't make sense.
* <p>
* The implementations may be file based or remote,
* so the methods throw java.io.IOException.
*
* @see AbstractAccessor
* @see MultiArray
* @see RemoteAccessor
* @author $Author: donm $
* @version $Revision: 1.3 $ $Date: 2003-02-03 20:09:03 $
*/
public interface
Accessor
{
/**
* Get (read) the array element at index.
* The returned value is wrapped in an object if it
* has a primitive type.
* Length of index must be greater than or equal to the rank of this.
* Values of index components must be less than corresponding
* values from getLengths().
* @param index MultiArray index
* @return Object value at <code>index</code>
* @exception NullPointerException If the argument is null.
* @exception IllegalArgumentException If the array length of index is
* too small
* @exception ArrayIndexOutOfBoundsException If an index component
* argument is negative, or if it is greater than or equal to the
* corresponding dimension length.
*/
public Object
get(int [] index)
throws IOException;
/**
* Get the array element at index, as a boolean.
* @see Accessor#get
*/
public boolean
getBoolean(int [] index)
throws IOException;
/**
* Get the array element at index, as a char.
* @see Accessor#get
*/
public char
getChar(int [] index)
throws IOException;
/**
* Get the array element at index, as a byte.
* @see Accessor#get
*/
public byte
getByte(int [] index)
throws IOException;
/**
* Get the array element at index, as a short.
* @see Accessor#get
*/
public short
getShort(int [] index)
throws IOException;
/**
* Get the array element at index, as an int.
* @see Accessor#get
*/
public int
getInt(int [] index)
throws IOException;
/**
* Get the array element at index, as a long.
* @see Accessor#get
*/
public long
getLong(int [] index)
throws IOException;
/**
* Get the array element at index, as a float.
* @see Accessor#get
*/
public float
getFloat(int [] index)
throws IOException;
/**
* Get the array element at index, as a double.
* @see Accessor#get
*/
public double
getDouble(int [] index)
throws IOException;
/**
* Set (modify, write) the array element at index
* to the specified value.
* If the array has a primitive component type, the value may
* be unwrapped.
* Values of index components must be less than corresponding
* values from getLengths().
* @param index MultiArray index
* @param value the new value.
* @exception NullPointerException If the index argument is null, or
* if the array has a primitive component type and the value argument is
* null
* @exception IllegalArgumentException If the array length of index is
* too small
* @exception ArrayIndexOutOfBoundsException If an index component
* argument is negative, or if it is greater than or equal to the
* corresponding dimension length.
*/
public void
set(int [] index, Object value)
throws IOException;
/**
* Set the array element at index to the specified boolean value.
* @see Accessor#set
*/
public void
setBoolean(int [] index, boolean value)
throws IOException;
/**
* Set the array element at index to the specified char value.
* @see Accessor#set
*/
public void
setChar(int [] index, char value)
throws IOException;
/**
* Set the array element at index to the specified byte value.
* @see Accessor#set
*/
public void
setByte(int [] index, byte value)
throws IOException;
/**
* Set the array element at index to the specified short value.
* @see Accessor#set
*/
public void
setShort(int [] index, short value)
throws IOException;
/**
* Set the array element at index to the specified int value.
* @see Accessor#set
*/
public void
setInt(int [] index, int value)
throws IOException;
/**
* Set the array element at index to the specified long value.
* @see Accessor#set
*/
public void
setLong(int [] index, long value)
throws IOException;
/**
* Set the array element at index to the specified float value.
* @see Accessor#set
*/
public void
setFloat(int [] index, float value)
throws IOException;
/**
* Set the array element at index to the specified double value.
* @see Accessor#set
*/
public void
setDouble(int [] index, double value)
throws IOException;
/**
* Aggregate read access.
* Return a new MultiArray of the
* same componentType as this, and with shape as specified,
* which is initialized to the values of this, as
* clipped to (origin, origin + shape).
* <p>
* It is easier to implement than to specify :-).
* <p>
* The main reason to implement this instead of using
* the equivalent proxy is for remote or file access.
* <p>
* <code>assert(origin[ii] + shape[ii] <= lengths[ii]);</code>
*
* @param origin int array specifying the starting index.
* @param shape int array specifying the extents in each
* dimension. This becomes the shape of the return.
* @return the MultiArray with the specified shape
*/
public MultiArray
copyout(int [] origin, int [] shape)
throws IOException;
/**
* Aggregate write access.
* Given a MultiArray, copy it into this at the specified starting index.
* TODO: clearer specification.
* <p>
* Hopefully this member can be optimized in various situations.
* <p>
* <code>assert(origin[ii] + (source.getLengths())[ii]
<= (getLengths())[ii]);</code>
*
* @param origin int array specifying the starting index.
* @param source MultiArray with the same componentType as
* this and shape smaller than
* <code>this.getLengths() - origin</code>
*/
public void
copyin(int [] origin, MultiArray source)
throws IOException;
/**
* Returns a new array containing all of the elements in this
* MultiArray. The returned array is one dimensional.
* The order of the elements in the result is natural,
* as if we used an IndexIterator to step through the elements
* of this MultiArray. The component type of the result is
* the same as this.
* <p>
* This method acts as bridge between array-based and MultiArray-based
* APIs.
* <p>
* This method is functionally equivalent to
* <pre>
Object anArray = Array.newInstance(getComponentType(), 1);
int [] origin = new int[getRank()]
int [] shape = getDimensions();
return toArray(anArray, origin, shape);
* </pre>
*
* @return a one dimensional Array containing all the elements
* in this MultiArray
*/
public Object
toArray()
throws IOException;
/**
* Returns an array containing elements of this
* MultiArray specified by origin and shape,
* possibly converting the component type.
* The returned array is one dimensional.
* The order of the elements in the result is natural,
* as if we used an IndexIterator to step through the elements
* of this MultiArray.
* <p>
* The anArray argument should be an array.
* If it is large enough to contain the output,
* it is used and no new storage is allocated.
* Otherwise, new storage is allocated with the
* same component type as the argument, and the data
* is copied into it.
* <p>
* This method acts as bridge between array-based and MultiArray-based
* APIs.
* <p>
* This method is similar to copyout(origin, shape).toArray(),
* but avoids a copy operation and (potentially) an allocation.
* <p>
* NOTE: Implementation of type conversion is deferred until
* JDK 1.2. Currently, the componentType of <code>anArray</code>
* must be the same as <code>this</code>
*
* @return a one dimensional Array containing the specified elements
*/
public Object
toArray(Object anArray, int [] origin, int [] shape)
throws IOException;
}