mirror of
https://github.com/meteoinfo/MeteoInfo.git
synced 2025-12-08 20:36:05 +00:00
252 lines
9.3 KiB
Java
252 lines
9.3 KiB
Java
/*
|
|
* 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 org.meteoinfo.ndarray;
|
|
|
|
import org.meteoinfo.ndarray.util.DataTypeUtil;
|
|
|
|
import java.io.IOException;
|
|
import java.nio.ByteBuffer;
|
|
import java.nio.ByteOrder;
|
|
|
|
/**
|
|
* Make a deep copy of an existing StructureData, so that all the data is contained in this object
|
|
*
|
|
* @author caron
|
|
* @since 6/19/2014
|
|
*/
|
|
public class StructureDataDeep extends StructureDataA {
|
|
|
|
/**
|
|
* Make deep copy from sdata to another StructureData object whose data is self contained
|
|
* @param sdata original sdata
|
|
* @param members the StructureData members. a reference is kept to this object
|
|
* @return StructureData with all data self contained
|
|
*/
|
|
static public StructureDataDeep copy(StructureData sdata, StructureMembers members) {
|
|
ArrayStructureBB abb = copyToArrayBB(sdata, members, ByteOrder.BIG_ENDIAN);
|
|
return new StructureDataDeep(abb);
|
|
}
|
|
|
|
/**
|
|
* Make deep copy from an ArrayStructure to a ArrayStructureBB whose data is contained in a ByteBuffer
|
|
* @param as original ArrayStructure
|
|
* @param bo what byte order to use ? (null for any)
|
|
* @param canonical packing must be canonical
|
|
* @return ArrayStructureBB with all data self contained
|
|
*/
|
|
static public ArrayStructureBB copyToArrayBB(ArrayStructureBak as, ByteOrder bo, boolean canonical) throws IOException {
|
|
if (!canonical && as.getClass().equals(ArrayStructureBB.class)) { // no subclasses, LOOK detect already canonical later
|
|
ArrayStructureBB abb = (ArrayStructureBB) as;
|
|
ByteBuffer bb = abb.getByteBuffer();
|
|
if (bo == null || bo.equals(bb.order()))
|
|
return abb;
|
|
}
|
|
|
|
StructureMembers smo = as.getStructureMembers();
|
|
StructureMembers sm = new StructureMembers(smo);
|
|
ArrayStructureBB abb = new ArrayStructureBB(sm, as.getShape());
|
|
ArrayStructureBB.setOffsets(sm); // this makes the packing canonical
|
|
if (bo != null) {
|
|
ByteBuffer bb = abb.getByteBuffer();
|
|
bb.order(bo);
|
|
}
|
|
|
|
StructureDataIterator iter = as.getStructureDataIterator();
|
|
try {
|
|
while (iter.hasNext())
|
|
copyToArrayBB(iter.next(), abb);
|
|
} finally {
|
|
iter.finish();
|
|
}
|
|
return abb;
|
|
}
|
|
|
|
/**
|
|
* Make deep copy from a StructureData to a ArrayStructureBB whose data is contained in a ByteBuffer.
|
|
* @param sdata original ArrayStructure.
|
|
* @return ArrayStructureBB with all data self contained
|
|
*/
|
|
static public ArrayStructureBB copyToArrayBB(StructureData sdata) {
|
|
return copyToArrayBB(sdata, new StructureMembers(sdata.getStructureMembers()), ByteOrder.BIG_ENDIAN);
|
|
}
|
|
|
|
/**
|
|
* Make deep copy from a StructureData to a ArrayStructureBB whose data is contained in a ByteBuffer
|
|
* @param sdata original ArrayStructure
|
|
* @param sm the StructureData members. a reference is kept to this object
|
|
* @param bo Byte Order of the ByteBuffer
|
|
* @return ArrayStructureBB with all data self contained
|
|
*/
|
|
static public ArrayStructureBB copyToArrayBB(StructureData sdata, StructureMembers sm, ByteOrder bo) {
|
|
int size = sm.getStructureSize();
|
|
ByteBuffer bb = ByteBuffer.allocate(size); // default is big endian
|
|
bb.order(bo);
|
|
ArrayStructureBB abb = new ArrayStructureBB(sm, new int[]{1}, bb, 0);
|
|
ArrayStructureBB.setOffsets(sm);
|
|
copyToArrayBB(sdata, abb);
|
|
return abb;
|
|
}
|
|
|
|
/**
|
|
* Make deep copy from a StructureData into the given ArrayStructureBB
|
|
* @param sdata original data from here
|
|
* @param abb copy data into this ArrayStructureBB, starting from wherever the ByteBuffer current position is
|
|
* @return number of bytes copied
|
|
*/
|
|
static public int copyToArrayBB(StructureData sdata, ArrayStructureBB abb) {
|
|
//StructureMembers sm = sdata.getStructureMembers();
|
|
ByteBuffer bb = abb.getByteBuffer();
|
|
int start = bb.limit();
|
|
|
|
for (StructureMembers.Member wantMember : abb.getMembers()) {
|
|
StructureMembers.Member m = sdata.findMember(wantMember.getName());
|
|
assert m != null;
|
|
assert m.getDataType() == wantMember.getDataType();
|
|
|
|
DataType dtype = m.getDataType();
|
|
//System.out.printf("do %s (%s) = %d%n", m.getName(), m.getDataType(), bb.position());
|
|
if (m.isScalar()) {
|
|
switch (dtype) {
|
|
case STRING:
|
|
bb.putInt(abb.addObjectToHeap(sdata.getScalarString(m)));
|
|
break;
|
|
case FLOAT:
|
|
bb.putFloat(sdata.getScalarFloat(m));
|
|
break;
|
|
case DOUBLE:
|
|
bb.putDouble(sdata.getScalarDouble(m));
|
|
break;
|
|
case INT:
|
|
case ENUM4:
|
|
bb.putInt(sdata.getScalarInt(m));
|
|
break;
|
|
case SHORT:
|
|
case ENUM2:
|
|
bb.putShort(sdata.getScalarShort(m));
|
|
break;
|
|
case BYTE:
|
|
case ENUM1:
|
|
bb.put(sdata.getScalarByte(m));
|
|
break;
|
|
case CHAR:
|
|
bb.put((byte) sdata.getScalarChar(m));
|
|
break;
|
|
case LONG:
|
|
bb.putLong(sdata.getScalarLong(m));
|
|
break;
|
|
case STRUCTURE:
|
|
StructureData sd = sdata.getScalarStructure(m);
|
|
ArrayStructureBB out_abb = new ArrayStructureBB(sd.getStructureMembers(),
|
|
new int[]{1}, bb, 0);
|
|
copyToArrayBB(sd, out_abb);
|
|
break;
|
|
default:
|
|
throw new IllegalStateException("scalar " + dtype.toString());
|
|
/* case BOOLEAN:
|
|
break;
|
|
case SEQUENCE:
|
|
break;
|
|
case OPAQUE:
|
|
break; */
|
|
}
|
|
} else {
|
|
int n = m.getSize();
|
|
switch (dtype) {
|
|
case STRING:
|
|
String[] ss = sdata.getJavaArrayString(m);
|
|
bb.putInt(abb.addObjectToHeap(ss)); // stored as String[] on the heap
|
|
break;
|
|
case FLOAT:
|
|
float[] fdata = sdata.getJavaArrayFloat(m);
|
|
for (int i = 0; i < n; i++)
|
|
bb.putFloat(fdata[i]);
|
|
break;
|
|
case DOUBLE:
|
|
double[] ddata = sdata.getJavaArrayDouble(m);
|
|
for (int i = 0; i < n; i++)
|
|
bb.putDouble(ddata[i]);
|
|
break;
|
|
case INT:
|
|
case ENUM4:
|
|
int[] idata = sdata.getJavaArrayInt(m);
|
|
for (int i = 0; i < n; i++)
|
|
bb.putInt(idata[i]);
|
|
break;
|
|
case SHORT:
|
|
case ENUM2:
|
|
short[] shdata = sdata.getJavaArrayShort(m);
|
|
for (int i = 0; i < n; i++)
|
|
bb.putShort(shdata[i]);
|
|
break;
|
|
case BYTE:
|
|
case ENUM1:
|
|
byte[] bdata = sdata.getJavaArrayByte(m);
|
|
for (int i = 0; i < n; i++)
|
|
bb.put(bdata[i]);
|
|
break;
|
|
case CHAR:
|
|
char[] cdata = sdata.getJavaArrayChar(m);
|
|
bb.put(DataTypeUtil.convertCharToByte(cdata));
|
|
break;
|
|
case LONG:
|
|
long[] ldata = sdata.getJavaArrayLong(m);
|
|
for (int i = 0; i < n; i++)
|
|
bb.putLong(ldata[i]);
|
|
break;
|
|
default:
|
|
throw new IllegalStateException("array " + dtype.toString());
|
|
/* case BOOLEAN:
|
|
break;
|
|
case OPAQUE:
|
|
break;
|
|
case STRUCTURE:
|
|
break; // */
|
|
case SEQUENCE:
|
|
break; // skip
|
|
}
|
|
}
|
|
}
|
|
return bb.limit() - start;
|
|
}
|
|
|
|
//private ArrayStructureBB abb;
|
|
private StructureDataDeep(ArrayStructureBB abb) {
|
|
super(abb, 0);
|
|
//this.abb = abb;
|
|
}
|
|
|
|
// public ByteBuffer getByteBuffer() { return abb.getByteBuffer(); }
|
|
|
|
}
|