ucar.ma2.StructureDataDeep Maven / Gradle / Ivy
The newest version!
/*
* Copyright (c) 1998-2018 University Corporation for Atmospheric Research/Unidata
* See LICENSE for license information.
*/
package ucar.ma2;
import ucar.nc2.Structure;
import ucar.nc2.iosp.IospHelper;
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
*/
public static 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
*/
public static ArrayStructureBB copyToArrayBB(ArrayStructure 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 sm = as.getStructureMembers().toBuilder(false).build();
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);
}
try (StructureDataIterator iter = as.getStructureDataIterator()) {
while (iter.hasNext())
copyToArrayBB(iter.next(), abb);
}
return abb;
}
/**
* Make deep copy to an ArrayStructureBB whose data is contained in a ByteBuffer.
* Use the order of the members in the given Structure; skip copying any not in the Structure
*
* @param s list of structure members come from here; must be compatible with ArrayStructure's data
* @param as original ArrayStructure
* @param bo what byte order to use ? (null for default)
* @return ArrayStructureBB with all data self contained
*/
public static ArrayStructureBB copyToArrayBB(Structure s, ArrayStructure as, ByteOrder bo) throws IOException {
StructureMembers sm = s.makeStructureMembers();
ArrayStructureBB abb = new ArrayStructureBB(sm, as.getShape());
ArrayStructureBB.setOffsets(sm);
if (bo != null) {
ByteBuffer bb = abb.getByteBuffer();
bb.order(bo);
}
try (StructureDataIterator iter = as.getStructureDataIterator()) {
while (iter.hasNext())
copyToArrayBB(iter.next(), abb);
}
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
*/
public static ArrayStructureBB copyToArrayBB(StructureData sdata) {
return copyToArrayBB(sdata, sdata.getStructureMembers().toBuilder(false).build(), 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
*/
public static 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
*/
public static 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();
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 UINT:
case ENUM4:
bb.putInt(sdata.getScalarInt(m));
break;
case SHORT:
case USHORT:
case ENUM2:
bb.putShort(sdata.getScalarShort(m));
break;
case BYTE:
case UBYTE:
case ENUM1:
bb.put(sdata.getScalarByte(m));
break;
case CHAR:
bb.put((byte) sdata.getScalarChar(m));
break;
case LONG:
case ULONG:
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);
/*
* 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(IospHelper.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);
/*
* 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(); }
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy