/*
VisAD system for interactive analysis and visualization of numerical
data. Copyright (C) 1996 - 2017 Bill Hibbard, Curtis Rueden, Tom
Rink, Dave Glowacki, Steve Emmerson, Tom Whittaker, Don Murray, and
Tommy Jasmin.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 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
Library General Public License for more details.
You should have received a copy of the GNU Library 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 visad.data.visad.object;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.EOFException;
import java.io.IOException;
import visad.CoordinateSystem;
import visad.ErrorEstimate;
import visad.GriddedSet;
import visad.IntegerSet;
import visad.Integer1DSet;
import visad.Integer2DSet;
import visad.Integer3DSet;
import visad.IntegerNDSet;
import visad.Linear1DSet;
import visad.LinearSet;
import visad.MathType;
import visad.SetType;
import visad.Unit;
import visad.VisADException;
import visad.data.visad.BinaryObjectCache;
import visad.data.visad.BinaryReader;
import visad.data.visad.BinaryWriter;
import visad.data.visad.Saveable;
public class BinaryIntegerSet
implements BinaryObject
{
public static final int computeBytes(boolean matchedTypes, int[] lengths,
Integer1DSet[] comps,
CoordinateSystem cs, Unit[] units,
ErrorEstimate[] errors)
{
int compsLen;
if (matchedTypes) {
compsLen = 1 + BinaryIntegerArray.computeBytes(lengths);
} else {
compsLen = 1 + 4;
for (int i = 0; i < comps.length; i++) {
int size = BinaryGeneric.computeBytes(comps[i]);
if (size < 0) {
compsLen = -1;
break;
}
compsLen += size;
}
}
if (compsLen < 0) {
return compsLen;
}
final int unitsLen = BinaryUnit.computeBytes(units);
final int errorsLen = BinaryErrorEstimate.computeBytes(errors);
return 1 + 4 + 1 + 4 +
compsLen +
(cs == null ? 0 : 5) +
(unitsLen == 0 ? 0 : unitsLen + 1) +
(errorsLen == 0 ? 0 : errorsLen + 1) +
1;
}
public static final Integer1DSet[] getComponents(LinearSet set)
{
final int dim = ((GriddedSet )set).getDimension();
Integer1DSet[] comps = new Integer1DSet[dim];
for (int i = 0; i < dim; i++) {
Linear1DSet comp = set.getLinear1DComponent(i);
if (comp instanceof Integer1DSet) {
comps[i] = (Integer1DSet )comp;
} else if (comp.getFirst() == 0.0) {
// had to put this in because an old serialized object
// had Linear1DSets instead of Integer1DSets
try {
comps[i] = new Integer1DSet(comp.getType(), comp.getLength(),
comp.getCoordinateSystem(),
comp.getSetUnits(),
comp.getSetErrors());
} catch (VisADException ve) {
return null;
}
} else {
// XXX what happens here?
System.err.println("Ignoring comp#" + i + ": " + comp);
comps[i] = null;
}
}
return comps;
}
public static boolean hasMatchedTypes(SetType type, Integer1DSet[] comps)
{
if (comps == null) {
return true;
}
MathType[] dComp = type.getDomain().getComponents();
if (dComp == null || dComp.length != comps.length) {
return false;
}
boolean matchedTypes = true;
for (int i = 0; i < dComp.length; i++) {
if (!dComp[i].equals(comps[i].getType())) {
matchedTypes = false;
break;
}
}
return matchedTypes;
}
private static final Integer1DSet[] readInteger1DSets(BinaryReader reader)
throws IOException, VisADException
{
DataInput file = reader.getInput();
final int len = file.readInt();
if(DEBUG_RD_DATA)System.err.println("rdI1DSetS: len (" + len + ")");
Integer1DSet[] sets = new Integer1DSet[len];
for (int i = 0; i < len; i++) {
sets[i] = (Integer1DSet )BinaryGeneric.read(reader);
}
return sets;
}
public static final GriddedSet read(BinaryReader reader, byte dataType)
throws IOException, VisADException
{
BinaryObjectCache cSysCache = reader.getCoordinateSystemCache();
BinaryObjectCache typeCache = reader.getTypeCache();
DataInput file = reader.getInput();
final int typeIndex = file.readInt();
if(DEBUG_RD_DATA&&DEBUG_RD_MATH)System.err.println("rdIntSet: type index (" + typeIndex + ")");
SetType st = (SetType )typeCache.get(typeIndex);
if(DEBUG_RD_DATA&&!DEBUG_RD_MATH)System.err.println("rdIntSet: type index (" + typeIndex + "=" + st + ")");
int[] lengths = null;
CoordinateSystem cs = null;
Unit[] units = null;
ErrorEstimate[] errs = null;
Integer1DSet[] comps = null;
boolean reading = true;
while (reading) {
final byte directive;
try {
directive = file.readByte();
} catch (EOFException eofe) {
return null;
}
switch (directive) {
case FLD_LENGTHS:
if(DEBUG_RD_DATA)System.err.println("rdIntSet: FLD_LENGTHS (" + FLD_LENGTHS + ")");
lengths = BinaryIntegerArray.read(reader);
break;
case FLD_INTEGER_SETS:
if(DEBUG_RD_DATA)System.err.println("rdIntSet: FLD_INTEGER_SETS (" + FLD_INTEGER_SETS + ")");
comps = readInteger1DSets(reader);
break;
case FLD_INDEX_COORDSYS:
if(DEBUG_RD_DATA)System.err.println("rdIntSet: FLD_INDEX_COORDSYS (" + FLD_INDEX_COORDSYS + ")");
final int index = file.readInt();
if(DEBUG_RD_DATA&&DEBUG_RD_CSYS)System.err.println("rdIntSet: cSys index (" + index + ")");
cs = (CoordinateSystem )cSysCache.get(index);
if(DEBUG_RD_DATA&&!DEBUG_RD_CSYS)System.err.println("rdIntSet: cSys index (" + index + "=" + cs + ")");
break;
case FLD_INDEX_UNITS:
if(DEBUG_RD_DATA)System.err.println("rdIntSet: FLD_INDEX_UNITS (" + FLD_INDEX_UNITS + ")");
units = BinaryUnit.readList(reader);
break;
case FLD_INDEX_ERRORS:
if(DEBUG_RD_DATA)System.err.println("rdIntSet: FLD_INDEX_ERRORS (" + FLD_INDEX_ERRORS + ")");
errs = BinaryErrorEstimate.readList(reader);
break;
case FLD_END:
if(DEBUG_RD_DATA)System.err.println("rdIntSet: FLD_END (" + FLD_END + ")");
reading = false;
break;
default:
throw new IOException("Unknown IntegerSet directive " + directive);
}
}
if (st == null) {
throw new IOException("No SetType found for IntegerSet");
}
if (comps != null) {
if (lengths != null) {
throw new IOException("Both components and lengths found for IntegerSet");
}
switch (dataType) {
case DATA_INTEGER_1D_SET:
throw new IOException("Components specified for Integer1DSet");
case DATA_INTEGER_2D_SET:
return new Integer2DSet(st, comps, cs, units, errs);
case DATA_INTEGER_3D_SET:
return new Integer3DSet(st, comps, cs, units, errs);
case DATA_INTEGER_ND_SET:
return new IntegerNDSet(st, comps, cs, units, errs);
default:
throw new IOException("Unknown IntegerSet type " + dataType);
}
} else {
if (lengths == null) {
throw new IOException("No lengths found for IntegerSet");
}
final int dim;
switch (dataType) {
case DATA_INTEGER_1D_SET:
dim = 1;
break;
case DATA_INTEGER_2D_SET:
dim = 2;
break;
case DATA_INTEGER_3D_SET:
dim = 3;
break;
default:
dim = -1;
break;
}
if (dim > 0 && lengths.length != dim) {
throw new VisADException("Expected " + dim + " length" +
(dim > 1 ? "s" : "") + ", not " +
lengths.length);
}
switch (dataType) {
case DATA_INTEGER_1D_SET:
return new Integer1DSet(st, lengths[0], cs, units, errs);
case DATA_INTEGER_2D_SET:
return new Integer2DSet(st, lengths[0], lengths[1], cs, units, errs);
case DATA_INTEGER_3D_SET:
return new Integer3DSet(st, lengths[0], lengths[1], lengths[2],
cs, units, errs);
case DATA_INTEGER_ND_SET:
return new IntegerNDSet(st, lengths, cs, units, errs);
default:
throw new IOException("Unknown IntegerSet type " + dataType);
}
}
}
public static final void writeDependentData(BinaryWriter writer,
SetType type,
Integer1DSet[] comps,
CoordinateSystem cs,
Unit[] units,
ErrorEstimate[] errors,
GriddedSet set,
Class canonicalClass,
Object token)
throws IOException
{
if (!set.getClass().equals(canonicalClass) &&
!(set instanceof IntegerSet && set instanceof Saveable))
{
return;
}
Object dependToken;
if (token == SAVE_DEPEND_BIG) {
dependToken = token;
} else {
dependToken = SAVE_DEPEND;
}
if(DEBUG_WR_DATA&&!DEBUG_WR_MATH)System.err.println("wrIntSet: type (" + type + ")");
BinarySetType.write(writer, type, set, SAVE_DATA);
if (cs != null) {
if(DEBUG_WR_DATA&&!DEBUG_WR_CSYS)System.err.println("wrIntSet: coordSys (" + cs + ")");
BinaryCoordinateSystem.write(writer, cs, SAVE_DATA);
}
if (units != null) {
if(DEBUG_WR_DATA&&!DEBUG_WR_UNIT){
System.err.println("wrIntSet: List of " + units.length + " Units");
for(int x=0;x<units.length;x++){
System.err.println("wrIntSet: #"+x+": "+units[x]);
}
}
BinaryUnit.writeList(writer, units, SAVE_DATA);
}
if (errors != null) {
if(DEBUG_WR_DATA&&!DEBUG_WR_ERRE){
System.err.println("wrIntSet: List of " + errors.length + " ErrorEstimates");
for(int x=0;x<errors.length;x++){
System.err.println("wrIntSet: #"+x+": "+errors[x]);
}
}
BinaryErrorEstimate.writeList(writer, errors, SAVE_DATA);
}
if (comps != null) {
for (int i = 0; i < comps.length; i++) {
BinaryGeneric.write(writer, comps[i], dependToken);
}
}
}
public static final void write(BinaryWriter writer, SetType type,
int[] lengths, Integer1DSet[] comps,
CoordinateSystem cs, Unit[] units,
ErrorEstimate[] errors, GriddedSet set,
Class canonicalClass, byte dataType,
Object token)
throws IOException
{
writeDependentData(writer, type, comps, cs, units, errors, set,
canonicalClass, token);
// if we only want to write dependent data, we're done
if (token == SAVE_DEPEND || token == SAVE_DEPEND_BIG) {
return;
}
if (!set.getClass().equals(canonicalClass) &&
!(set instanceof IntegerSet && set instanceof Saveable))
{
if(DEBUG_WR_DATA)System.err.println("wrIntSet: punt "+set.getClass().getName());
BinaryUnknown.write(writer, set, token);
return;
}
// see if domain types and component types match
boolean matchedTypes = hasMatchedTypes(type, comps);
final int dim = set.getDimension();
if (!matchedTypes) {
if (dataType == DATA_INTEGER_1D_SET) {
throw new IOException("Components specified for Integer1DSet");
}
if (comps.length != dim) {
throw new IOException("Expected " + dim + " IntegerSet component" +
(dim > 1 ? "s" : "") + ", not " + comps.length);
}
} else {
if (lengths == null) {
throw new IOException("Null " + canonicalClass.getName() +
" lengths");
}
if (lengths.length != dim) {
throw new IOException("Expected " + dim + " IntegerSet length" +
(dim > 1 ? "s" : "") + ", not " +
lengths.length);
}
}
int typeIndex = writer.getTypeCache().getIndex(type);
if (typeIndex < 0) {
throw new IOException("SetType " + type + " not cached");
}
int csIndex = -1;
if (cs != null) {
csIndex = writer.getCoordinateSystemCache().getIndex(cs);
if (csIndex < 0) {
throw new IOException("CoordinateSystem " + cs + " not cached");
}
}
int[] unitsIndex = null;
if (units != null) {
unitsIndex = BinaryUnit.lookupList(writer.getUnitCache(), units);
}
int[] errorsIndex = null;
if (errors != null) {
errorsIndex = BinaryErrorEstimate.lookupList(writer.getErrorEstimateCache(),
errors);
}
final int objLen = computeBytes(matchedTypes, lengths, comps, cs, units,
errors);
DataOutput file = writer.getOutput();
if(DEBUG_WR_DATA)System.err.println("wrIntSet: OBJ_DATA (" + OBJ_DATA + ")");
file.writeByte(OBJ_DATA);
if(DEBUG_WR_DATA)System.err.println("wrIntSet: objLen (" + objLen + ")");
file.writeInt(objLen);
if(DEBUG_WR_DATA)System.err.println("wrIntSet: " +
(dataType == DATA_INTEGER_1D_SET ?
"DATA_INTEGER_1D_SET" :
(dataType == DATA_INTEGER_2D_SET ?
"DATA_INTEGER_2D_SET" :
(dataType == DATA_INTEGER_3D_SET ?
"DATA_INTEGER_3D_SET" :
(dataType == DATA_INTEGER_ND_SET ?
"DATA_INTEGER_ND_SET" : "DATA_???")))) +
"(" + dataType + ")");
file.writeByte(dataType);
if(DEBUG_WR_DATA)System.err.println("wrIntSet: type index (" + typeIndex + ")");
file.writeInt(typeIndex);
if (matchedTypes) {
if(DEBUG_WR_DATA)System.err.println("wrIntSet: FLD_LENGTHS (" + FLD_LENGTHS + ")");
file.writeByte(FLD_LENGTHS);
BinaryIntegerArray.write(writer, lengths, token);
} else {
if(DEBUG_WR_DATA)System.err.println("wrIntSet: FLD_INTEGER_SETS (" + FLD_INTEGER_SETS + ")");
file.writeByte(FLD_INTEGER_SETS);
if(DEBUG_WR_DATA)System.err.println("wrIntSet: set length (" + comps.length + ")");
file.writeInt(comps.length);
for (int i = 0; i < comps.length; i++) {
BinaryGeneric.write(writer, comps[i], token);
}
}
if (csIndex >= 0) {
if(DEBUG_WR_DATA)System.err.println("wrIntSet: FLD_INDEX_COORDSYS (" + FLD_INDEX_COORDSYS + ")");
file.writeByte(FLD_INDEX_COORDSYS);
if(DEBUG_WR_DATA)System.err.println("wrIntSet: coord sys Index (" + csIndex + ")");
file.writeInt(csIndex);
}
if (unitsIndex != null) {
if(DEBUG_WR_DATA)System.err.println("wrIntSet: FLD_INDEX_UNITS (" + FLD_INDEX_UNITS + ")");
file.writeByte(FLD_INDEX_UNITS);
BinaryIntegerArray.write(writer, unitsIndex, token);
}
if (errorsIndex != null) {
if(DEBUG_WR_DATA)System.err.println("wrIntSet: FLD_INDEX_ERRORS (" + FLD_INDEX_ERRORS + ")");
file.writeByte(FLD_INDEX_ERRORS);
BinaryIntegerArray.write(writer, errorsIndex, token);
}
if(DEBUG_WR_DATA)System.err.println("wrIntSet: FLD_END (" + FLD_END + ")");
file.writeByte(FLD_END);
}
}