/* 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.IOException; import visad.BaseUnit; import visad.CommonUnit; import visad.Unit; import visad.VisADException; import visad.data.visad.BinaryObjectCache; import visad.data.visad.BinaryReader; import visad.data.visad.BinaryWriter; public class BinaryUnit implements BinaryObject { public static final int computeBytes(Unit u) { return 4 + BinaryString.computeBytes(u.getIdentifier()) + BinaryString.computeBytes(u.getDefinition().trim()) + 1; } public static final int computeBytes(Unit[] array) { return BinaryIntegerArray.computeBytes(array); } public static final int[] lookupList(BinaryObjectCache cache, Unit[] units) { // make sure there's something to write boolean empty = true; for (int i = 0; i < units.length; i++) { if (units[i] != null) { empty = false; break; } } if (empty) { return null; } int[] indices = new int[units.length]; for (int i = 0; i < units.length; i++) { if (units[i] == null) { indices[i] = -1; } else { indices[i] = cache.getIndex(units[i]); } } return indices; } public static final Unit read(BinaryReader reader) throws IOException, VisADException { BinaryObjectCache cache = reader.getUnitCache(); DataInput file = reader.getInput(); final int objLen = file.readInt(); if(DEBUG_RD_UNIT)System.err.println("cchU: objLen (" + objLen + ")"); // read the index number for this Unit final int index = file.readInt(); if(DEBUG_RD_UNIT)System.err.println("cchU: index (" + index + ")"); // read the Unit identifier String idStr = BinaryString.read(reader); if(DEBUG_RD_UNIT&&!DEBUG_RD_STR)System.err.println("cchU: identifier (" + idStr + ")"); // read the Unit description String defStr = BinaryString.read(reader); if(DEBUG_RD_UNIT&&!DEBUG_RD_STR)System.err.println("cchU: definition (" + defStr + ")"); final byte endByte = file.readByte(); if (endByte != FLD_END) { if(DEBUG_RD_MATH)System.err.println("cchU: read " + endByte + " (wanted FLD_END)"); throw new IOException("Corrupted file (no Unit end-marker)"); } if(DEBUG_RD_MATH)System.err.println("cchU: FLD_END (" + endByte + ")"); Unit u; if (defStr.equals("promiscuous") || defStr.equals("UniversalUnit")) { u = CommonUnit.promiscuous; } else { try { u = visad.data.units.Parser.parse(defStr); } catch (Exception e) { throw new VisADException("Couldn't parse Unit specification \"" + defStr + "\""); } if (!(u instanceof BaseUnit)) { try { Unit namedUnit = u.clone(idStr); u = namedUnit; } catch (Exception e) { e.printStackTrace(); } } } cache.add(index, u); return u; } public static final Unit[] readList(BinaryReader reader) throws IOException { BinaryObjectCache cache = reader.getUnitCache(); DataInput file = reader.getInput(); final int len = file.readInt(); if(DEBUG_RD_UNIT)System.err.println("rdUnits: len (" + len + ")"); if (len < 1) { throw new IOException("Corrupted file" + " (bad Unit array length " + len + ")"); } Unit[] units = new Unit[len]; for (int i = 0; i < len; i++) { final int index = file.readInt(); if(DEBUG_RD_UNIT)System.err.println("rdUnits: #"+i+" index ("+index+")"); if (index < 0) { units[i] = null; } else { units[i] = (Unit )cache.get(index); } if(DEBUG_RD_UNIT)System.err.println("rdUnits: === #"+i+" Unit ("+units[i]+")"); } return units; } public static final int write(BinaryWriter writer, Unit u, Object token) throws IOException { BinaryObjectCache cache = writer.getUnitCache(); int index = cache.getIndex(u); if (index >= 0) { return index; } String uDef = u.getDefinition().trim(); String uId = u.getIdentifier(); // cache the Unit so we can find its index number index = cache.add(u); if (index < 0) { throw new IOException("Couldn't cache Unit " + u); } final int objLen = computeBytes(u); DataOutput file = writer.getOutput(); if(DEBUG_WR_UNIT)System.err.println("wrU: OBJ_UNIT (" + OBJ_UNIT + ")"); file.writeByte(OBJ_UNIT); if(DEBUG_WR_UNIT)System.err.println("wrU: objLen (" + objLen + ")"); file.writeInt(objLen); if(DEBUG_WR_UNIT)System.err.println("wrU: index (" + index + ")"); file.writeInt(index); if(DEBUG_WR_UNIT)System.err.println("wrU: identifier (" + uId + ")"); BinaryString.write(writer, uId, token); if(DEBUG_WR_UNIT)System.err.println("wrU: definition (" + uDef + ")"); BinaryString.write(writer, uDef, token); if(DEBUG_WR_UNIT)System.err.println("wrU: FLD_END (" + FLD_END + ")"); file.writeByte(FLD_END); return index; } public static final int[] writeList(BinaryWriter writer, Unit[] units, Object token) throws IOException { // make sure there's something to write boolean empty = true; for (int i = 0; i < units.length; i++) { if (units[i] != null) { empty = false; break; } } if (empty) { return null; } int[] indices = new int[units.length]; for (int i = 0; i < units.length; i++) { if (units[i] == null) { indices[i] = -1; } else { indices[i] = write(writer, units[i], token); } } return indices; } }