//----------------------------------------------------------------------------- // Copyright (c) 1994,1995 Southeastern Universities Research Association, // Continuous Electron Beam Accelerator Facility // // This software was developed under a United States Government license // described in the NOTICE file included as part of this distribution. // // Jefferson Lab HPC Group, 12000 Jefferson Ave., Newport News, VA 23606 //----------------------------------------------------------------------------- // // Description: // rsvc data object containing multiple dataEntry Object identified // by a string tag // // Author: // Jie Chen // Jefferson Lab HPC Group // // Revision History: // $Log: rsvcData.java,v $ // Revision 1.1.1.1 2000/05/23 15:12:50 pal // cdev_psi_1.7.2 // // Revision 1.1 1999/10/18 17:12:40 chen // *** empty log message *** // // // import java.io.OutputStream; import java.io.InputStream; import java.io.IOException; import java.util.Hashtable; import java.util.Enumeration; import java.lang.NumberFormatException; import rsvcDataTypes; import rsvcTimeStamp; import rsvcDataEntry; import rsvcException; import rsvcDataOutputStream; public class rsvcData { // magic number public static final int _RSVC_MAGIC_NUM = 0x2c45da2a; // this is a hash table holding all data entry objects private Hashtable store_; // no need to put synchronized for memeber functions since // the hashtable is thread safe /** * Construct an empty rsvcData Object */ public rsvcData () { // create a hash table with initial capacity of 1 and load factor 0.25 // to improve look up time for a data entry store_ = new Hashtable (1, (float)0.25); } /** * Construct a rsvcData Object from an existing data object. * This is a deep copy. */ public rsvcData (rsvcData data) { store_ = new Hashtable (1, (float)0.25); Object obj; rsvcDataEntry temp; Enumeration list = data.store_.elements(); while (list.hasMoreElements()) { obj = list.nextElement (); temp = ((rsvcDataEntry)obj).copy(); store_.put (temp.getTag(), temp); } } /** * Return a duplicated data object: deep copy */ public rsvcData copy () { rsvcData data = new rsvcData (); Object obj; rsvcDataEntry temp; Enumeration list = store_.elements(); while (list.hasMoreElements()) { obj = list.nextElement (); temp = ((rsvcDataEntry)obj).copy(); data.store_.put (temp.getTag(), temp); } return data; } /** * Clean up this data object */ public void remove () { store_.clear (); // no free individual elements :-( } /** * Remove a dataEntry with tag */ public int remove (String tag) { if (store_.remove (tag) != null) return 0; return -1; } /** * Insert a single byte with a tag. If a data item with the same * tag is already there, the previous data is removed and new * data is inserted. */ public int insert (String tag, byte data) { int status = remove (tag); rsvcDataEntry entry = new rsvcDataEntry (tag, data); store_.put (tag, entry); return status; } /** * Insert a short value with a tag. If a data item with the same * tag is already there, the previous data is removed and new * data is inserted. */ public int insert (String tag, short data) { int status = remove (tag); rsvcDataEntry entry = new rsvcDataEntry (tag, data); store_.put (tag, entry); return status; } /** * Insert an integer with a tag. If a data item with the same * tag is already there, the previous data is removed and new * data is inserted. */ public int insert (String tag, int data) { int status = remove (tag); rsvcDataEntry entry = new rsvcDataEntry (tag, data); store_.put (tag, entry); return status; } /** * Insert a long value with a tag. If a data item with the same * tag is already there, the previous data is removed and new * data is inserted. */ public int insert (String tag, long data) { int status = remove (tag); rsvcDataEntry entry = new rsvcDataEntry (tag, data); store_.put (tag, entry); return status; } /** * Insert a float value with a tag. If a data item with the same * tag is already there, the previous data is removed and new * data is inserted. */ public int insert (String tag, float data) { int status = remove (tag); rsvcDataEntry entry = new rsvcDataEntry (tag, data); store_.put (tag, entry); return status; } /** * Insert a double with a tag. If a data item with the same * tag is already there, the previous data is removed and new * data is inserted. */ public int insert (String tag, double data) { int status = remove (tag); rsvcDataEntry entry = new rsvcDataEntry (tag, data); store_.put (tag, entry); return status; } /** * Insert a timestamp with a tag. If a data item with the same * tag is already there, the previous data is removed and new * data is inserted. */ public int insert (String tag, rsvcTimeStamp data) { int status = remove (tag); rsvcDataEntry entry = new rsvcDataEntry (tag, data); store_.put (tag, entry); return status; } /** * Insert a String Value with a tag. If a data item with the same * tag is already there, the previous data is removed and new * data is inserted. */ public int insert (String tag, String data) { int status = remove (tag); rsvcDataEntry entry = new rsvcDataEntry (tag, data); store_.put (tag, entry); return status; } /** * Insert an array of byte with a tag. If a data item with the same * tag is already there, the previous data is removed and new * data is inserted. */ public int insert (String tag, byte[] data) { int status = remove (tag); rsvcDataEntry entry = new rsvcDataEntry (tag, data); store_.put (tag, entry); return status; } /** * Insert an array of short with a tag. If a data item with the same * tag is already there, the previous data is removed and new * data is inserted. */ public int insert (String tag, short[] data) { int status = remove (tag); rsvcDataEntry entry = new rsvcDataEntry (tag, data); store_.put (tag, entry); return status; } /** * Insert an array of integer with a tag. If a data item with the same * tag is already there, the previous data is removed and new * data is inserted. */ public int insert (String tag, int[] data) { int status = remove (tag); rsvcDataEntry entry = new rsvcDataEntry (tag, data); store_.put (tag, entry); return status; } /** * Insert an array of long with a tag. If a data item with the same * tag is already there, the previous data is removed and new * data is inserted. */ public int insert (String tag, long[] data) { int status = remove (tag); rsvcDataEntry entry = new rsvcDataEntry (tag, data); store_.put (tag, entry); return status; } /** * Insert an array of float with a tag. If a data item with the same * tag is already there, the previous data is removed and new * data is inserted. */ public int insert (String tag, float[] data) { int status = remove (tag); rsvcDataEntry entry = new rsvcDataEntry (tag, data); store_.put (tag, entry); return status; } /** * Insert an array of double with a tag. If a data item with the same * tag is already there, the previous data is removed and new * data is inserted. */ public int insert (String tag, double[] data) { int status = remove (tag); rsvcDataEntry entry = new rsvcDataEntry (tag, data); store_.put (tag, entry); return status; } /** * Insert an array of timestamp with a tag. If a data item with the same * tag is already there, the previous data is removed and new * data is inserted. */ public int insert (String tag, rsvcTimeStamp[] data) { int status = remove (tag); rsvcDataEntry entry = new rsvcDataEntry (tag, data); store_.put (tag, entry); return status; } /** * Insert an array of string with a tag. If a data item with the same * tag is already there, the previous data is removed and new * data is inserted. */ public int insert (String tag, String[] data) { int status = remove (tag); rsvcDataEntry entry = new rsvcDataEntry (tag, data); store_.put (tag, entry); return status; } /** * Insert a data entry item with a given tag. If a data item with the same * tag is already there, the previous data is removed and new * data is inserted. */ public int insert (rsvcDataEntry data) { int status = remove (data.getTag()); store_.put (data.getTag(), data); return status; } /** * Get a data entry with a tag */ public rsvcDataEntry get (String tag) { Object obj = store_.get (tag); if (obj != null) return (rsvcDataEntry)obj; return null; } /** * Find a data entry with a tag */ public rsvcDataEntry find (String tag) { Object obj = store_.get (tag); if (obj != null) return (rsvcDataEntry)obj; return null; } /** * Find whether this data contains entry with a given tag */ public boolean contains (String tag) { return store_.containsKey (tag); } /** * Change a data entry tag from old to new. * if old tag has no associated data entry, nothing is done */ public void changeTag (String oldtag, String newtag) { Object obj = store_.remove (oldtag); if (obj != null) { rsvcDataEntry data = (rsvcDataEntry)obj; data.setTag (newtag); store_.put (newtag, data); } } /** * Copy a data entry with a oldtag to create a new entry with a newtag. */ public void dup (String oldtag, String newtag) throws rsvcException { if (store_.containsKey (oldtag) != true) throw new rsvcException ("Dup: oldtag has no associated data"); else if (store_.containsKey (newtag) == true) throw new rsvcException ("Dup: newtag has associated data"); else { rsvcDataEntry entry = get (oldtag); rsvcDataEntry newentry = entry.copy(); newentry.setTag (newtag); store_.put (newtag, newentry); } } /** * Replace all data entries with entries inside the provided data object */ public void replace (rsvcData data) { Object obj; rsvcDataEntry temp; Enumeration list = data.store_.elements(); while (list.hasMoreElements ()) { obj = list.nextElement (); temp = (rsvcDataEntry)obj; if (contains (temp.getTag())) insert (temp); } } /** * Compare two data objects. Return true if they equal to each other. */ public boolean equals (rsvcData data) { Object obj0; rsvcDataEntry temp0; Object obj1; rsvcDataEntry temp1; Enumeration list0 = data.store_.elements(); Enumeration list1 = store_.elements(); int size0 = 0; int size1 = 0; while (list0.hasMoreElements ()) { obj0 = list0.nextElement (); size0 ++; } while (list1.hasMoreElements ()) { obj1 = list1.nextElement (); size1 ++; } if (size0 != size1) return false; list0 = data.store_.elements (); while (list0.hasMoreElements ()) { // for each element, find whether there is an element // in this data obj0 = list0.nextElement (); temp0 = (rsvcDataEntry)obj0; temp1 = get (temp0.getTag()); if (temp1 == null || temp0.equals (temp1) == false) return false; } return true; } /** * Return number of data entries inside this object */ public int size () { return store_.size(); } /** * Return number of valid data entries inside this object */ public int numValidEntries () { int count = 0; Object obj; rsvcDataEntry temp; Enumeration list = store_.elements(); while (list.hasMoreElements ()) { obj = list.nextElement (); temp = (rsvcDataEntry)obj; if (temp.getType() != rsvcDataTypes.RSVC_INVALID) count ++; } return count; } /** * Check whether this data is empty */ public boolean isEmpty () { return store_.isEmpty(); } /** * Return enumeration of elements */ public Enumeration elements() { return store_.elements (); } /** * Convert data object to a string representation */ public String toString (String title) { String result = new String (); if (title != null) result = title + "\n"; Object obj; Enumeration list = store_.elements(); while (list.hasMoreElements()) { obj = list.nextElement (); result += obj.toString (); result += "\n"; } return result; } /** * Convert data object to a string representation */ public String toString () { return toString ("Contents: "); } /** * Output contents to standard out */ public void asciiDump () { System.out.print ("\nBeginning of display----------------------------\n"); System.out.print (toString()); System.out.print ("\nEnd of Display----------------------------------\n"); } /** * Calculate stream size of this object */ public int streamSize () { rsvcDataEntry tmp = null; int datasize = 0; int i; // magic number datasize += rsvcDataOutputStream.streamSize (rsvcData._RSVC_MAGIC_NUM); // number of elements datasize += rsvcDataOutputStream.streamSize (numValidEntries()); // add size for each valid item Enumeration list = store_.elements(); while (list.hasMoreElements()) { tmp = (rsvcDataEntry)(list.nextElement()); // individual data entry size datasize += tmp.streamSize (); } return datasize; } /** * Stream rsvcData into a buffered data output stream */ public void streamOut (OutputStream output) throws IOException { rsvcDataEntry tmp; rsvcDataOutputStream writer = new rsvcDataOutputStream (output); try{ writer.write (rsvcData._RSVC_MAGIC_NUM); }catch (IOException e) { throw e; } try { writer.write (numValidEntries ()); }catch (IOException e){ throw e; } Enumeration list = store_.elements (); while (list.hasMoreElements()) { tmp = (rsvcDataEntry)(list.nextElement()); try { tmp.streamOut (writer); }catch (IOException e) { throw e; } } } /** * Stream rsvcData into a buffered data output stream */ public void streamOut (rsvcDataOutputStream writer) throws IOException { rsvcDataEntry tmp; try{ writer.write (rsvcData._RSVC_MAGIC_NUM); }catch (IOException e) { throw e; } try { writer.write (numValidEntries ()); }catch (IOException e){ throw e; } Enumeration list = store_.elements (); while (list.hasMoreElements()) { tmp = (rsvcDataEntry)(list.nextElement()); try { tmp.streamOut (writer); }catch (IOException e) { throw e; } } } /** * Take a input data stream and populate this data object */ public void streamIn (InputStream stream) throws IOException { int i, j; // clean out this object first remove (); // attach input stream rsvcDataInputStream input = new rsvcDataInputStream (stream); // read magic number first int magic; try { magic = input.readInt (); }catch (IOException e){ throw e; } if (magic != rsvcData._RSVC_MAGIC_NUM) { throw new IOException ("Magic number mismatch"); } // read number of elements int count; try { count = input.readInt (); }catch (IOException e) { throw e; } // read each data entry for (i = 0; i < count; i++) { short type; short ndims; int elems, nelems; String tag = null; rsvcDataEntry de = null; // read tag try { tag = input.readString (); }catch (IOException e) { throw e; } // read type try { type = input.readShort (); }catch (IOException e) { throw e; } // read dimension try { ndims = input.readShort (); }catch (IOException e) { throw e; } // read number elements try { elems = input.readInt (); }catch (IOException e) { throw e; } // read data stream compatible to C++ generated stream nelems = elems; if (type != rsvcDataTypes.RSVC_INVALID) { if (ndims == 0) nelems = 1; else nelems = elems; } if (type == rsvcDataTypes.RSVC_INVALID) throw new IOException ("Data Entry Type is invalid"); else if (type == rsvcDataTypes.RSVC_BYTE) { if (nelems == 1) { byte tmp; try { tmp = input.readByte (); }catch (IOException e) { throw e; } de = new rsvcDataEntry (tag, tmp); } else { byte[] tmp = new byte[nelems]; for (j = 0; j < nelems; j++) { try { tmp[j] = input.readByte(); } catch (IOException e) { throw e; } } de = new rsvcDataEntry (tag, tmp); } } else if (type == rsvcDataTypes.RSVC_INT16) { if (nelems == 1) { short tmp; try { tmp = input.readShort (); }catch (IOException e) { throw e; } de = new rsvcDataEntry (tag, tmp); } else { short[] tmp = new short[nelems]; for (j = 0; j < nelems; j++) { try { tmp[j] = input.readShort(); } catch (IOException e) { throw e; } } de = new rsvcDataEntry (tag, tmp); } } else if (type == rsvcDataTypes.RSVC_INT32) { if (nelems == 1) { int tmp; try { tmp = input.readInt (); }catch (IOException e) { throw e; } de = new rsvcDataEntry (tag, tmp); } else { int[] tmp = new int[nelems]; for (j = 0; j < nelems; j++) { try { tmp[j] = input.readInt(); } catch (IOException e) { throw e; } } de = new rsvcDataEntry (tag, tmp); } } else if (type == rsvcDataTypes.RSVC_LONG) { if (nelems == 1) { long tmp; try { tmp = input.readLong (); }catch (IOException e) { throw e; } de = new rsvcDataEntry (tag, tmp); } else { long[] tmp = new long[nelems]; for (j = 0; j < nelems; j++) { try { tmp[j] = input.readLong(); } catch (IOException e) { throw e; } } de = new rsvcDataEntry (tag, tmp); } } else if (type == rsvcDataTypes.RSVC_FLOAT) { if (nelems == 1) { float tmp; try { tmp = input.readFloat (); }catch (IOException e) { throw e; } de = new rsvcDataEntry (tag, tmp); } else { float[] tmp = new float[nelems]; for (j = 0; j < nelems; j++) { try { tmp[j] = input.readFloat(); } catch (IOException e) { throw e; } } de = new rsvcDataEntry (tag, tmp); } } else if (type == rsvcDataTypes.RSVC_DOUBLE) { if (nelems == 1) { double tmp; try { tmp = input.readDouble (); }catch (IOException e) { throw e; } de = new rsvcDataEntry (tag, tmp); } else { double[] tmp = new double[nelems]; for (j = 0; j < nelems; j++) { try { tmp[j] = input.readDouble(); } catch (IOException e) { throw e; } } de = new rsvcDataEntry (tag, tmp); } } else if (type == rsvcDataTypes.RSVC_TIMESTAMP) { if (nelems == 1) { rsvcTimeStamp tmp; try { tmp = input.readTimeStamp (); }catch (IOException e) { throw e; } de = new rsvcDataEntry (tag, tmp); } else { rsvcTimeStamp[] tmp = new rsvcTimeStamp[nelems]; for (j = 0; j < nelems; j++) { try { tmp[j] = input.readTimeStamp(); } catch (IOException e) { throw e; } } de = new rsvcDataEntry (tag, tmp); } } else if (type == rsvcDataTypes.RSVC_STRING) { if (nelems == 1) { String tmp; try { tmp = input.readString (); }catch (IOException e) { throw e; } de = new rsvcDataEntry (tag, tmp); } else { String[] tmp = new String[nelems]; for (j = 0; j < nelems; j++) { try { tmp[j] = input.readString(); } catch (IOException e) { throw e; } } de = new rsvcDataEntry (tag, tmp); } } if (de != null) insert (de); } } /** * Take a input data stream and populate this data object */ public void streamIn (rsvcDataInputStream input) throws IOException { int i, j; // clean out this object first remove (); // read magic number first int magic; try { magic = input.readInt (); }catch (IOException e){ throw e; } if (magic != rsvcData._RSVC_MAGIC_NUM) { throw new IOException ("Magic number mismatch"); } // read number of elements int count; try { count = input.readInt (); }catch (IOException e) { throw e; } // read each data entry for (i = 0; i < count; i++) { short type; short ndims; int elems, nelems; String tag = null; rsvcDataEntry de = null; // read tag try { tag = input.readString (); }catch (IOException e) { throw e; } // read type try { type = input.readShort (); }catch (IOException e) { throw e; } // read dimension try { ndims = input.readShort (); }catch (IOException e) { throw e; } // read number elements try { elems = input.readInt (); }catch (IOException e) { throw e; } // read data stream compatible to C++ generated stream nelems = elems; if (type != rsvcDataTypes.RSVC_INVALID) { if (ndims == 0) nelems = 1; else nelems = elems; } if (type == rsvcDataTypes.RSVC_INVALID) throw new IOException ("Data Entry Type is invalid"); else if (type == rsvcDataTypes.RSVC_BYTE) { if (nelems == 1) { byte tmp; try { tmp = input.readByte (); }catch (IOException e) { throw e; } de = new rsvcDataEntry (tag, tmp); } else { byte[] tmp = new byte[nelems]; for (j = 0; j < nelems; j++) { try { tmp[j] = input.readByte(); } catch (IOException e) { throw e; } } de = new rsvcDataEntry (tag, tmp); } } else if (type == rsvcDataTypes.RSVC_INT16) { if (nelems == 1) { short tmp; try { tmp = input.readShort (); }catch (IOException e) { throw e; } de = new rsvcDataEntry (tag, tmp); } else { short[] tmp = new short[nelems]; for (j = 0; j < nelems; j++) { try { tmp[j] = input.readShort(); } catch (IOException e) { throw e; } } de = new rsvcDataEntry (tag, tmp); } } else if (type == rsvcDataTypes.RSVC_INT32) { if (nelems == 1) { int tmp; try { tmp = input.readInt (); }catch (IOException e) { throw e; } de = new rsvcDataEntry (tag, tmp); } else { int[] tmp = new int[nelems]; for (j = 0; j < nelems; j++) { try { tmp[j] = input.readInt(); } catch (IOException e) { throw e; } } de = new rsvcDataEntry (tag, tmp); } } else if (type == rsvcDataTypes.RSVC_LONG) { if (nelems == 1) { long tmp; try { tmp = input.readLong (); }catch (IOException e) { throw e; } de = new rsvcDataEntry (tag, tmp); } else { long[] tmp = new long[nelems]; for (j = 0; j < nelems; j++) { try { tmp[j] = input.readLong(); } catch (IOException e) { throw e; } } de = new rsvcDataEntry (tag, tmp); } } else if (type == rsvcDataTypes.RSVC_FLOAT) { if (nelems == 1) { float tmp; try { tmp = input.readFloat (); }catch (IOException e) { throw e; } de = new rsvcDataEntry (tag, tmp); } else { float[] tmp = new float[nelems]; for (j = 0; j < nelems; j++) { try { tmp[j] = input.readFloat(); } catch (IOException e) { throw e; } } de = new rsvcDataEntry (tag, tmp); } } else if (type == rsvcDataTypes.RSVC_DOUBLE) { if (nelems == 1) { double tmp; try { tmp = input.readDouble (); }catch (IOException e) { throw e; } de = new rsvcDataEntry (tag, tmp); } else { double[] tmp = new double[nelems]; for (j = 0; j < nelems; j++) { try { tmp[j] = input.readDouble(); } catch (IOException e) { throw e; } } de = new rsvcDataEntry (tag, tmp); } } else if (type == rsvcDataTypes.RSVC_TIMESTAMP) { if (nelems == 1) { rsvcTimeStamp tmp; try { tmp = input.readTimeStamp (); }catch (IOException e) { throw e; } de = new rsvcDataEntry (tag, tmp); } else { rsvcTimeStamp[] tmp = new rsvcTimeStamp[nelems]; for (j = 0; j < nelems; j++) { try { tmp[j] = input.readTimeStamp(); } catch (IOException e) { throw e; } } de = new rsvcDataEntry (tag, tmp); } } else if (type == rsvcDataTypes.RSVC_STRING) { if (nelems == 1) { String tmp; try { tmp = input.readString (); }catch (IOException e) { throw e; } de = new rsvcDataEntry (tag, tmp); } else { String[] tmp = new String[nelems]; for (j = 0; j < nelems; j++) { try { tmp[j] = input.readString(); } catch (IOException e) { throw e; } } de = new rsvcDataEntry (tag, tmp); } } if (de != null) insert (de); } } }