
ucar.ma2.ArrayStructure Maven / Gradle / Ivy
/*
* Copyright 1998-2014 University Corporation for Atmospheric Research/Unidata
*
* Portions of this software were developed by the Unidata Program at the
* University Corporation for Atmospheric Research.
*
* Access and use of this software shall impose the following obligations
* and understandings on the user. The user is granted the right, without
* any fee or cost, to use, copy, modify, alter, enhance and distribute
* this software, and any derivative works thereof, and its supporting
* documentation for any purpose whatsoever, provided that this entire
* notice appears in all copies of the software, derivative works and
* supporting documentation. Further, UCAR requests that the user credit
* UCAR/Unidata in any publications that result from the use of this
* software or in any product that includes this software. The names UCAR
* and/or Unidata, however, may not be used in any advertising or publicity
* to endorse or promote any products or commercial entity unless specific
* written permission is obtained from UCAR/Unidata. The user also
* understands that UCAR/Unidata is not obligated to provide the user with
* any support, consulting, training or assistance of any kind with regard
* to the use, operation and performance of this software nor to provide
* the user with any updates, revisions, new versions or "bug fixes."
*
* THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
* INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
* FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
*/
package ucar.ma2;
import ucar.nc2.util.Indent;
import java.io.IOException;
import java.util.Formatter;
import java.util.List;
import java.nio.ByteBuffer;
/**
* Superclass for implementations of Array of StructureData.
*
* The general way to access data in an ArrayStructure is to use
* StructureData getStructureData(Index index).
*
* For 1D arrays (or by calculating your own recnum for nD arrays), you can also use:
* StructureData getStructureData(int recnum).
*
* Once you have a StructureData object, you can access data in a general way by using:
* Array StructureData.getArray(Member m)
*
* When dealing with large arrays of Structures, there can be significant overhead in using the generic interfaces.
* A number of convenience routines may be able to avoid extra Object creation, and so are recommended for efficiency.
* The following may avoid the overhead of creating the StructureData object:
* Array getArray(int recno, StructureMembers.Member m)
*
* The following can be convenient for accessing all the data in the ArrayStructure for one member, but its efficiency
* depends on the implementation:
* Array getMemberArray(StructureMembers.Member m)
*
* These require that you know the data types of the member data, but they are the most efficent:
*
* getScalarXXX(int recnum, Member m)
* getJavaArrayXXX(int recnum, Member m)
* where XXX is Byte, Char, Double, Float, Int, Long, Short, or String. For members that are themselves Structures,
* the equivilent is:
*
* StructureData getScalarStructure(int recnum, Member m)
* ArrayStructure getArrayStructure(int recnum, Member m)
*
* These will return any compatible type as a double or float, but will have extra overhead when the types dont match:
*
* convertScalarXXX(int recnum, Member m)
* convertJavaArrayXXX(int recnum, Member m)
* where XXX is Double or Float
*
* @author caron
* @see Array
* @see StructureData
*/
public abstract class ArrayStructure extends Array {
/* Implementation notes
ArrayStructure contains the default implementation of storing the data in individual member arrays.
ArrayStructureMA uses all of these.
ArrayStructureW uses some of these.
ArrayStructureBB override all such methods.
*/
protected StructureMembers members;
protected int nelems;
protected StructureData[] sdata;
/**
* Create a new Array of type StructureData and the given members and shape.
* dimensions.length determines the rank of the new Array.
*
* @param members a description of the structure members
* @param shape the shape of the Array.
*/
protected ArrayStructure(StructureMembers members, int[] shape) {
super(shape);
this.members = members;
this.nelems = (int) indexCalc.getSize();
}
// for subclasses to create views
protected ArrayStructure(StructureMembers members, Index ima) {
super(ima);
this.members = members;
this.nelems = (int) indexCalc.getSize();
}
// copy from javaArray to storage using the iterator: used by factory( Object);
protected void copyFrom1DJavaArray(IndexIterator iter, Object javaArray) {
Object[] ja = (Object[]) javaArray;
for (Object aJa : ja)
iter.setObjectNext(aJa);
}
// copy to javaArray from storage using the iterator: used by copyToNDJavaArray;
protected void copyTo1DJavaArray(IndexIterator iter, Object javaArray) {
Object[] ja = (Object[]) javaArray;
for (int i = 0; i < ja.length; i++)
ja[i] = iter.getObjectNext();
}
public Class getElementType() {
return StructureData.class;
}
/**
* Get the StructureMembers object.
* @return the StructureMembers object.
*/
public StructureMembers getStructureMembers() {
return members;
}
/**
* Get a list of structure members.
* @return the structure members.
*/
public List getMembers() {
return members.getMembers();
}
/**
* Get a list structure member names.
* @return the structure members.
*/
public List getStructureMemberNames() {
return members.getMemberNames();
}
/**
* Find a member by its name.
*
* @param memberName find member with this name
* @return StructureMembers.Member matching the name, or null if not found
*/
public StructureMembers.Member findMember(String memberName) {
return members.findMember(memberName);
}
@Override
public long getSizeBytes() {
return indexCalc.getSize() * members.getStructureSize();
}
/**
* Get the index-th StructureData of this ArrayStructure.
*
* @param i which one to get, specified by an Index.
* @return object of type StructureData.
*/
public Object getObject(Index i) {
return getObject(i.currentElement());
}
/**
* Set one of the StructureData of this ArrayStructure.
*
* @param i which one to set, specified by an Index.
* @param value must be type StructureData.
*/
public void setObject(Index i, Object value) {
setObject(i.currentElement(), value);
}
/**
* Get the index-th StructureData of this ArrayStructure.
*
* @param index which one to get, specified by an integer.
* @return object of type StructureData.
*/
public Object getObject(int index) {
return getStructureData(index);
}
/**
* Set the index-th StructureData of this ArrayStructure.
*
* @param index which one to set.
* @param value must be type StructureData.
*/
public void setObject(int index, Object value) {
if (sdata == null)
sdata = new StructureData[nelems];
sdata[index] = (StructureData) value;
}
/**
* Get the index-th StructureData of this ArrayStructure.
*
* @param i which one to get, specified by an Index.
* @return object of type StructureData.
*/
public StructureData getStructureData(Index i) {
return getStructureData(i.currentElement());
}
/**
* Get the index-th StructureData of this ArrayStructure.
*
* @param index which one to get, specified by an integer.
* @return object of type StructureData.
*/
public StructureData getStructureData(int index) {
if (sdata == null)
sdata = new StructureData[nelems];
if (index >= sdata.length)
throw new IllegalArgumentException(index + " > " + sdata.length);
if (sdata[index] == null)
sdata[index] = makeStructureData(this, index);
return sdata[index];
}
public Object getStorage() {
// this fills the sdata array
for (int i = 0; i < nelems; i++)
getStructureData(i);
return sdata;
}
abstract protected StructureData makeStructureData(ArrayStructure as, int recno);
/**
* Get the size of each StructureData object in bytes.
*
* @return the size of each StructureData object in bytes.
*/
public int getStructureSize() {
return members.getStructureSize();
}
public StructureDataIterator getStructureDataIterator() { // throws java.io.IOException {
return new ArrayStructureIterator();
}
public class ArrayStructureIterator implements StructureDataIterator {
private int count = 0;
private int size = (int) getSize();
@Override
public boolean hasNext() throws IOException {
return count < size;
}
@Override
public StructureData next() throws IOException {
return getStructureData(count++);
}
@Override
public void setBufferSize(int bytes) {
}
@Override
public StructureDataIterator reset() {
count = 0;
return this;
}
@Override
public int getCurrentRecno() {
return count-1;
}
@Override
public void finish() {
}
// debugging
public ArrayStructure getArrayStructure() { return ArrayStructure.this; }
}
///////////////////////////////////////////////////////////////////////////////
/**
* Get member data of any type for a specific record as an Array.
* This may avoid the overhead of creating the StructureData object, but is equivilent to
* getStructure(recno).getArray( Member m).
*
* @param recno get data from the recnum-th StructureData of the ArrayStructure. Must be less than getSize();
* @param m get data from this StructureMembers.Member.
* @return Array values.
*/
public Array getArray(int recno, StructureMembers.Member m) {
DataType dataType = m.getDataType();
if (dataType == DataType.DOUBLE) {
double[] pa = getJavaArrayDouble(recno, m);
return Array.factory(double.class, m.getShape(), pa);
} else if (dataType == DataType.FLOAT) {
float[] pa = getJavaArrayFloat(recno, m);
return Array.factory(float.class, m.getShape(), pa);
} else if ((dataType == DataType.BYTE) || (dataType == DataType.ENUM1)) {
byte[] pa = getJavaArrayByte(recno, m);
return Array.factory(byte.class, m.getShape(), pa);
} else if ((dataType == DataType.SHORT) || (dataType == DataType.ENUM2)) {
short[] pa = getJavaArrayShort(recno, m);
return Array.factory(short.class, m.getShape(), pa);
} else if ((dataType == DataType.INT) || (dataType == DataType.ENUM4)) {
int[] pa = getJavaArrayInt(recno, m);
return Array.factory(int.class, m.getShape(), pa);
} else if (dataType == DataType.LONG) {
long[] pa = getJavaArrayLong(recno, m);
return Array.factory(long.class, m.getShape(), pa);
} else if (dataType == DataType.CHAR) {
char[] pa = getJavaArrayChar(recno, m);
return Array.factory(char.class, m.getShape(), pa);
} else if (dataType == DataType.STRING) {
String[] pa = getJavaArrayString(recno, m);
return Array.factory(String.class, m.getShape(), pa);
} else if (dataType == DataType.STRUCTURE) {
return getArrayStructure(recno, m);
} else if (dataType == DataType.SEQUENCE) {
return getArraySequence(recno, m);
} else if (dataType == DataType.OPAQUE) {
return getArrayObject(recno, m);
}
throw new RuntimeException("Dont have implemenation for " + dataType);
}
/**
* Set data for one member, over all structures.
* This is used by VariableDS to do scale/offset.
*
* @param m set data for this StructureMembers.Member.
* @param memberArray Array values.
*/
public void setMemberArray(StructureMembers.Member m, Array memberArray) {
m.setDataArray(memberArray);
if (memberArray instanceof ArrayStructure) { // LOOK
ArrayStructure as = (ArrayStructure) memberArray;
m.setStructureMembers( as.getStructureMembers());
}
}
/**
* Extract data for one member, over all structures.
*
* @param m get data from this StructureMembers.Member.
* @return Array values.
* @throws java.io.IOException on read error (only happens for Sequences, otherwise data is already read)
*/
public Array extractMemberArray(StructureMembers.Member m) throws IOException {
if (m.getDataArray() != null)
return m.getDataArray();
DataType dataType = m.getDataType();
/* special handling for sequences
if (dataType == DataType.SEQUENCE) {
List sdataList = new ArrayList();
for (int recno=0; recno ranges) throws InvalidRangeException {
Section viewSection = new Section(ranges);
ArrayStructureW result = new ArrayStructureW(this.members, viewSection.getShape());
int count = 0;
Section.Iterator iter = viewSection.getIterator(getShape());
while (iter.hasNext()) {
int recno = iter.next(null);
StructureData sd = getStructureData(recno);
result.setStructureData(sd, count++);
}
return result;
}
/**
* DO NOT USE, throws UnsupportedOperationException
*/
public Array copy() {
throw new UnsupportedOperationException();
}
/**
* DO NOT USE, throw ForbiddenConversionException
*/
public double getDouble(Index i) {
throw new ForbiddenConversionException();
}
/**
* DO NOT USE, throw ForbiddenConversionException
*/
public void setDouble(Index i, double value) {
throw new ForbiddenConversionException();
}
/**
* DO NOT USE, throw ForbiddenConversionException
*/
public float getFloat(Index i) {
throw new ForbiddenConversionException();
}
/**
* DO NOT USE, throw ForbiddenConversionException
*/
public void setFloat(Index i, float value) {
throw new ForbiddenConversionException();
}
/**
* DO NOT USE, throw ForbiddenConversionException
*/
public long getLong(Index i) {
throw new ForbiddenConversionException();
}
/**
* DO NOT USE, throw ForbiddenConversionException
*/
public void setLong(Index i, long value) {
throw new ForbiddenConversionException();
}
/**
* DO NOT USE, throw ForbiddenConversionException
*/
public int getInt(Index i) {
throw new ForbiddenConversionException();
}
/**
* DO NOT USE, throw ForbiddenConversionException
*/
public void setInt(Index i, int value) {
throw new ForbiddenConversionException();
}
/**
* DO NOT USE, throw ForbiddenConversionException
*/
public short getShort(Index i) {
throw new ForbiddenConversionException();
}
/**
* DO NOT USE, throw ForbiddenConversionException
*/
public void setShort(Index i, short value) {
throw new ForbiddenConversionException();
}
/**
* DO NOT USE, throw ForbiddenConversionException
*/
public byte getByte(Index i) {
throw new ForbiddenConversionException();
}
/**
* DO NOT USE, throw ForbiddenConversionException
*/
public void setByte(Index i, byte value) {
throw new ForbiddenConversionException();
}
/**
* DO NOT USE, throw ForbiddenConversionException
*/
public boolean getBoolean(Index i) {
throw new ForbiddenConversionException();
}
/**
* DO NOT USE, throw ForbiddenConversionException
*/
public void setBoolean(Index i, boolean value) {
throw new ForbiddenConversionException();
}
/**
* DO NOT USE, throw ForbiddenConversionException
*/
public char getChar(Index i) {
throw new ForbiddenConversionException();
}
/**
* DO NOT USE, throw ForbiddenConversionException
*/
public void setChar(Index i, char value) {
throw new ForbiddenConversionException();
}
// trusted, assumes that individual dimension lengths have been checked
// package private : mostly for iterators
public double getDouble(int index) {
throw new ForbiddenConversionException();
}
public void setDouble(int index, double value) {
throw new ForbiddenConversionException();
}
public float getFloat(int index) {
throw new ForbiddenConversionException();
}
public void setFloat(int index, float value) {
throw new ForbiddenConversionException();
}
public long getLong(int index) {
throw new ForbiddenConversionException();
}
public void setLong(int index, long value) {
throw new ForbiddenConversionException();
}
public int getInt(int index) {
throw new ForbiddenConversionException();
}
public void setInt(int index, int value) {
throw new ForbiddenConversionException();
}
public short getShort(int index) {
throw new ForbiddenConversionException();
}
public void setShort(int index, short value) {
throw new ForbiddenConversionException();
}
public byte getByte(int index) {
throw new ForbiddenConversionException();
}
public void setByte(int index, byte value) {
throw new ForbiddenConversionException();
}
public char getChar(int index) {
throw new ForbiddenConversionException();
}
public void setChar(int index, char value) {
throw new ForbiddenConversionException();
}
public boolean getBoolean(int index) {
throw new ForbiddenConversionException();
}
public void setBoolean(int index, boolean value) {
throw new ForbiddenConversionException();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy