Commit in jevio-base/src/main/java/org/jlab/coda/jevio on MAIN | |||
BankHeader.java | -106 | 1.1.1.1 removed | |
BaseStructure.java | -1567 | 1.1.1.1 removed | |
BaseStructureHeader.java | -230 | 1.1.1.1 removed | |
BlockHeader.java | -482 | 1.1.1.1 removed | |
ByteDataTransformer.java | -510 | 1.1.1.1 removed | |
ByteParser.java | -485 | 1.1.1.1 removed | |
DataType.java | -98 | 1.1.1.1 removed | |
Demo.java | -127 | 1.1.1.1 removed | |
Environment.java | -203 | 1.1.1.1 removed | |
EventBuilder.java | -442 | 1.1.1.1 removed | |
EventParser.java | -445 | 1.1.1.1 removed | |
EventWriter.java | -368 | 1.1.1.1 removed | |
EvioBank.java | -147 | 1.1.1.1 removed | |
EvioDictionaryEntry.java | -200 | 1.1.1.1 removed | |
EvioEvent.java | -248 | 1.1.1.1 removed | |
EvioException.java | -43 | 1.1.1.1 removed | |
EvioFile.java | -1203 | 1.1.1.1 removed | |
EvioFileTest.java | -160 | 1.1.1.1 removed | |
EvioSegment.java | -105 | 1.1.1.1 removed | |
EvioTagSegment.java | -106 | 1.1.1.1 removed | |
EvioXMLDictionary.java | -221 | 1.1.1.1 removed | |
IEvioFilter.java | -29 | 1.1.1.1 removed | |
IEvioListener.java | -35 | 1.1.1.1 removed | |
IEvioProgressListener.java | -11 | 1.1.1.1 removed | |
IEvioStructure.java | -103 | 1.1.1.1 removed | |
IEvioWriter.java | -18 | 1.1.1.1 removed | |
INameProvider.java | -21 | 1.1.1.1 removed | |
NameProvider.java | -55 | 1.1.1.1 removed | |
NameProviderFactory.java | -54 | 1.1.1.1 removed | |
SegmentHeader.java | -98 | 1.1.1.1 removed | |
StructureFinder.java | -78 | 1.1.1.1 removed | |
StructureType.java | -63 | 1.1.1.1 removed | |
TagSegmentHeader.java | -97 | 1.1.1.1 removed | |
-8158 |
clean out jevio base before importing evio 4 sources
diff -N BankHeader.java --- BankHeader.java 27 Jul 2011 23:19:01 -0000 1.1.1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,106 +0,0 @@
-package org.jlab.coda.jevio; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; - -/** - * This the header for an evio bank structure (<code>EvioBank</code>). It does not contain the raw data, just the - * header. Note: since an "event" is really just the outermost bank, this is also the header for an - * <code>EvioEvent</code>. - * - * @author heddle - * - */ -public final class BankHeader extends BaseStructureHeader { - - /** - * Null constructor. - */ - public BankHeader() { - } - - /** - * Constructor - * @param tag the tag for the bank header. - * @param dataType the data type for the content of the bank. - * @param num sometimes, but not necessarily, an ordinal enumeration. - */ - public BankHeader(int tag, DataType dataType, int num) { - super(tag, dataType, num); - } - - /** - * Constructor - * @param tag the tag for the bank header. - * @param dataType the (int) data type for the content of the bank. - * @param num sometimes, but not necessarily, an ordinal enumeration. - */ - public BankHeader(int tag, int dataType, int num) { - super(tag, dataType, num); - } - - /** - * {@inheritDoc} - */ - public int getHeaderLength() {return 2;} - - /** - * {@inheritDoc} - */ - protected void toArray(byte[] bArray, int offset, ByteOrder order) { - if (order == ByteOrder.BIG_ENDIAN) { - ByteDataTransformer.intToBytes(length, bArray, offset); - ByteDataTransformer.shortToBytes(shortValue(tag), bArray, offset+4); - bArray[offset+6] = byteValue(dataType); - bArray[offset+7] = byteValue(number); - } - else { - ByteDataTransformer.intToBytes(Integer.reverseBytes(length), bArray, offset); - bArray[offset+4] = byteValue(number); - bArray[offset+5] = byteValue(dataType); - ByteDataTransformer.shortToBytes(Short.reverseBytes(shortValue(tag)), bArray, offset+6); - } - - } - - - /** - * Obtain a string representation of the bank header. - * - * @return a string representation of the bank header. - */ - @Override - public String toString() { - StringBuffer sb = new StringBuffer(512); - sb.append(String.format("bank length: %d\n", length)); - sb.append(String.format("number: %d\n", number)); - sb.append(String.format("data type: %s\n", getDataTypeName())); - sb.append(String.format("tag: %d\n", tag)); - return sb.toString(); - } - - /** - * Write myself out a byte buffer. This write is relative--i.e., it uses the current position of the buffer. - * - * @param byteBuffer the byteBuffer to write to. - * @return the number of bytes written, which for a BankHeader is 8. - */ - @Override - public int write(ByteBuffer byteBuffer) { - byteBuffer.putInt(length); - - if (byteBuffer.order() == ByteOrder.BIG_ENDIAN) { - byteBuffer.putShort(shortValue(tag)); - byteBuffer.put(byteValue(dataType)); - byteBuffer.put(byteValue(number)); - } - else { - byteBuffer.put(byteValue(number)); - byteBuffer.put(byteValue(dataType)); - byteBuffer.putShort(shortValue(tag)); - } - - return 8; - } - -}
diff -N BaseStructure.java --- BaseStructure.java 27 Jul 2011 23:19:01 -0000 1.1.1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,1567 +0,0 @@
-package org.jlab.coda.jevio; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.util.Arrays; -import java.util.Enumeration; -import java.util.Vector; -import java.util.LinkedList; -import java.io.UnsupportedEncodingException; -import java.io.StringWriter; - -import javax.swing.tree.DefaultMutableTreeNode; -import javax.swing.tree.MutableTreeNode; -import javax.swing.tree.TreeNode; -import javax.xml.stream.XMLStreamException; -import javax.xml.stream.XMLStreamWriter; -import javax.xml.stream.XMLOutputFactory; - -/** - * This is the base class for all evio structures: Banks, Segments, and TagSegments. It implements - * <code>MutableTreeNode</code> because a tree representation of events is created when a new event is parsed. - * - * @author heddle - * @author timmer - add byte order tracking - * - */ -public abstract class BaseStructure implements IEvioStructure, MutableTreeNode, IEvioWriter { - - /** - * Holds the header of the bank. - */ - protected BaseStructureHeader header; - - /** - * The raw data of the structure. - */ - protected byte rawBytes[]; - - /** - * Used if raw data should be interpreted as ints. - */ - protected int intData[]; - - /** - * Used if raw data should be interpreted as longs. - */ - protected long longData[]; - - /** - * Used if raw data should be interpreted as shorts. - */ - protected short shortData[]; - - /** - * Used if raw data should be interpreted as doubles. - */ - protected double doubleData[]; - - /** - * Used if raw data should be interpreted as doubles. - */ - protected float floatData[]; - - /** - * Used if raw data should be interpreted as a string. - */ - protected StringBuffer stringData; - - /** - * Keep track of end of the last string added to stringData (including null but not padding). - */ - private int stringEnd; - - /** - * The number of stored data items like number of banks, ints, floats, etc. - * (not the size in ints or bytes). Some items may be padded such as shorts - * and bytes. This will tell the meaningful number of such data items. - * In the case of containers, returns number of bytes not in header. - */ - protected int numberDataItems; - - /** - * Give the XML output proper indentation. - */ - protected String xmlIndent = ""; - - /** - * Name of this object as an XML element. - */ - protected String xmlElementName; - - /** - * Name of this object's contents as an XML attribute if it is a structure type. - */ - protected String xmlContentAttributeName; - - /** - * Endianness of the data if appropriate, - * either {@link ByteOrder#BIG_ENDIAN} or {@link ByteOrder#LITTLE_ENDIAN}. - */ - protected ByteOrder byteOrder; - - /** - * The parent of the structure. If it is an "event", the parent is null. This is used for creating trees for a - * variety of purposes (not necessarily graphical.) - */ - private BaseStructure parent; - - /** - * Holds the children of this structure. This is used for creating trees for a variety of purposes - * (not necessarily graphical.) - */ - protected Vector<BaseStructure> children; - - /** - * Constructor using a provided header - * - * @param header the header to use. - * @see BaseStructureHeader - */ - public BaseStructure(BaseStructureHeader header) { - this.header = header; - // by default we're big endian since this is java - byteOrder = ByteOrder.BIG_ENDIAN; - setXmlNames(); - } - - /** - * A convenience method use instead of "instanceof" to see what type of structure we have. Note: this returns the - * type of this structure, not the type of data (the content type) this structure holds. - * - * @return the <code>StructureType</code> of this structure. - * @see StructureType - */ - @Override - public abstract StructureType getStructureType(); - - /** - * This is a method that must be filled in by subclasses. Write this structure out as an XML record. - * - * @param xmlWriter the writer used to write the events. It is tied to an open file. - */ - public abstract void toXML(XMLStreamWriter xmlWriter); - - /** - * Get the element name for the structure for writing to XML. - * - * @return the element name for the structure for writing to XML. - */ - public abstract String getXMLElementName(); - - /** - * Write this structure out as an XML format string. - */ - public String toXML() { - - try { - StringWriter sWriter = new StringWriter(); - XMLStreamWriter xmlWriter = XMLOutputFactory.newInstance().createXMLStreamWriter(sWriter); - - toXML(xmlWriter); - return sWriter.toString(); - } - catch (XMLStreamException e) { - e.printStackTrace(); - } - return null; - } - - /** - * Set the name of this object's XML element and also content type attribute if content is structure type. - */ - protected void setXmlNames() { - - // is this structure holding a structure type container? - boolean holdingStructureType = false; - - // type of data held by this container type - DataType type = header.getDataTypeEnum(); - - switch (type) { - case CHAR8: - xmlElementName = "int8"; break; - case UCHAR8: - xmlElementName = "uint8"; break; - case SHORT16: - xmlElementName = "int16"; break; - case USHORT16: - xmlElementName = "uint16"; break; - case INT32: - xmlElementName = "int32"; break; - case UINT32: - xmlElementName = "uint32"; break; - case LONG64: - xmlElementName = "int64"; break; - case ULONG64: - xmlElementName = "uint64"; break; - case FLOAT32: - xmlElementName = "float32"; break; - case DOUBLE64: - xmlElementName = "float64"; break; - case CHARSTAR8: - xmlElementName = "string"; break; - - case UNKNOWN32: - holdingStructureType = true; - xmlContentAttributeName = "unknown32"; - break; - - case TAGSEGMENT: - case ALSOTAGSEGMENT: - holdingStructureType = true; - xmlContentAttributeName = "tagsegment"; - break; - - case SEGMENT: - case ALSOSEGMENT: - holdingStructureType = true; - xmlContentAttributeName = "segment"; - break; - - case BANK: - case ALSOBANK: - holdingStructureType = true; - xmlContentAttributeName = "bank"; - break; - - default: - xmlElementName = "unknown"; break; - } - - if (holdingStructureType) { - // Which container type are we (NOT what are we holding)? - // Because that determines our element name. - StructureType structType = getStructureType(); - if (structType == StructureType.UNKNOWN32) { - xmlElementName = "unknown32"; - } - else { - xmlElementName = getXMLElementName(); - } - } - - } - - /** - * Set the indentation (string of spaces) for more pleasing XML output. - * @param s the indentation (string of spaces) for more pleasing XML output - */ - protected void setXmlIndent(String s) { - xmlIndent = s; - } - - /** - * Increase the indentation (string of spaces) of the XML output. - */ - protected void increaseXmlIndent() { - xmlIndent += " "; - } - - /** - * Decrease the indentation (string of spaces) of the XML output. - */ - protected void decreaseXmlIndent() { - xmlIndent = xmlIndent.substring(0, xmlIndent.length() - 3); - } - - /** - * What is the byte order of this data? - * @return {@link ByteOrder#BIG_ENDIAN} or {@link ByteOrder#LITTLE_ENDIAN} - */ - public ByteOrder getByteOrder() { - return byteOrder; - } - - /** - * Set the byte order of this data. This method <b>cannot</b> be used to swap data. - * It is only used to describe the endianness of the rawdata contained. - * @param byteOrder {@link ByteOrder#BIG_ENDIAN} or {@link ByteOrder#LITTLE_ENDIAN} - */ - public void setByteOrder(ByteOrder byteOrder) { - this.byteOrder = byteOrder; - } - - /** - * Is a byte swap required? This is java and therefore big endian. If data is - * little endian, then a swap is required. - * - * @return <code>true</code> if byte swapping is required (data is little endian). - */ - public boolean isSwap() { - return byteOrder == ByteOrder.LITTLE_ENDIAN; - } - - /** - * Get the description from the name provider (dictionary), if there is one. - * - * @return the description from the name provider (dictionary), if there is one. If not, return - * NameProvider.NO_NAME_STRING. - */ - @Override - public String getDescription() { - return NameProvider.getName(this); - } - - /** - * Obtain a string representation of the structure. - * - * @return a string representation of the structure. - */ - @Override - public String toString() { - StructureType stype = getStructureType(); - DataType dtype = header.getDataTypeEnum(); - - String description = getDescription(); - if (NameProvider.NO_NAME_STRING.equals(description)) { - description = null; - } - String s = stype + " of " + dtype + "s " + " len (ints): " + header.length + " " + " tag: " + header.tag; - if (this instanceof EvioBank) { - s += " num: " + header.number; - } - - if (rawBytes == null) { - s += " data: null"; - } - else { - s += " datalen (bytes): " + rawBytes.length; - } - - if (description != null) { - s += " [" + description + "]"; - } - - int numChildren = (children == null) ? 0 : children.size(); - - s += " <#children: " + numChildren + ">"; - return s; - } - - /** - * This is a method from the IEvioStructure Interface. Return the header for this structure. - * - * @return the header for this structure. - */ - @Override - public BaseStructureHeader getHeader() { - return header; - } - - /** - * Get the number of stored data items like number of banks, ints, floats, etc. - * (not the size in ints or bytes). Some items may be padded such as shorts - * and bytes. This will tell the meaningful number of such data items. - * In the case of containers, returns number of bytes not in header. - * - * @return number of stored data items (not size or length), - * or number of bytes if container - */ - public int getNumberDataItems() { - if (isContainer()) { - numberDataItems = header.getLength() + 1 - header.getHeaderLength(); - } - - // if the calculation has not already been done ... - if (numberDataItems < 1) { - // When parsing a file or byte array, it is not fully unpacked until data - // is asked for specifically, for example as an int array or a float array. - // Thus we don't know how many of a certain item (say doubles) there is. - // But we can figure that out now based on the size of the raw data byte array. - int divisor = 0; - DataType type = header.getDataTypeEnum(); - - switch (type) { - case CHAR8: - case UCHAR8: - divisor = 1; break; - case SHORT16: - case USHORT16: - divisor = 2; break; - case INT32: - case UINT32: - case FLOAT32: - divisor = 4; break; - case LONG64: - case ULONG64: - case DOUBLE64: - divisor = 8; break; - case CHARSTAR8: - String[] s = getStringData(); - numberDataItems = s.length; - break; - default: - } - - if (divisor > 0) numberDataItems = rawBytes.length/divisor; - } - - return numberDataItems; - } - - /** - * Get the length of this structure in bytes, including the header. - * @return the length of this structure in bytes, including the header. - */ - public int getTotalBytes() { - return 4*(header.getLength() + 1); - } - - /** - * Get the raw data of the structure. - * - * @return the raw data of the structure. - */ - public byte[] getRawBytes() { - return rawBytes; - } - - /** - * Set the data for the structure. - * - * @param rawBytes the structure raw data. - */ - public void setRawBytes(byte[] rawBytes) { - this.rawBytes = rawBytes; - } - - /** - * This is a method from the IEvioStructure Interface. Gets the raw data as an integer array, - * if the content type as indicated by the header is appropriate. - * NOTE: since Java does not have unsigned primitives, both INT32 and UINT32 - * data types will be returned as int arrays. The application will have to deal - * with reinterpreting signed ints that are negative as unsigned ints. - * - * @return the data as an int array, or <code>null</code> if this makes no sense for the given content type. - */ - @Override - public int[] getIntData() { - - switch (header.getDataTypeEnum()) { - case INT32: - case UINT32: - if (intData == null) { - if (rawBytes == null) { - return null; - } - intData = ByteDataTransformer.getAsIntArray(rawBytes, byteOrder); - } - return intData; - default: - return null; - } - } - - /** - * This is a method from the IEvioStructure Interface. Gets the raw data as a long array, - * if the content type as indicated by the header is appropriate. - * NOTE: since Java does not have unsigned primitives, both LONG64 and ULONG64 - * data types will be returned as long arrays. The application will have to deal - * with reinterpreting signed longs that are negative as unsigned longs. - * - * @return the data as an long array, or <code>null</code> if this makes no sense for the given content type. - */ - @Override - public long[] getLongData() { - - switch (header.getDataTypeEnum()) { - case LONG64: - case ULONG64: - if (longData == null) { - if (rawBytes == null) { - return null; - } - longData = ByteDataTransformer.getAsLongArray(rawBytes, byteOrder); - } - return longData; - default: - return null; - } - } - - /** - * This is a method from the IEvioStructure Interface. Gets the raw data as a float array, - * if the content type as indicated by the header is appropriate. - * - * @return the data as an double array, or <code>null</code> if this makes no sense for the given contents type. - */ - @Override - public float[] getFloatData() { - - switch (header.getDataTypeEnum()) { - case FLOAT32: - if (floatData == null) { - if (rawBytes == null) { - return null; - } - floatData = ByteDataTransformer.getAsFloatArray(rawBytes, byteOrder); - } - return floatData; - default: - return null; - } - } - - /** - * This is a method from the IEvioStructure Interface. Gets the raw data as a double array, - * if the content type as indicated by the header is appropriate. - * - * @return the data as an double array, or <code>null</code> if this makes no sense for the given content type. - */ - @Override - public double[] getDoubleData() { - - switch (header.getDataTypeEnum()) { - case DOUBLE64: - if (doubleData == null) { - if (rawBytes == null) { - return null; - } - doubleData = ByteDataTransformer.getAsDoubleArray(rawBytes, byteOrder); - } - return doubleData; - default: - return null; - } - } - - /** - * This is a method from the IEvioStructure Interface. Gets the raw data as a double array, - * if the contents type as indicated by the header is appropriate. - * NOTE: since Java does not have unsigned primitives, both SHORT16 and USHORT16 - * data types will be returned as short arrays. The application will have to deal - * with reinterpreting signed shorts that are negative as unsigned longs. - * - * @return the data as an short array, or <code>null</code> if this makes no sense for the given contents type. - */ - @Override - public short[] getShortData() { - - switch (header.getDataTypeEnum()) { - case SHORT16: - case USHORT16: - if (shortData == null) { - if (rawBytes == null) { - return null; - } - shortData = ByteDataTransformer.getAsShortArray(rawBytes, byteOrder); - } - return shortData; - default: - return null; - } - } - - /** - * This is a method from the IEvioStructure Interface. Gets the raw data as an byte array, - * if the contents type as indicated by the header is appropriate. - * NOTE: since Java does not have unsigned primitives, CHARSTAR8, CHAR8 and UCHAR8 - * data types will be returned as byte arrays. The application will have to deal - * with reinterpreting bytes as characters, if necessary. - * - * @return the data as an byte array, or <code>null</code> if this makes no sense for the given contents type. - */ - @Override - public byte[] getByteData() { - - switch (header.getDataTypeEnum()) { - case CHARSTAR8: - case CHAR8: - case UCHAR8: - return rawBytes; - default: - return null; - } - } - - /** - * This is a method from the IEvioStructure Interface. Gets the raw data (ascii) as an - * array of String objects, if the contents type as indicated by the header is appropriate. - * For any other behavior, the user should retrieve the data as a byte array and - * manipulate it in the exact manner desired.<p> - * Originally, in evio versions 2 and 3, only one string was stored. Recent changes cause - * an array of strings to be stored and retrieved. The changes are backwards compatible. - * - * The following is true about the string raw data format: - * <ul> - * <li>All strings are immediately followed by an ending null (0). - * <li>All string arrays are further padded/ended with at least one 0x4 valued ASCII - * char (up to 4 possible). - * <li>The presence of 1 to 4 ending 4's distinguishes the recent string array version from - * the original, single string version. - * <li>The priginal version string may be padded with anything after its ending null. - * <li>Ending non-printing ascii chars (value < 32, = 127) are not included in the string - * since they are there for padding. - * </ul> - * - * @return the data as an array of String objects if DataType is CHARSTAR8, or <code>null</code> - * if this makes no sense for the given type. - * - */ - @Override - public String[] getStringData() { - - String[] strs; - switch (header.getDataTypeEnum()) { - case CHARSTAR8: - if (stringData == null) { - if (rawBytes == null) { - return null; - } - try { - // stringData contains all elements of rawBytes - stringData = new StringBuffer(new String(rawBytes, "US-ASCII")); - } - catch (UnsupportedEncodingException e) { /* will never happen */ } - } - - // Strings are separated by ASCII nulls (char val = 0) and the end is padded by ASCII 4's - // (char val = 4). However, in the legacy versions of evio, there is - // only 1 null-terminated string and anything as padding. To accomodate legacy evio, if - // there is not an ending ASCII value 4, anything past the first null is ignored. - // After doing so, split at the nulls. Do not use the String - // method "split" as any empty trailing strings are unfortunately discarded. - - boolean newVersion = true; - if (stringData.charAt(stringData.length() - 1) != '\004') { - newVersion = false; - } - - char c; - LinkedList<Integer> nullIndexList = new LinkedList<Integer>(); - - for (int i=0; i < stringData.length(); i++) { - c = stringData.charAt(i); - if ( c == '\000' ) { - nullIndexList.add(i); - // only 1 null terminated string originally in evio v2,3 - if (!newVersion) { - break; - } - } - // Look for any non-printing/control characters (not including null) - // and end the string there. Allow new lines (c = 10). - else if ( (c < 32 || c == 127) && c != 10 ) { - break; - } - } - - strs = new String[nullIndexList.size()]; - int lastIndex, firstIndex=0; - for (int i=0; i < nullIndexList.size(); i++) { - lastIndex = nullIndexList.get(i); - strs[i] = stringData.substring(firstIndex, lastIndex); - firstIndex = lastIndex + 1; - } - - return strs; - - default: - return null; - } - } - - /** - * This is a method from the IEvioStructure Interface. Gets the raw data (ascii) as a String, - * if the contents type as indicated by the header is appropriate. - * NOTE: ending non-printing ascii chars (value < 32) are not included in the string - * (since they are most likely there for padding). - * For any other behavior, the user should retrieve the data as a byte array and - * manipulate it in the exact manner desired. - * - * @return the data as a String if DataType is CHARSTAR8, or <code>null</code> - * if this makes no sense for the given type. - * - */ - //@Override - private String getStringDataOrig() { - - switch (header.getDataTypeEnum()) { - case CHARSTAR8: - if (stringData == null) { - if (rawBytes == null) { - return null; - } - try { - // stringData contains all elements of rawBytes - stringData = new StringBuffer(new String(rawBytes, "US-ASCII")); - } - catch (UnsupportedEncodingException e) { /* will never happen */ } - } - - // When fashioning a return string, we assume ascii (one char per byte). - // If there are any bytes = 0 (ie null termination) or other nonprinting chars, - // Java includes them in the string, but ignores them when printing. - // In light of this and the fact that this data type is padded to make an - // integral number of 32 byte chunks, the ending nonprinting chars will be - // stripped off when forming the return string. - String s = null; - try { - int endingNonPrintingChars = 0; - for (int i=rawBytes.length-1; i >= 0; i--) { - if (rawBytes[i] < 32) { - endingNonPrintingChars++; - continue; - } - break; - } - s = new String(rawBytes, 0, rawBytes.length - endingNonPrintingChars, "US-ASCII"); - } - catch (UnsupportedEncodingException e) { /* will never happen */ } - - return s; - - default: - return null; - } - } - - /** - * Get the parent of this structure. The outer event bank is the only structure with a <code>null</code> - * parent (the only orphan). All other structures have non-null parent giving the container in which they - * were embedded. Part of the <code>MutableTreeNode</code> interface. - * - * @return the parent of this structure. - */ - @Override - public BaseStructure getParent() { - return parent; - } - - /** - * Get an enumeration of all the children of this structure. If none, it returns a constant, - * empty Enumeration. Part of the <code>MutableTreeNode</code> interface. - */ - @Override - public Enumeration<?> children() { - if (children == null) { - return DefaultMutableTreeNode.EMPTY_ENUMERATION; - } - return children.elements(); - } - - /** - * Add a child at the given index. - * - * @param child the child to add. - * @param index the target index. Part of the <code>MutableTreeNode</code> interface. - */ - @Override - public void insert(MutableTreeNode child, int index) { - if (children == null) { - children = new Vector<BaseStructure>(10); - } - children.add(index, (BaseStructure) child); - } - - /** - * Convenience method to add a child at the end of the child list. In this application - * where are not concerned with the ordering of the children. - * - * @param child the child to add. It will be added to the end of child list. - */ - public void insert(MutableTreeNode child) { - if (children == null) { - children = new Vector<BaseStructure>(10); - } - //add to end - insert(child, children.size()); - } - - /** - * Removes the child at index from the receiver. Part of the <code>MutableTreeNode</code> interface. - * - * @param index the target index for removal. - */ - @Override - public void remove(int index) { - children.remove(index); - } - - /** - * Removes the child. Part of the <code>MutableTreeNode</code> interface. - * - * @param child the child node being removed. - */ - @Override - public void remove(MutableTreeNode child) { - children.remove(child); - } - - /** - * Remove this node from its parent. Part of the <code>MutableTreeNode</code> interface. - */ - @Override - public void removeFromParent() { - parent.remove(this); - } - - /** - * Set the parent for this node. Part of the <code>MutableTreeNode</code> interface. - */ - @Override - public void setParent(MutableTreeNode parent) { - this.parent = (BaseStructure) parent; - } - - /** - * This method is not relevant for this implementation. - * An empty implementation is provided to satisfy the interface. - * Part of the <code>MutableTreeNode</code> interface. - */ - @Override - public void setUserObject(Object arg0) { - } - - /** - * Checks whether children are allowed. Structures of structures can have children. - * Structures of primitive data can not. Thus is is entirely determined by the content type. - * Part of the <code>MutableTreeNode</code> interface. - * - * @return <code>true</code> if this node does not hold primitive data, - * i.e., if it is a structure of structures (a container). - */ - @Override - public boolean getAllowsChildren() { - return header.getDataTypeEnum().isStructure(); - } - - /** - * Obtain the child at the given index. Part of the <code>MutableTreeNode</code> interface. - * - * @param index the target index. - * @return the child at the given index. - * @throws ArrayIndexOutOfBoundsException if the index is out of range - * ({@code index < 0 || index >= children.size()}) - */ - @Override - public TreeNode getChildAt(int index) { - return children.elementAt(index); - } - - /** - * Get the count of the number of children. Part of the <code>MutableTreeNode</code> interface. - * - * @return the number of children. - */ - @Override - public int getChildCount() { - if (children == null) { - return 0; - } - return children.size(); - } - - /** - * Get the index of a node. Part of the <code>MutableTreeNode</code> interface. - * - * @return the index of the target node. - */ - @Override - public int getIndex(TreeNode node) { - return children.indexOf(node); - } - - /** - * Checks whether this is a leaf. Leaves are structures with no children. - * All structures that contain primitive data are leaf structures. - * Part of the <code>MutableTreeNode</code> interface.<br> - * Note: this means that an empty container, say a Bank of Segments that have no segments, is a leaf. - * - * @return <code>true</code> if this is a structure with a primitive data type, i.e., it is not a container - * structure that contains other structures. - */ - @Override - public boolean isLeaf() { - return ((children == null) || (children.size() < 1)); - } - - /** - * Checks whether this structure is a container, i.e. a structure of structures. - * @return <code>true</code> if this structure is a container. This is the same check as - * <code>getAllowsChildren()</code>. - */ - public boolean isContainer() { - return header.getDataTypeEnum().isStructure(); - } - - /** - * This calls the xml write for all of a structure's children. - * It is used for a depth-first traversal through the tree - * when writing an event to xml. - * - * @param xmlWriter the writer used to write the events. It is tied to an open file. - */ - protected void childrenToXML(XMLStreamWriter xmlWriter) { - if (children == null) { - return; - } - - increaseXmlIndent(); - - for (BaseStructure structure : children) { - structure.setXmlIndent(xmlIndent); - structure.toXML(xmlWriter); - } - - decreaseXmlIndent(); - } - - /** - * All structures have a common start to their xml writing - * - * @param xmlWriter the writer used to write the events. It is tied to an open file. - */ - protected void commonXMLStart(XMLStreamWriter xmlWriter) { - try { - xmlWriter.writeCharacters("\n"); - xmlWriter.writeCharacters(xmlIndent); - xmlWriter.writeStartElement(xmlElementName); - } - catch (XMLStreamException e) { - e.printStackTrace(); - } - } - - /** - * All structures have a common data write for their xml writing - * - * @param xmlWriter the writer used to write the events. It is tied to an open file. - */ - protected void commonXMLDataWrite(XMLStreamWriter xmlWriter) { - - // only leafs write data - if (!isLeaf()) { - return; - } - - try { - String s; - String indent = String.format("\n%s", xmlIndent); - - BaseStructureHeader header = getHeader(); - switch (header.getDataTypeEnum()) { - case DOUBLE64: - double doubledata[] = getDoubleData(); - for (int i=0; i < doubledata.length; i++) { - if (i%2 == 0) { - xmlWriter.writeCharacters(indent); - } - s = String.format("%24.16e ", doubledata[i]); - xmlWriter.writeCharacters(s); - } - break; - - case FLOAT32: - float floatdata[] = getFloatData(); - for (int i=0; i < floatdata.length; i++) { - if (i%2 == 0) { - xmlWriter.writeCharacters(indent); - } - s = String.format("%14.7e ", floatdata[i]); - xmlWriter.writeCharacters(s); - } - break; - - case LONG64: - case ULONG64: - long longdata[] = getLongData(); - for (int i=0; i < longdata.length; i++) { - if (i%2 == 0) { - xmlWriter.writeCharacters(indent); - } - s = String.format("%20d ", longdata[i]); - xmlWriter.writeCharacters(s); - } - break; - - case INT32: - case UINT32: - int intdata[] = getIntData(); - for (int i=0; i < intdata.length; i++) { - if (i%5 == 0) { - xmlWriter.writeCharacters(indent); - } - s = String.format("%11d ", intdata[i]); - xmlWriter.writeCharacters(s); - } - break; - - case SHORT16: - case USHORT16: - short shortdata[] = getShortData(); - for (int i=0; i < shortdata.length; i++) { - if (i%5 == 0) { - xmlWriter.writeCharacters(indent);[truncated at 1000 lines; 571 more skipped]
diff -N BaseStructureHeader.java --- BaseStructureHeader.java 27 Jul 2011 23:19:01 -0000 1.1.1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,230 +0,0 @@
-package org.jlab.coda.jevio; - -import java.nio.ByteOrder; - -/** - * This the header for the base structure (<code>BaseStructure</code>). It does not contain the raw data, just the - * header. The three headers for the actual structures found in evio (BANK, SEGMENT, and TAGSEMENT) all extend this. - * - * @author heddle - * - */ -public abstract class BaseStructureHeader implements IEvioWriter { - - /** - * The length of the structure in ints. This never includes the first header word itself (which contains the - * length). - */ - protected int length; - - /** - * The structure tag. - */ - protected int tag = 0; - - /** - * The numeric data type of the structure. - */ - protected int dataType = 0; - - /** - * The number. Only Banks have a number field in their header, so this is only relevant for Banks. - */ - protected int number; - - /** - * Null constructor. - */ - public BaseStructureHeader() { - } - - /** - * Constructor - * @param tag the tag for the header. - * @param dataType the enum data type for the content of the structure. - */ - public BaseStructureHeader(int tag, DataType dataType) { - this(tag, dataType.getValue(), 0); - } - - /** - * Constructor - * @param tag the tag for the header. - * @param dataType the (int) data type for the content of the structure. - */ - public BaseStructureHeader(int tag, int dataType) { - this(tag, dataType, 0); - } - - /** - * Constructor - * @param tag the tag for the header. - * @param dataType the data type for the content of the structure. - * @param num sometimes, but not necessarily, an ordinal enumeration. - */ - public BaseStructureHeader(int tag, DataType dataType, int num) { - this(tag, dataType.getValue(), num); - } - - /** - * Constructor - * @param tag the tag for the event header. - * @param dataType the (int) data type for the content of the structure. - * @param num sometimes, but not necessarily, an ordinal enumeration. - */ - public BaseStructureHeader(int tag, int dataType, int num) { - this.tag = tag; - this.dataType = dataType; - this.number = num; - } - - - /** - * Get the number. Only Banks have a number field in their header, so this is only relevant for Banks. - * - * @return the number. - */ - public int getNumber() { - return number; - } - - /** - * Set the number. Only Banks have a number field in their header, so this is only relevant for Banks. - * - * @param number the number. - */ - public void setNumber(int number) { - //num is really an unsigned byte - if (number < 0) { - number += 256; - } - this.number = number; - } - - /** - * Get the data type for the structure. - * - * @return the data type for the structure. - */ - public int getDataType() { - return dataType; - } - - /** - * Set the numeric data type for the structure. - * - * @param dataType the dataTtype for the structure. - */ - public void setDataType(int dataType) { - this.dataType = dataType; - } - - /** - * Get the length of the structure in ints, not counting the length word. - * - * @return Get the length of the structure in ints (not counting the length word). - */ - public int getLength() { - return length; - } - - /** - * Set the length of the structure in ints, not counting the length word. - * - * @param length the length of the structure in ints, not counting the length word. - */ - public void setLength(int length) { - this.length = length; - } - - /** - * Get the length of the structure's header in ints. This includes the first header word itself - * (which contains the length) and in the case of banks, it also includes the second header word. - * - * @return Get the length of the structure's header in ints. - */ - public abstract int getHeaderLength(); - - /** - * Write myself out as a byte array of evio format data - * into the given byte array in the specified byte order. - * - * @return byte array containing evio format data of this bank in currently set byte order - */ - protected abstract void toArray(byte[] bArray, int offset, ByteOrder order); - - /** - * Get the structure tag. - * - * @return the structure tag. - */ - public int getTag() { - return tag; - } - - /** - * Set the structure tag. - * - * @param tag the structure tag. - */ - public void setTag(int tag) { - this.tag = tag; - } - - /** - * Returns the data type as a string. - * - * @return the data type as a string. - */ - public String getDataTypeName() { - return DataType.getName(dataType); - } - - /** - * Returns the data type for data stored in this structure as a <code>DataType</code> enum. - * - * @return the data type for data stored in this structure as a <code>DataType</code> enum. - * @see DataType - */ - public DataType getDataTypeEnum() { - return DataType.getDataType(dataType); - } - - /** - * Obtain a string representation of the structure header. - * - * @return a string representation of the structure header. - */ - @Override - public String toString() { - StringBuffer sb = new StringBuffer(512); - sb.append(String.format("structure length: %d\n", length)); - sb.append(String.format("data type: %s\n", getDataTypeName())); - sb.append(String.format("tag: %d\n", tag)); - return sb.toString(); - } - - /** - * Convenience method to return the byte value of an integer. Although - * the parameter is an Integer, use "autoboxing" to pass in a primitive. I.e., - * byteValue(3) works just fine. - * @param integer the integer whose byte value is needed. Can pass in a primitive int. - * @return the byte value of the integer. - */ - public byte byteValue(Integer integer) { - return integer.byteValue(); - } - - /** - * Convenience method to return the short value of an integer. Although - * the parameter is an Integer, use "autoboxing" to pass in a primitive. I.e., - * shortValue(3345) works just fine. - * @param integer the integer whose short value is needed. Can pass in a primitive int. - * @return the short value of the integer. - */ - public short shortValue(Integer integer) { - return integer.shortValue(); - } - - -}
diff -N BlockHeader.java --- BlockHeader.java 27 Jul 2011 23:19:01 -0000 1.1.1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,482 +0,0 @@
-package org.jlab.coda.jevio; - -import java.nio.ByteBuffer; - -/** - * This holds a evio block header, also known as a physical record header. Unfortunately, in versions 2 & 3, evio files - * impose an anachronistic block structure. The complication that arises is that logical records (events) will - * sometimes cross physical record boundaries. - * - * - * <code><pre> - * ############################ - * Evio block header: - * ############################ - * - * MSB(31) LSB(0) - * <--- 32 bits ------------------------> - * _______________________________________ - * | Block Length | - * |_____________________________________| - * | Block Number | - * |_____________________________________| - * | Header Length = 8 | - * |_____________________________________| - * | Start | - * |_____________________________________| - * | End | - * |_____________________________________| - * | Version | - * |_____________________________________| - * | Reserved 1 | - * |_____________________________________| - * | Reserved 2 | - * |_____________________________________| - * - * - * Block Length = number of ints in block (including this one). - * This is fixed for versions 1-3, generally at 8192 (32768 bytes) - * Block Number = id number - * Header Length = number of ints in this header (always 8) - * Start = offset to first event header in block - * End = offset to last data word in block - * Version = evio format version - * Reserved 1 = reserved - * Reserved 2 = magic number (0xc0da0100) used to check endianness - * - * </pre></code> - * - * - * @author heddle - * - */ -public class BlockHeader implements IEvioWriter { - - /** - * The maximum block size in 32 bit ints in this (versions 2 & 3) implementation of evio. - * There is, in actuality, no limit on size; however, the version 2/3 C library only used - * 8192 as the block size. - */ - public static final int MAX_BLOCK_SIZE = 32768; - - /** - * The magic number, should be the value of <code>magicNumber</code>. - */ - public static final int MAGIC_NUMBER = 0xc0da0100; - - /** - * The block (physical record) size in 32 bit ints. - */ - private int size; - - /** - * The block number. In a file, this is usually sequential. - */ - private int number; - - /** - * The block header length. Should be 8 in all cases, so getting this correct constitutes a check. - */ - private int headerLength; - - /** - * Offset (in ints, relative to start of block) to the start of the first event (logical record) that begins in this - * block. For the first event it will just be = 8, the size of the block header. For subsequent physical records it - * will generally not be 8. Note that a logical record (event) that spans three blocks (physical records) will have - * <code>start = 0</code>. - * - */ - private int start; - - /** - * The number of valid words (header + data) in the block (physical record.) This is normally the same as the block - * size, except for the last block (physical record) in the file. <br> - * NOTE: for evio files, even if end < size (blocksize) for the last block (physical record), the data behind it - * will be padded with zeroes so that the file size is an integer multiple of the block size. - */ - private int end; - - /** - * The evio version. - */ - private int version; - - /** - * First reserved word. Sometimes this is used to indicate the ordinal number of the last event that starts - * within this block--but that is not mandated. In that case, if the previous block had a value of - * reserved1 = 6 and this block has a value of 9, then this block contains the end of event 6, all of events - * 7 and 8, and the start of event 9--unless it ends exactly on the end of event 8.<br> - */ - private int reserved1; - - /** - * This is the magic word: 0xc0da0100 (formerly reserved2). Used to check endianness. - */ - private int magicNumber; - - /** - * This is not part of the block header proper. It is a position in a memory buffer of the start of the block - * (physical record). It is kept for convenience. - */ - private int bufferStartingPosition = -1; - - /** - * Get the size of the block (physical record). - * - * @return the size of the block (physical record) in ints. - */ - public int getSize() { - return size; - } - - /** - * Null constructor initializes all fields to zero. - */ - public BlockHeader() { - size = 0; - number = 0; - headerLength = 0; - start = 0; - end = 0; - version = 0; - reserved1 = 0; - magicNumber = 0; - } - - /** - * Creates a BlockHeader for evio version 2 format. Only the (block) <code>size</code> - * and (block) <clode>number</code> are provided. The other six words, which can be - * modified by setters, are initialized to these values:<br> - *<ul> - *<li><code>headerLength</code> is initialized to 8<br> - *<li><code>start</code> is initialized to 8<br> - *<li><code>end</code> is initialized to <code>size</code><br> - *<li><code>version</code> is initialized to 2<br> - *<li><code>reserved1</code> is initialized to 0<br> - *<li><code>magicNumber</code> is initialized to <code>MAGIC_NUMBER</code><br> - *</ul> - * @param size the size of the block in ints. - * @param number the block number--usually sequential. - */ - public BlockHeader(int size, int number) { - this.size = size; - this.number = number; - headerLength = 8; - start = 8; - end = size; - version = 2; - reserved1 = 0; - magicNumber = MAGIC_NUMBER; - } - - /** - * Set the size of the block (physical record). Some trivial checking is done. - * - * @param size the new value for the size, in ints. - * @throws EvioException - */ - public void setSize(int size) throws EvioException { - if ((size < 8) || (size > MAX_BLOCK_SIZE)) { - throw new EvioException(String.format("Bad value for size in block (physical record) header: %d", size)); - } - - // I'm not sure why this restriction is in here - timmer - if ((size % 256) != 0) { - throw new EvioException(String.format( - "Bad value for size in block (physical record) header: %d (must be multiple of 256 ints)", size)); - } - this.size = size; - } - - /** - * Get the starting position of the block (physical record.). This is the offset (in ints, relative to start of - * block) to the start of the first event (logical record) that begins in this block. For the first event it will - * just be = 8, the size of the block header. For subsequent blocks it will generally not be 8. Note that a - * an event that spans three blocks (physical records) will have <code>start = 0</code>. - * - * NOTE: a logical record (event) that spans three blocks (physical records) will have <code>start = 0</code>. - * - * @return the starting position of the block (physical record.) - */ - public int getStart() { - return start; - } - - /** - * Set the starting position of the block (physical record.). This is the offset (in ints, relative to start of - * block) to the start of the first event (logical record) that begins in this block. For the first event it will - * just be = 8, the size of the block header. For subsequent blocks it will generally not be 8. Some trivial - * checking is done. Note that an event that spans three blocks (physical records) will have - * <code>start = 0</code>. - * - * NOTE: a logical record (event) that spans three blocks (physical records) will have <code>start = 0</code>. - * - * @param start the new value for the start. - * @throws EvioException - */ - public void setStart(int start) throws EvioException { - if ((start < 0) || (start > MAX_BLOCK_SIZE)) { - throw new EvioException(String.format("Bad value for start in block (physical record) header: %d", start)); - } - this.start = start; - } - - /** - * Get the ending position of the block (physical record.) This is the number of valid words (header + data) in the - * block (physical record.) This is normally the same as the block size, except for the last block (physical record) - * in the file.<br> - * NOTE: for evio files, even if end < size (blocksize) for the last block (physical record), the data behind it - * will be padded with zeroes so that the file size is an integer multiple of the block size. - * - * @return the ending position of the block (physical record.) - */ - public int getEnd() { - return end; - } - - /** - * Set the ending position of the block (physical record.) This is the number of valid words (header + data) in the - * block (physical record.) This is normally the same as the block size, except for the last block (physical record) - * in the file. Some trivial checking is done.<br> - * NOTE: for evio files, even if end < size (blocksize) for the last block (physical record), the data behind it - * will be padded with zeroes so that the file size is an integer multiple of the block size. - * - * @param end the new value for the end. - * @throws EvioException - */ - public void setEnd(int end) throws EvioException { - if ((end < 8) || (end > MAX_BLOCK_SIZE)) { - throw new EvioException(String.format("Bad value for end in block (physical record) header: %d", end)); - } - this.end = end; - } - - /** - * Get the block number for this block (physical record). In a file, this is usually sequential. - * - * @return the block number for this block (physical record). - */ - public int getNumber() { - return number; - } - - /** - * Set the block number for this block (physical record). In a file, this is usually sequential. This is not - * checked. - * - * @param number the number of the block (physical record). - */ - public void setNumber(int number) { - this.number = number; - } - - /** - * Get the block header length, in ints. This should be 8. - * - * @return the block header length. This should be 8. - */ - public int getHeaderLength() { - return headerLength; - } - - /** - * Set the block header length, in ints. This should be 8. However, since this is usually read as part of reading - * the physical record header, it is a good check to have a setter rather than just fix its value at 8. - * - * param headerLength the new block header length. This should be 8. - * - * @throws EvioException if headerLength is not 8. - */ - public void setHeaderLength(int headerLength) throws EvioException { - if (headerLength != 8) { - String message = "Bad Block (Physical Record) Header Length: " + headerLength; - throw new EvioException(message); - } - this.headerLength = headerLength; - } - - /** - * Get the evio version of the block (physical record) header. - * - * @return the evio version of the block (physical record) header. - */ - public int getVersion() { - return version; - } - - /** - * Sets the evio version. Should be 2 or 3 but no check is performed here, see - * {@link EvioFile#nextBlockHeader()}. - * - * @param version the evio version of evio. - */ - public void setVersion(int version) { - this.version = version; - } - - /** - * Get the first reserved word in the block (physical record) header. - * - * @return the first reserved word in the block (physical record). - */ - public int getReserved1() { - return reserved1; - } - - /** - * Sets the value of reserved 1. - * - * @param reserved1 the value for reserved1. - */ - public void setReserved1(int reserved1) { - this.reserved1 = reserved1; - } - - /** - * Get the magic number the block (physical record) header which should be 0xc0da0100. - * Formerly this location in the header was called "reserved2". - * - * @return the magic number in the block (physical record). - */ - public int getMagicNumber() { - return magicNumber; - } - - /** - * Sets the value of magicNumber. This should match the constant MAGIC_NUMBER. - * If it doesn't, some obvious possibilities: <br> - * 1) The evio data (perhaps from a file) is screwed up.<br> - * 2) The reading algorithm is screwed up. <br> - * 3) The endianess is not being handled properly. - * - * @param magicNumber the new value for magic number. - * @throws EvioException - */ - public void setMagicNumber(int magicNumber) throws EvioException { - if (magicNumber != MAGIC_NUMBER) { - throw new EvioException(String.format("Value for magicNumber %8x does not match MAGIC_NUMBER 0xc0da0100.", - magicNumber)); - } - this.magicNumber = magicNumber; - } - - /** - * Obtain a string representation of the block (physical record) header. - * - * @return a string representation of the block (physical record) header. - */ - @Override - public String toString() { - StringBuffer sb = new StringBuffer(512); - sb.append(String.format("block size: %d\n", size)); - sb.append(String.format("number: %d\n", number)); - sb.append(String.format("headerLen: %d\n", headerLength)); - sb.append(String.format("start: %d\n", start)); - sb.append(String.format("end: %d\n", end)); - sb.append(String.format("version: %d\n", version)); - sb.append(String.format("reserved1: %d\n", reserved1)); - sb.append(String.format("magicNumber: %8x\n", magicNumber)); - sb.append(String.format(" *buffer start: %d\n", getBufferStartingPosition())); - sb.append(String.format(" *next start: %d\n", nextBufferStartingPosition())); - return sb.toString(); - } - - /** - * Get the position in the buffer (in bytes) of this block's last data word.<br> - * - * @return the position in the buffer (in bytes) of this block's last data word. - */ - public int getBufferEndingPosition() { - return bufferStartingPosition + 4*end; - } - - /** - * Get the starting position in the buffer (in bytes) from which this header was read--if that happened.<br> - * This is not part of the block header proper. It is a position in a memory buffer of the start of the block - * (physical record). It is kept for convenience. It is up to the reader to set it. - * - * @return the starting position in the buffer (in bytes) from which this header was read--if that happened. - */ - public int getBufferStartingPosition() { - return bufferStartingPosition; - } - - /** - * Set the starting position in the buffer (in bytes) from which this header was read--if that happened.<br> - * This is not part of the block header proper. It is a position in a memory buffer of the start of the block - * (physical record). It is kept for convenience. It is up to the reader to set it. - * - * @param bufferStartingPosition the starting position in the buffer from which this header was read--if that - * happened. - */ - public void setBufferStartingPosition(int bufferStartingPosition) { - this.bufferStartingPosition = bufferStartingPosition; - } - - /** - * Determines where the start of the next block (physical record) header in some buffer is located (in bytes). - * This assumes the start position has been maintained by the object performing the buffer read. - * - * @return the start of the next block (physical record) header in some buffer is located (in bytes). - */ - public int nextBufferStartingPosition() { - return bufferStartingPosition + 4 * size; - } - - /** - * Determines where the start of the first event (logical record) in this block (physical record) is located - * (in bytes). This assumes the start position has been maintained by the object performing the buffer read. - * - * @return where the start of the first event (logical record) in this block (physical record) is located - * (in bytes). Returns 0 if start is 0, signaling that this entire physical record is part of a - * logical record that spans at least three physical records. - */ - public int firstEventStartingPosition() { - if (start == 0) { - return 0; - } - return bufferStartingPosition + 4 * start; - } - - /** - * Gives the bytes remaining in this block (physical record) given a buffer position. The position is an absolute - * position in a byte buffer. This assumes that the absolute position in <code>bufferStartingPosition</code> is - * being maintained properly by the reader. - * - * @param position the absolute current position is a byte buffer. - * @return the number of bytes remaining in this block (physical record.) - * @throws EvioException - */ - public int bytesRemaining(int position) throws EvioException { - if (position < bufferStartingPosition) { - throw new EvioException("Provided position is less than buffer starting position."); - } - - int nextBufferStart = nextBufferStartingPosition(); -//System.out.println("bytesRemaining: position = " + position + ", next buffer start = " + nextBufferStart); - if (position > nextBufferStart) { - throw new EvioException("Provided position beyond buffer end position."); - } - - return nextBufferStart - position; - } - - /** - * Write myself out a byte buffer. This write is relative--i.e., it uses the current position of the buffer. - * - * @param byteBuffer the byteBuffer to write to. - * @return the number of bytes written, which for a BlockHeader is 32. - */ - @Override - public int write(ByteBuffer byteBuffer) { - byteBuffer.putInt(size); - byteBuffer.putInt(number); - byteBuffer.putInt(headerLength); // should always be 8 - byteBuffer.putInt(start); - byteBuffer.putInt(end); - byteBuffer.putInt(version); - byteBuffer.putInt(reserved1); - byteBuffer.putInt(magicNumber); - return 32; - } -}
diff -N ByteDataTransformer.java --- ByteDataTransformer.java 27 Jul 2011 23:19:01 -0000 1.1.1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,510 +0,0 @@
-package org.jlab.coda.jevio; - -import java.nio.*; - -/** - * This utility class contains methods for transforming a raw byte array into arrays of - * other types such as int and double. It also contains a method for byte swapping evio - * format data as well as other handy methods. - * - * @author heddle - * @author timmer - * @author wolin - * - */ -public class ByteDataTransformer { - - /** - * Converts a byte array into an int array. - * - * @param bytes the byte array. - * @param byteOrder the endianness of the data in the byte array, - * {@link ByteOrder#BIG_ENDIAN} or {@link ByteOrder#LITTLE_ENDIAN}. - * @return the raw bytes converted into an int array. - */ - public static int[] getAsIntArray(byte bytes[], ByteOrder byteOrder) { - ByteBuffer byteBuffer = ByteBuffer.wrap(bytes).order(byteOrder); - int intsize = bytes.length / 4; - int array[] = new int[intsize]; - for (int i = 0; i < intsize; i++) { - array[i] = byteBuffer.getInt(); - } - return array; - } - - /** - * Converts a byte array into an short array. - * - * @param bytes the byte array. - * @param byteOrder the endianness of the data in the byte array, - * {@link ByteOrder#BIG_ENDIAN} or {@link ByteOrder#LITTLE_ENDIAN}. - * @return the raw bytes converted into an int array. - */ - public static short[] getAsShortArray(byte bytes[], ByteOrder byteOrder) { - ByteBuffer byteBuffer = ByteBuffer.wrap(bytes).order(byteOrder); - int shortsize = bytes.length / 2; - short array[] = new short[shortsize]; - for (int i = 0; i < shortsize; i++) { - array[i] = byteBuffer.getShort(); - } - return array; - } - - - /** - * Converts a byte array into a long array. - * - * @param bytes the byte array. - * @param byteOrder the endianness of the data in the byte array, - * {@link ByteOrder#BIG_ENDIAN} or {@link ByteOrder#LITTLE_ENDIAN}. - * @return the raw bytes converted into a long array. - */ - public static long[] getAsLongArray(byte bytes[], ByteOrder byteOrder) { - ByteBuffer byteBuffer = ByteBuffer.wrap(bytes).order(byteOrder); - int longsize = bytes.length / 8; - long array[] = new long[longsize]; - for (int i = 0; i < longsize; i++) { - array[i] = byteBuffer.getLong(); - } - return array; - } - - /** - * Converts a byte array into a double array. - * - * @param bytes the byte array. - * @param byteOrder the endianness of the data in the byte array, - * {@link ByteOrder#BIG_ENDIAN} or {@link ByteOrder#LITTLE_ENDIAN}. - * @return the raw bytes converted into a double array. - */ - public static double[] getAsDoubleArray(byte bytes[], ByteOrder byteOrder) { - ByteBuffer byteBuffer = ByteBuffer.wrap(bytes).order(byteOrder); - int doublesize = bytes.length / 8; - double array[] = new double[doublesize]; - for (int i = 0; i < doublesize; i++) { - array[i] = byteBuffer.getDouble(); - } - return array; - } - - /** - * Converts a byte array into a float array. - * - * @param bytes the byte array. - * @param byteOrder the endianness of the data in the byte array, - * {@link ByteOrder#BIG_ENDIAN} or {@link ByteOrder#LITTLE_ENDIAN}. - * @return the raw bytes converted into a float array. - */ - public static float[] getAsFloatArray(byte bytes[], ByteOrder byteOrder) { - ByteBuffer byteBuffer = ByteBuffer.wrap(bytes).order(byteOrder); - int floatsize = bytes.length / 4; - float array[] = new float[floatsize]; - for (int i = 0; i < floatsize; i++) { - array[i] = byteBuffer.getFloat(); - } - return array; - } - - /** - * Copies an integer value into 4 bytes of a byte array. - * @param intVal integer value - * @param b byte array - * @param off offset into the byte array - */ - public static final void intToBytes(int intVal, byte[] b, int off) { - b[off] = (byte) ((intVal & 0xff000000) >>> 24); - b[off+1] = (byte) ((intVal & 0x00ff0000) >>> 16); - b[off+2] = (byte) ((intVal & 0x0000ff00) >>> 8); - b[off+3] = (byte) (intVal & 0x000000ff); - } - - - /** - * Copies a short value into 2 bytes of a byte array. - * @param val short value - * @param b byte array - * @param off offset into the byte array - */ - public static final void shortToBytes(short val, byte[] b, int off) { - b[off] = (byte) ((val & 0x0000ff00) >>> 8); - b[off+1] = (byte) (val & 0x000000ff); - } - - - /** - * Copies a 2-byte short value into a 4-byte int while preserving bit pattern. - * In other words, it treats the short as an unsigned value. The resulting int - * does NOT undergo sign extension (bits of highest 2 bytes are not all ones), - * and will not be a negative number. - * - * @param shortVal short value considered to be unsigned - * @return the equivalent int value - */ - public static final int shortBitsToInt(short shortVal) { - return (shortVal & 0x0000ffff); - } - - - /** - * Copies a 1-byte byte value into a 4-byte int while preserving bit pattern. - * In other words, it treats the byte as an unsigned value. The resulting int - * does NOT undergo sign extension (bits of highest 3 bytes are not all ones), - * and will not be a negative number. - * - * @param byteVal byte value considered to be unsigned - * @return the equivalent int value - */ - public static final int byteBitsToInt(byte byteVal) { - return (byteVal & 0x000000ff); - } - - - //-------------------------------- - // EVIO FORMAT DATA SWAPPING - //-------------------------------- - - /** - * Swaps evio format data (event or bank) contained in a ByteBuffer. - * NOTE: the byte order of the source buffer must be set properly by - * the caller using {@link ByteBuffer#order(java.nio.ByteOrder)}. - * - * @param srcBuf evio data (event or bank) to be swapped - * @param destBuf destination for swapped evio data; if null, swap in place - * @throws EvioException if data not in evio format - */ - public static void swap(ByteBuffer srcBuf, ByteBuffer destBuf) throws EvioException { - ByteOrder srcOrder = srcBuf.order(); - ByteOrder destOrder = ByteOrder.BIG_ENDIAN; - - if (srcOrder == ByteOrder.BIG_ENDIAN) { - destOrder = ByteOrder.LITTLE_ENDIAN; - } - - // writing into this buffer will automatically swap bytes - if (destBuf != null) { - destBuf.order(destOrder); - } - - try { - swapBank(srcBuf, destBuf); - } - catch (BufferOverflowException e) { - throw new EvioException("Data not in evio format", e); - } - catch (BufferUnderflowException e) { - throw new EvioException("Data not in evio format", e); - } - catch (IndexOutOfBoundsException e) { - throw new EvioException("Data not in evio format", e); - } - - // if swapping in place, set buffer's new byte order now that it's completely swapped - if (destBuf == null) { - srcBuf.order(destOrder); - } - } - - /** - * Swaps evio event or bank data. - * - * @param bank evio data (event or bank) to be swapped - * @return bank object with swapped data - * @throws EvioException if data not in evio format - */ - public static EvioEvent swap(EvioBank bank) throws EvioException { - ByteOrder newOrder = (bank.getByteOrder() == ByteOrder.BIG_ENDIAN) ? ByteOrder.LITTLE_ENDIAN : ByteOrder.BIG_ENDIAN; - - byte[] array = bank.toArray(); - ByteBuffer buf = ByteBuffer.wrap(array); - buf.order(bank.getByteOrder()); - - try { - swapBank(buf, null); - } - catch (BufferOverflowException e) { - throw new EvioException("Data not in evio format", e); - } - catch (BufferUnderflowException e) { - throw new EvioException("Data not in evio format", e); - } - catch (IndexOutOfBoundsException e) { - throw new EvioException("Data not in evio format", e); - } - - ByteParser parser = new ByteParser(); - buf.rewind(); - // set buf to new byte order now that it's completely swapped - buf.order(newOrder); - return parser.parseEvent(buf); - } - - /** - * Copies buffer of 4-byte integers. - * - * @param srcBuf input data buffer - * @param length number of integer words to copy - * @param destBuf destination data buffer; if null, swap in place - */ - private static void copyData(ByteBuffer srcBuf, int length, ByteBuffer destBuf) { - - if (destBuf == null) return; - - int numBytes = 4*length; - byte[] bytes = new byte[numBytes]; - - srcBuf.get(bytes, 0, numBytes); - destBuf.put(bytes, 0, numBytes); - - return; - } - - /** - * Swaps buffer of 4-byte integers. - * - * @param srcBuf input data buffer - * @param length number of integer words to swap - * @param destBuf destination data buffer; if null, swap in place - */ - private static void swapIntArray(ByteBuffer srcBuf, int length, ByteBuffer destBuf) { - - if (destBuf == null) { - int pos; - for (int i = 0; i < length; i++) { - pos = srcBuf.position(); - srcBuf.putInt(Integer.reverseBytes(srcBuf.getInt(pos))); - } - } - else { - for (int i = 0; i < length; i++) { - destBuf.putInt(srcBuf.getInt()); - } - } - return; - } - - /** - * Swaps 8-byte longs packed into 4-byte integer buffer. - * - * @param srcBuf input data buffer - * @param length number of integer words to swap - * @param destBuf destination data buffer; if null, swap in place - */ - private static void swapLongArray(ByteBuffer srcBuf, int length, ByteBuffer destBuf) { - int numLongs = length/2; - - if (destBuf == null) { - int pos; - for (int i = 0; i < numLongs; i++) { - pos = srcBuf.position(); - srcBuf.putLong(Long.reverseBytes(srcBuf.getLong(pos))); - } - } - else { - for (int i = 0; i < numLongs; i++) { - destBuf.putLong(srcBuf.getLong()); - } - } - return; - } - - /** - * Swaps 2-byte shorts packed in 4-byte integer buffer. - * - * @param srcBuf input data buffer - * @param length number of integer words to swap - * @param destBuf destination data buffer; if null, swap in place - */ - private static void swapShortArray(ByteBuffer srcBuf, int length, ByteBuffer destBuf) { - int numShorts = 2*length; - - if (destBuf == null) { - int pos; - for (int i = 0; i < numShorts; i++) { - pos = srcBuf.position(); - srcBuf.putShort(Short.reverseBytes(srcBuf.getShort(pos))); - } - } - else { - for (int i = 0; i < numShorts; i++) { - destBuf.putShort(srcBuf.getShort()); - } - } - return; - } - - /** - * Swap an evio bank. - * - * @param srcBuf evio bank data to swap - * @param destBuf destination buffer for swapped bank; if null, swap in place - * @return size of data (in 4 byte ints) contained in bank plus header - * @throws EvioException if data not in evio format - */ - private static int swapBank(ByteBuffer srcBuf, ByteBuffer destBuf) throws EvioException { - - // parse 2 header ints to find data length & type - srcBuf.mark(); - int dataLength = srcBuf.getInt() - 1; - DataType dataType = DataType.getDataType((srcBuf.getInt() >> 8) & 0xff); - srcBuf.reset(); - - // swap 2 header ints - swapIntArray(srcBuf, 2, destBuf); // does not advance position - - // swap data following header - swapData(srcBuf, dataType, dataLength, destBuf); - - // return total length of this bank including both header ints - return dataLength + 2; - } - - /** - * Swap an evio segment. - * - * @param srcBuf byte buffer to swap - * @param destBuf destination buffer for swapped event; if null, swap in place - * @return size of data (in 4 byte ints) contained in segment plus header - * @throws EvioException if data not in evio format - */ - private static int swapSegment(ByteBuffer srcBuf, ByteBuffer destBuf) throws EvioException { - - // parse 1 header int to find data length & type - srcBuf.mark(); - int d = srcBuf.getInt(); - srcBuf.reset(); - int dataLength = (d & 0xffff); - DataType dataType = DataType.getDataType((d >> 16) & 0xff); - - // swap 1 header int - swapIntArray(srcBuf, 1, destBuf); - - // swap data following header - swapData(srcBuf, dataType, dataLength, destBuf); - - // return total length of this bank including header int - return dataLength + 1; - } - - - /** - * Swap an evio tagsegment. - * - * @param srcBuf byte buffer to swap - * @param destBuf destination buffer for swapped event; if null, swap in place - * @return size of data (in 4 byte ints) contained in tagsegment plus header - * @throws EvioException if data not in evio format - */ - private static int swapTagSegment(ByteBuffer srcBuf, ByteBuffer destBuf) throws EvioException { - - // parse 1 header int to find data length & type - srcBuf.mark(); - int d = srcBuf.getInt(); - srcBuf.reset(); - int dataLength = (d & 0xffff); - DataType dataType = DataType.getDataType((d >> 16) & 0xf); - - // swap 1 header int - swapIntArray(srcBuf, 1, destBuf); - - // swap data following header - swapData(srcBuf, dataType, dataLength, destBuf); - - // return total length of this bank including header int - return dataLength + 1; - } - - - /** - * Handle the swapping of evio data or container of evio data. - * - * @param srcBuf byte buffer to swap - * @param type type of data in the data buffer - * @param length length of data (4 byte ints) to swap - * @param destBuf destination buffer for swapped event; if null, swap in place - * @throws EvioException if data not in evio format - */ - private static void swapData(ByteBuffer srcBuf, DataType type, int length, - ByteBuffer destBuf) throws EvioException { - - int len = 0; - - // A container (bank, segment, or tagsegment) to be swapped has called this method. - // We switch on the type of data or containers held by this top-level container. - // If data is held, just swap it here or call swap<Fragment> methods if containers - // are held. - - switch (type) { - - // 32 bit swap - case INT32: - case UINT32: - case FLOAT32: - swapIntArray(srcBuf, length, destBuf); - break; - - // 16 bit swap - case SHORT16: - case USHORT16: - swapShortArray(srcBuf, length, destBuf); - break; - - // 64 bit swap - case LONG64: - case ULONG64: - case DOUBLE64: - swapLongArray(srcBuf, length, destBuf); - break; - - // no swap - case UNKNOWN32: - case CHAR8: - case UCHAR8: - case CHARSTAR8: - copyData(srcBuf, length, destBuf); - break; - - // container of banks - case BANK: - case ALSOBANK: - // The calling container is a bank of banks and may contain - // multiple banks, each of which need to be swapped. - while (len < length) { - len += swapBank(srcBuf, destBuf); - } - if (len != length) { - throw new EvioException("Data not in evio format"); - } - break; - - // container of segments - case SEGMENT: - case ALSOSEGMENT: - while (len < length) { - len += swapSegment(srcBuf, destBuf); - } - if (len != length) { - throw new EvioException("Data not in evio format"); - } - break; - - // container of tagsegments - case TAGSEGMENT: - case ALSOTAGSEGMENT: - while (len < length) { - len += swapTagSegment(srcBuf, destBuf); - } - if (len != length) { - throw new EvioException("Data not in evio format"); - } - break; - - // unknown type, just copy - default: - copyData(srcBuf, length, destBuf); - break; - } - - return; - } - -}
diff -N ByteParser.java --- ByteParser.java 27 Jul 2011 23:19:01 -0000 1.1.1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,485 +0,0 @@
-package org.jlab.coda.jevio; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.io.DataInputStream; -import java.io.IOException; - -import javax.swing.event.EventListenerList; -import javax.swing.tree.DefaultTreeModel; - -/** - * This class controls the creating of an event by the parsing of a byte array. - * Unlike the EventParser class, it does not use a singleton pattern because the parsing of bytes is used primarily - * for reading data sent over the network or from an ET system and is used in a multithreaded environment. - * This class acts like EvioFile and EventParser together, except the data in our case is obtained by reading - * IO streams (eg. from a socket). Thus, it's much simpler than reading a file and the result is we have a - * byte array to parse.<p> - * - * @author timmer - */ -public class ByteParser { - - /** - * Listener list for structures (banks, segments, tagsegments) encountered while processing an event. - */ - private EventListenerList evioListenerList; - - /** - * This flag determines whether notification of listeners is active. Normally it is. But in some cases it should be - * temporarily suspended. For example, in a "goto event" process, the listeners will not be notified of the - * intervening events as the file is scanned to get to the target event. - */ - protected boolean notificationActive = true; - - /** - * A single global structure filter. This may prove to be a limitation: perhaps we want one per listener. - */ - private IEvioFilter evioFilter; - - /** - * No-arg constructor. - */ - public ByteParser() { } - - - /** - * This is the workhorse method for parsing the byte array. It will drill down and uncover all structures - * (banks, segments, and tagsegments) and notify any interested listeners in a SAX-Like manner. <br> - * Note: applications may choose not to provide a listener. In that case, when the event is parsed, its structures - * may be accessed through the event's tree model, i.e., via <code>event.getTreeModel()</code>. - * - * @param bytes the binary data to be parsed. - * @param byteOrder the byte order of the binary array, either - * {@link ByteOrder#BIG_ENDIAN} or {@link ByteOrder#LITTLE_ENDIAN}. - * @return an EvioEvent object created from the byte array. - * @throws EvioException if data not in evio format. - */ - public EvioEvent parseEvent(byte[] bytes, ByteOrder byteOrder) throws EvioException { - // wrap the byte array in a ByteBuffer for ease of parsing & automatic byte swapping - ByteBuffer buf = ByteBuffer.wrap(bytes).order(byteOrder); - return parseEvent(buf); - } - - - /** - * This is the workhorse method for parsing the byte buffer. It will drill down and uncover all structures - * (banks, segments, and tagsegments) and notify any interested listeners in a SAX-Like manner. <br> - * Note: applications may choose not to provide a listener. In that case, when the event is parsed, its structures - * may be accessed through the event's tree model, i.e., via <code>event.getTreeModel()</code>. - * - * @param buf buffer of binary data to parse. - * @return an EvioEvent object created from the byte array. - * @throws EvioException if data not in evio format. - */ - public EvioEvent parseEvent(ByteBuffer buf) throws EvioException { - return (EvioEvent) parseBank(buf, null, null); - } - - - /** - * This is a method for reading data over a DataInputStream and parsing it into an EvioEvent. - * - * @param in data input stream containing binary data to parse in network byte order. - * @param byteOrder the byte order of the input bytes, either - * {@link ByteOrder#BIG_ENDIAN} or {@link ByteOrder#LITTLE_ENDIAN}. - * @return an EvioEvent object created from the data input stream. - * @throws IOException if IO error. - * @throws EvioException if data not in evio format. - */ - public EvioEvent readEvent(DataInputStream in, ByteOrder byteOrder) throws IOException, EvioException { - int length, lengthRead; - length = lengthRead = in.readInt(); - if (byteOrder == ByteOrder.LITTLE_ENDIAN) { - length = Integer.reverseBytes(lengthRead); - } - - byte[] buffer = new byte[4*(length + 1)]; - - in.readFully(buffer, 4, 4*length); - - // put length at beginning of array - ByteDataTransformer.intToBytes(lengthRead, buffer, 0); - - return parseEvent(buffer, byteOrder); - } - - - /** - * Parse a ByteBuffer as an evio bank. - * - * @param buf buffer of binary data to parse. - * @param event the EvioEvent object being created. - * @param parent the parent of the bank being created. - * @return the EvioBank object created from the byte buffer. - * @throws EvioException if data not in evio format. - */ - private BaseStructure parseBank(ByteBuffer buf, EvioEvent event, BaseStructure parent) - throws EvioException { - - // create & fill bank header - BankHeader header = createBankHeader(buf); - - // create bank - EvioBank bank; - - // if no event created yet, we're top level so create it - if (event == null) { - // create event which is top-level bank - event = new EvioEvent(header); - event.treeModel = new DefaultTreeModel(event); - bank = event; - } - else { - // create bank and put it in parent - bank = new EvioBank(header); - bank.setParent(parent); - event.insert(bank, parent); - } - - return parseStructure(buf, event, bank); - } - - - - /** - * Parse a ByteBuffer as an evio segment. - * - * @param buf buffer of binary data to parse. - * @param event the EvioEvent object being created. - * @param parent the parent of the segment being created. - * @return the EvioSegment object created from the byte buffer. - * @throws EvioException if data not in evio format. - */ - private BaseStructure parseSegment(ByteBuffer buf, EvioEvent event, BaseStructure parent) - throws EvioException { - - // create & fill segment header - SegmentHeader header = createSegmentHeader(buf); - - // create segment and put it in parent - EvioSegment segment = new EvioSegment(header); - segment.setParent(parent); - event.insert(segment, parent); - - return parseStructure(buf, event, segment); - } - - - /** - * Parse a ByteBuffer as an evio tag segment. - * - * @param buf buffer of binary data to parse. - * @param event the EvioEvent object being created. - * @param parent the parent of the tag segment being created. - * @return the EvioTagSegment object created from the byte buffer. - * @throws EvioException if data not in evio format. - */ - private BaseStructure parseTagSegment(ByteBuffer buf, EvioEvent event, BaseStructure parent) - throws EvioException { - - // create & fill tag segment header - TagSegmentHeader header = createTagSegmentHeader(buf); - - // create tag segment and put it in parent - EvioTagSegment tagSegment = new EvioTagSegment(header); - tagSegment.setParent(parent); - event.insert(tagSegment, parent); - - return parseStructure(buf, event, tagSegment); - } - - - /** - * Parse the evio structure (bank, segment, or tagsegment). - * - * @param buf buffer of binary data to parse. - * @param event the EvioEvent object being created. - * @param structure the structure object being created (bank, segment, or tagsegment) - * @return object passed in as structure - * @throws EvioException if data not in evio format. - */ - private BaseStructure parseStructure(ByteBuffer buf, EvioEvent event, BaseStructure structure) - throws EvioException { - - BaseStructureHeader header = structure.getHeader(); - - // save position (before raw data) for returning to later - buf.mark(); - - // length of non-header (raw) data in 32-bit ints - int dataLen = header.getLength() + 1 - header.getHeaderLength(); - - // store raw bytes in structure - byte[] bytes = new byte[4*dataLen]; - buf.get(bytes, 0, bytes.length); - structure.setRawBytes(bytes); - structure.setByteOrder(buf.order()); - - // Does the present structure contain structures? (as opposed to a leaf, which contains primitives). If - // it is a leaf (condition == true), we are done. That will leave the raw bytes in the "leaf" structures - // (e.g., a bank of ints) -- which will be interpreted by the various "get data" methods. - if (!header.getDataTypeEnum().isStructure()) { - // notify the listeners - notifyEvioListeners(event, structure); - return structure; - } - - // Move buffer position before raw data since the raw - // data is an evio container and needs to be parsed. - buf.reset(); - - // parse structures contained in raw data - parseData(buf, header.getDataTypeEnum(), dataLen, event, structure); - - // return same structure passed in - return structure; - } - - - /** - * Create a bank header from the next eight bytes of the byte buffer. - * - * @param byteBuffer the byte buffer, probably from a bank that encloses this new bank. - * @return the new header. - */ - private BankHeader createBankHeader(ByteBuffer byteBuffer) { - BankHeader header = new BankHeader(); - header.setLength(byteBuffer.getInt()); - - if (byteBuffer.order() == ByteOrder.BIG_ENDIAN) { - // interested in bit pattern, not negative numbers - header.setTag(ByteDataTransformer.shortBitsToInt(byteBuffer.getShort())); - header.setDataType(ByteDataTransformer.byteBitsToInt(byteBuffer.get())); - header.setNumber(ByteDataTransformer.byteBitsToInt(byteBuffer.get())); - } - else { - header.setNumber(ByteDataTransformer.byteBitsToInt(byteBuffer.get())); - header.setDataType(ByteDataTransformer.byteBitsToInt(byteBuffer.get())); - header.setTag(ByteDataTransformer.shortBitsToInt(byteBuffer.getShort())); - } - return header; - } - - - /** - * Create a segment header from the next four bytes of the byte buffer. - * - * @param byteBuffer the byte buffer, probably from a bank that encloses this new segment. - * @return the new header. - */ - private SegmentHeader createSegmentHeader(ByteBuffer byteBuffer) { - SegmentHeader header = new SegmentHeader(); - - if (byteBuffer.order() == ByteOrder.BIG_ENDIAN) { - header.setTag(ByteDataTransformer.byteBitsToInt(byteBuffer.get())); - header.setDataType(ByteDataTransformer.byteBitsToInt(byteBuffer.get())); - header.setLength(ByteDataTransformer.shortBitsToInt(byteBuffer.getShort())); - } - else { - header.setLength(ByteDataTransformer.shortBitsToInt(byteBuffer.getShort())); - header.setDataType(ByteDataTransformer.byteBitsToInt(byteBuffer.get())); - header.setTag(ByteDataTransformer.byteBitsToInt(byteBuffer.get())); - } - - return header; - } - - - /** - * Create a tag segment header from the next four bytes of the byte buffer. - * - * @param byteBuffer the byte buffer, probably from a bank that encloses this new tag segment. - * @return the new header. - */ - private TagSegmentHeader createTagSegmentHeader(ByteBuffer byteBuffer) { - TagSegmentHeader header = new TagSegmentHeader(); - - int temp; - - if (byteBuffer.order() == ByteOrder.BIG_ENDIAN) { - temp = ByteDataTransformer.shortBitsToInt(byteBuffer.getShort()); - header.setTag(temp >>> 4); - header.setDataType(temp & 0xF); - header.setLength(ByteDataTransformer.shortBitsToInt(byteBuffer.getShort())); - } - else { - header.setLength(ByteDataTransformer.shortBitsToInt(byteBuffer.getShort())); - temp = ByteDataTransformer.shortBitsToInt(byteBuffer.getShort()); - header.setTag(temp >>> 4); - header.setDataType(temp & 0xF); - } - - return header; - } - - - /** - * Handle parsing raw data bytes into containers of data. - * - * @param buf the buffer of binary data to parse. - * @param type the type of container in the data buffer. - * @param length the length of data in the data buffer to be parsed for these containers. - * @param event the EvioEvent object being created. - * @param parent the parent of the structure (banks, segments, or tagsegments) being created. - * @throws EvioException if data not in evio format. - */ - private void parseData(ByteBuffer buf, DataType type, int length, EvioEvent event, BaseStructure parent) - throws EvioException { - - int len = 0; - - switch (type) { - - // parent is container of banks - case BANK: - case ALSOBANK: - // The calling container is a bank of banks and may contain - // multiple banks, each of which need to be parsed. - while (len < length) { - BaseStructure bank = parseBank(buf, event, parent); - len += bank.getHeader().getLength() + 1; - } - if (len != length) { - throw new EvioException("Data not in evio format"); - } - - break; - - // parent is container of segments - case SEGMENT: - case ALSOSEGMENT: - while (len < length) { - BaseStructure seg = parseSegment(buf, event, parent); - len += seg.getHeader().getLength() + 1; - } - if (len != length) { - throw new EvioException("Data not in evio format"); - } - break; - - // parent is container of tagsegments - case TAGSEGMENT: - case ALSOTAGSEGMENT: - while (len < length) { - BaseStructure tag = parseTagSegment(buf, event, parent); - len += tag.getHeader().getLength() + 1; - } - if (len != length) { - throw new EvioException("Data not in evio format"); - } - break; - - // non-container type, do nothing - default: - break; - } - - // notify the listeners - notifyEvioListeners(event, parent); - - return; - } - - - /** - * This is when a structure is encountered while parsing an event. It notifies all listeners about the structure. - * - * @param structure the structure encountered, which may be a Bank, Segment, or TagSegment. - */ - protected void notifyEvioListeners(EvioEvent evioEvent, IEvioStructure structure) { - - // are notifications turned off? - if (!notificationActive) { - return; - } - - if (evioListenerList == null) { - return; - } - - // if there is a global filter, lets use it. - if (evioFilter != null) { - if (!evioFilter.accept(structure.getStructureType(), structure.getHeader())) { - return; - } - } - - // Guaranteed to return a non-null array - Object[] listeners = evioListenerList.getListenerList(); - - // This weird loop is the bullet proof way of notifying all listeners. - for (int i = listeners.length - 2; i >= 0; i -= 2) { - if (listeners[i] == IEvioListener.class) { - ((IEvioListener) listeners[i + 1]).gotStructure(evioEvent, structure); - } - } - } - - /** - * Remove an Evio listener. Evio listeners listen for structures encountered when an event is being parsed. - * - * @param listener The Evio listener to remove. - */ - public void removeEvioListener(IEvioListener listener) { - - if ((listener == null) || (evioListenerList == null)) { - return; - } - - evioListenerList.remove(IEvioListener.class, listener); - } - - /** - * Add an Evio listener. Evio listeners listen for structures encountered when an event is being parsed. - * - * @param listener The Evio listener to add. - */ - public void addEvioListener(IEvioListener listener) { - - if (listener == null) { - return; - } - - if (evioListenerList == null) { - evioListenerList = new EventListenerList(); - } - - evioListenerList.add(IEvioListener.class, listener); - } - - /** - * Get the flag determining whether notification of listeners is active. Normally it is. But in some cases it should - * be temporarily suspended. For example, in a "goto event" process, the listeners will not be notified of the - * intervening events as the file is scanned to get to the target event. - * - * @return <code>true</code> if notification of events to the listeners is active. - */ - public boolean isNotificationActive() { - return notificationActive; - } - - /** - * Set the flag determining whether notification of listeners is active. Normally it is. But in some cases it - * should be temporarily suspended. For example, in a "goto event" process, the listeners will not be notified of - * the intervening events as the file is scanned to get to the target event. - * - * @param notificationActive set <code>true</code> if notification of events to the listeners is active. - */ - public void setNotificationActive(boolean notificationActive) { - this.notificationActive = notificationActive; - } - - /** - * Set the global filter used for filtering structures. If set to <code>null</code>, the default, then all - * structures will be sent to the listeners. - * - * @param evioFilter the filter to set. - * @see IEvioFilter - */ - public void setEvioFilter(IEvioFilter evioFilter) { - this.evioFilter = evioFilter; - } - - -}
diff -N DataType.java --- DataType.java 27 Jul 2011 23:19:01 -0000 1.1.1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,98 +0,0 @@
-package org.jlab.coda.jevio; - -/** - * This an enum used to convert data type numerical values to a more meaningful name. For example, the data type with - * value 0xe corresponds to the enum BANK. Mostly this is used for printing. - * - * @author heddle - * - */ -public enum DataType { - - UNKNOWN32 (0x0), - UINT32 (0x1), - FLOAT32 (0x2), - CHARSTAR8 (0x3), - SHORT16 (0x4), - USHORT16 (0x5), - CHAR8 (0x6), - UCHAR8 (0x7), - DOUBLE64 (0x8), - LONG64 (0x9), - ULONG64 (0xa), - INT32 (0xb), - TAGSEGMENT (0xc), - SEGMENT (0xd), - BANK (0xe), - ALSOBANK (0x10), - ALSOSEGMENT (0x20), - ALSOTAGSEGMENT (0x40); - - private int value; - - private DataType(int value) { - this.value = value; - } - - /** - * Get the enum's value. - * - * @return the value, e.g., 0xe for a BANK - */ - public int getValue() { - return value; - } - - /** - * Obtain the name from the value. - * - * @param value the value to match. - * @return the name, or "UNKNOWN". - */ - public static String getName(int value) { - DataType datatypes[] = DataType.values(); - for (DataType dt : datatypes) { - if (dt.value == value) { - return dt.name(); - } - } - return "UNKNOWN"; - } - - /** - * Obtain the enum from the value. - * - * - * @param value the value to match. - * @return the matching enum, or <code>null</code>. - */ - public static DataType getDataType(int value) { - DataType datatypes[] = DataType.values(); - for (DataType dt : datatypes) { - if (dt.value == value) { - return dt; - } - } - return null; - } - - /** - * Convenience routine to see if "this" data type is a structure (a container.) - * @return <code>true</code> if the data type corresponds to one of the structure - * types: BANK, SEGMENT, or TAGSEGMENT. - */ - public boolean isStructure() { - switch (this) { - case BANK: - case SEGMENT: - case TAGSEGMENT: - return true; - case ALSOBANK: - case ALSOSEGMENT: - case ALSOTAGSEGMENT: - return true; - default: - return false; - } - } -}
diff -N Demo.java --- Demo.java 27 Jul 2011 23:19:01 -0000 1.1.1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,127 +0,0 @@
-package org.jlab.coda.jevio; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; - -/** - * Used for demoing the JEvio library. - * - * @author heddle - * - */ -public class Demo implements IEvioListener { - - /** - * Main program for testing - * - * @param args the command line arguments. - */ - public static void main(String args[]) { - System.out.println("Test of EvioFile class."); - - String cwd = Environment.getInstance().getCurrentWorkingDirectory(); - - // assumes we have a directory "testdata" with the test files in the cwd. -// String testEventFile = cwd + "\\testdata\\dennis.ev"; -// String testEventFile = cwd + "\\testdata\\out.ev"; -// String testDictFile = cwd + "\\testdata\\eviodict.xml"; - String testEventFile = cwd + File.separator + "testdata" + File.separator + "out.ev"; - String testDictFile = cwd + File.separator + "testdata" + File.separator + "eviodict.xml"; - - EvioFile evioFile = null; - - try { - File file = new File(testEventFile); - System.out.println("ev file: " + testEventFile + " size: " + file.length()); - - evioFile = new EvioFile(testEventFile); - - // uncomment below to test a filter -// IEvioFilter myFilter = new IEvioFilter() { -// @Override -// public boolean accept(StructureType structureType, BaseStructureHeader structureHeader) { -// DataType dataType = structureHeader.getDataTypeEnum(); -// -// return (dataType == DataType.DOUBLE64); -// } -// }; -// EventParser.getInstance().setEvioFilter(myFilter); - - - //add myself as a listener - EventParser.getInstance().addEvioListener(new Demo()); - - // create a dictionary, set the global name provider - NameProvider.setProvider(NameProviderFactory.createNameProvider(new File(testDictFile))); - - // try a block test - EvioFileTest.readAllBlockHeadersTest(evioFile); - - // try read all events test - EvioFileTest.readAllEventsTest(evioFile); - - // just count the blocks - EvioFileTest.totalBlockCount(evioFile); - - // try processing some events - EvioFileTest.parseEventsTest(evioFile, 1); - } - catch (FileNotFoundException e) { - e.printStackTrace(); - System.exit(1); - } - catch (IOException e) { - e.printStackTrace(); - System.exit(1); - } - - } - - public void startEventParse(EvioEvent evioEvent) { } - - public void endEventParse(EvioEvent evioEvent) { } - - /** - * This IEvioListener has received a structure as the result of an event being parsed. - * @param evioEvent the event being parsed. - * @param structure the structure that I received. It is a BANK, SEGEMENT - * or TAGSEGMENT. - */ - @Override - public void gotStructure(EvioEvent evioEvent, IEvioStructure structure) { - - BaseStructureHeader header = structure.getHeader(); - - System.out.println("------------------"); - System.out.println("" + structure); - - switch (header.getDataTypeEnum()) { - case DOUBLE64: - System.out.println(" DOUBLE VALS"); - double doubledata[] = structure.getDoubleData(); - for (double d : doubledata) { - System.out.println(" " + d); - } - break; - - case INT32: case UINT32: - System.out.println(" INT VALS"); - int intdata[] = structure.getIntData(); - for (int i : intdata) { - System.out.println(" " + i); - } - break; - - case CHAR8: case UCHAR8: - System.out.println(" BYTE VALS"); - byte bytedata[] = structure.getByteData(); - for (byte i : bytedata) { - System.out.println(" " + i); - } - break; - } - - } - -}
diff -N Environment.java --- Environment.java 27 Jul 2011 23:19:01 -0000 1.1.1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,203 +0,0 @@
-package org.jlab.coda.jevio; - -import java.net.InetAddress; -import java.net.UnknownHostException; - -/** - * This is a utility class employing a singleton to obtain environment information, such as user name, home directory, - * OS name, etc. - * - * @author heddle - * - */ -public class Environment { - - /** - * Singleton instantiation. - */ - private static Environment environment; - - /** - * User's home directory. - */ - - private String homeDirectory; - - /** - * Current working directory - */ - - private String currentWorkingDirectory; - - /** - * User name - */ - - private String userName; - - /** - * Operating System Name - */ - - private String osName; - - /** - * Temporary Directory - */ - - private String tempDirectory; - - /** - * Class path. - */ - private String classPath; - - /** - * The host name. - */ - private String hostName; - - /** - * Private constructor for the singleton. - */ - private Environment() { - homeDirectory = getProperty("user.home"); - currentWorkingDirectory = getProperty("user.dir"); - userName = getProperty("user.name"); - osName = getProperty("os.name"); - tempDirectory = getProperty("java.io.tmpdir"); - classPath = getProperty("java.class.path"); - - try { - InetAddress addr = InetAddress.getLocalHost(); - - // Get hostname - hostName = addr.getHostName(); - } - catch (UnknownHostException e) { - hostName = "???"; - } - - } - - /** - * Accessor for the singleton. - * - * @return the singleton <code>Environment</code> object. - */ - public static Environment getInstance() { - if (environment == null) { - environment = new Environment(); - } - return environment; - } - - /** - * Convenience routine for getting a system property. - * - * @param keyName the key name of the property - * @return the property, or <code>null</null>. - */ - private String getProperty(String keyName) { - try { - return System.getProperty(keyName); - } - catch (Exception e) { - return null; - } - } - - /** - * Get the current class path. - * - * @return the current class path. - */ - public String getClassPath() { - return classPath; - } - - /** - * Get the current working directory. - * - * @return the current WorkingDirectory. - */ - public String getCurrentWorkingDirectory() { - return currentWorkingDirectory; - } - - /** - * Get the user's home directory. - * - * @return the home directory. - */ - public String getHomeDirectory() { - return homeDirectory; - } - - /** - * Get the operating system name. - * - * @return the operating system name. - */ - public String getOsName() { - return osName; - } - - /** - * Get the temp directory. - * - * @return the temp directory. - */ - public String getTempDirectory() { - return tempDirectory; - } - - /** - * Get the user name. - * - * @return the userName. - */ - public String getUserName() { - return userName; - } - - /** - * Get the host name. - * - * @return the host name. - */ - public String getHostName() { - return hostName; - } - - /** - * Convert to a string for diagnostics - * - * @return The string - */ - - @Override - public String toString() { - StringBuffer sb = new StringBuffer(1024); - sb.append("Environment: \n"); - sb.append("Host Name: " + getHostName() + "\n"); - sb.append("User Name: " + getUserName() + "\n"); - sb.append("Temp Directory: " + getTempDirectory() + "\n"); - sb.append("OS Name: " + getOsName() + "\n"); - sb.append("Home Directory: " + getHomeDirectory() + "\n"); - sb.append("Current Working Directory: " + getCurrentWorkingDirectory() + "\n"); - sb.append("Class Path: " + getClassPath() + "\n"); - return sb.toString(); - } - - /** - * Main program used for testing only. - * - * @param args - */ - public static void main(String[] args) { - Environment env = Environment.getInstance(); - System.out.println(env.toString()); - } - -}
diff -N EventBuilder.java --- EventBuilder.java 27 Jul 2011 23:19:01 -0000 1.1.1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,442 +0,0 @@
-package org.jlab.coda.jevio; - -import java.io.File; - -/** - * This class is used for creating and manipulating events. One constructor is convenient for creating new events while - * another is useful for manipulating existing events. You can create a new EventBuilder for each event being handled, - * However, in many cases one can use the same EventBuilder for all events by calling the setEvent method. - * The only reason a singleton pattern was not used was to allow for the possibility that events will be built or - * manipulated on multiple threads. - * @author heddle - * - */ -public class EventBuilder { - - /** - * The event being built - */ - private EvioEvent event; - - - /** - * This is the constructor to use for an EventBuilder object that will operate on a new, empty event. - * @param tag the tag for the event header (which is just a bank header). - * @param dataType the data type for the event object--which again is just the type for the outer most - * bank. Often an event is a bank of banks, so typically this will be DataType.BANK, or 0xe (14). - * @param num often an ordinal enumeration. - */ - public EventBuilder(int tag, DataType dataType, int num) { - //create an event with the correct header data. - event = new EvioEvent(tag, dataType, num); - } - - /** - * This is the constructor to use when you want to manipulate an existing event. - * @param event the event to manipulate. - */ - public EventBuilder(EvioEvent event) { - this.event = event; - } - - /** - * This goes through the event recursively, and makes sure all the length fields - * in the headers are properly set. - */ - public void setAllHeaderLengths() { - event.setAllHeaderLengths(); - } - - /** - * This clears all the data fields in a structure, but not the parent or the children. This keeps the - * existing tree structure intact. To remove a structure (and, consequently, all its descendants) from the - * tree, use <code>remove</code> - * @param structure the segment to clear. - */ - public void clearData(BaseStructure structure) { - if (structure != null) { - structure.rawBytes = null; - structure.doubleData = null; - structure.floatData = null; - structure.intData = null; - structure.longData = null; - structure.shortData = null; - } - } - - /** - * Add a child to a parent structure. - * - * @param parent the parent structure. - * @param child the child structure. - * @throws EvioException if child is null, has wrong byte order, - * is wrong structure type, or parent is not a container - */ - public void addChild(BaseStructure parent, BaseStructure child) throws EvioException { - - if (child == null) { - throw new EvioException("Attempt to add null child in addChild."); - } - - if (child.getByteOrder() != event.getByteOrder()) { - throw new EvioException("Attempt to add child with opposite byte order."); - } - - // the child must be consistent with the data type of the parent. For example, if the child - //is a BANK, then the data type of the parent but be BANK. - DataType parentDataType = parent.header.getDataTypeEnum(); - String errStr; - if (parentDataType.isStructure()) { - switch(parentDataType) { - case BANK: case ALSOBANK: - if (child.getStructureType() != StructureType.BANK) { - errStr = "Type mismatch in addChild. Parent content type: " + parentDataType + - " child type: " + child.getStructureType(); - throw new EvioException(errStr); - } - break; - - case SEGMENT: case ALSOSEGMENT: - if (child.getStructureType() != StructureType.SEGMENT) { - errStr = "Type mismatch in addChild. Parent content type: " + parentDataType + - " child type: " + child.getStructureType(); - throw new EvioException(errStr); - } - break; - - case TAGSEGMENT: case ALSOTAGSEGMENT: - if (child.getStructureType() != StructureType.TAGSEGMENT) { - errStr = "Type mismatch in addChild. Parent content type: " + parentDataType + - " child type: " + child.getStructureType(); - throw new EvioException(errStr); - } - break; - } - } - else { //parent is not a container--it is expecting to hold primitives and cannot have children - errStr = "Type mismatch in addChild. Parent content type: " + parentDataType + - " cannot have children."; - throw new EvioException(errStr); - } - - - parent.insert(child); - setAllHeaderLengths(); - } - - /** - * This removes a structure (and all its descendants) from the tree. - * @param child the child structure to remove. - * @throws EvioException - */ - public void remove(BaseStructure child) throws EvioException { - if (child == null) { - throw new EvioException("Attempt to remove null child."); - } - - BaseStructure parent = child.getParent(); - - //the only orphan structure is the event itself, which cannot be removed. - if (parent == null) { - throw new EvioException("Attempt to remove root node, i.e., the event. Don't remove an event. Just discard it."); - } - - child.removeFromParent(); - setAllHeaderLengths(); - } - - /** - * Appends int data to the structure. If the structure has no data, then this - * is the same as setting the data. - * @param structure the structure to receive the data, which is appended. - * @param data the int data to append, or set if there is no existing data. - * @throws EvioException - */ - public void appendIntData(BaseStructure structure, int data[]) throws EvioException { - if (structure == null) { - throw new EvioException("Tried to append int data to a null structure."); - } - structure.appendIntData(data); - setAllHeaderLengths(); - } - - /** - * Appends short data to the structure. If the structure has no data, then this - * is the same as setting the data. - * @param structure the structure to receive the data, which is appended. - * @param data the short data to append, or set if there is no existing data. - * @throws EvioException - */ - public void appendShortData(BaseStructure structure, short data[]) throws EvioException { - if (structure == null) { - throw new EvioException("Tried to append short data to a null structure."); - } - structure.appendShortData(data); - setAllHeaderLengths(); - } - - - /** - * Appends long data to the structure. If the structure has no data, then this - * is the same as setting the data. - * @param structure the structure to receive the data, which is appended. - * @param data the long data to append, or set if there is no existing data. - * @throws EvioException - */ - public void appendLongData(BaseStructure structure, long data[]) throws EvioException { - if (structure == null) { - throw new EvioException("Tried to append long data to a null structure."); - } - structure.appendLongData(data); - setAllHeaderLengths(); - } - - /** - * Appends byte data to the structure. If the structure has no data, then this - * is the same as setting the data. - * @param structure the structure to receive the data, which is appended. - * @param data the byte data to append, or set if there is no existing data. - * @throws EvioException - */ - public void appendByteData(BaseStructure structure, byte data[]) throws EvioException { - if (structure == null) { - throw new EvioException("Tried to append byte data to a null structure."); - } - structure.appendByteData(data); - setAllHeaderLengths(); - } - - /** - * Appends float data to the structure. If the structure has no data, then this - * is the same as setting the data. - * @param structure the structure to receive the data, which is appended. - * @param data the float data to append, or set if there is no existing data. - * @throws EvioException - */ - public void appendFloatData(BaseStructure structure, float data[]) throws EvioException { - if (structure == null) { - throw new EvioException("Tried to append float data to a null structure."); - } - structure.appendFloatData(data); - setAllHeaderLengths(); - } - -// /** -// * Appends char data to the structure. If the structure has no data, then this -// * is the same as setting the data. -// * @param structure the structure to receive the data, which is appended. -// * @param data the char data to append, or set if there is no existing data. -// * @throws EvioException -// */ -// public void appendCharData(BaseStructure structure, char data[]) throws EvioException { -// -// if (structure == null) { -// throw new EvioException("Tried to append char data to a null structure."); -// } -// structure.appendCharData(data); -// setAllHeaderLengths(); -// } - - /** - * Appends string data to the structure. If the structure has no data, then this - * is the same as setting the data. - * @param structure the structure to receive the data, which is appended. - * @param data the string to append, or set if there is no existing data. - * @throws EvioException - */ - public void appendStringData(BaseStructure structure, String data) throws EvioException { - - if (structure == null) { - throw new EvioException("Tried to append String to a null structure."); - } - structure.appendStringData(data); - setAllHeaderLengths(); - } - - - /** - * Appends double data to the structure. If the structure has no data, then this - * is the same as setting the data. - * @param structure the structure to receive the data, which is appended. - * @param data the double data to append, or set if there is no existing data. - * @throws EvioException - */ - public void appendDoubleData(BaseStructure structure, double data[]) throws EvioException { - if (structure == null) { - throw new EvioException("Tried to append double data to a null structure."); - } - structure.appendDoubleData(data); - } - - /** - * Get the underlying event. - * @return the underlying event. - */ - public EvioEvent getEvent() { - return event; - } - - /** - * Set the underlying event. As far as this event builder is concerned, the - * previous underlying event is lost, and all subsequent calls will affect - * the newly supplied event. - * param the new underlying event. - */ - public void setEvent(EvioEvent event) { - this.event = event; - } - - /** - * Main program for testing. - * @param args ignored command line arguments. - */ - public static void main(String args[]) { - //create an event writer to write out the test events. - String outfile = "C:\\Documents and Settings\\heddle\\My Documents\\test.ev"; - EventWriter eventWriter = null; - try { - eventWriter = new EventWriter(new File(outfile)); - } - catch (EvioException e) { - e.printStackTrace(); - System.exit(1); - } - - //count the events we make for testing - int eventNumber = 1; - - //use a tag of 11 for events--for no particular reason - int tag = 11; - - try { - //first event-- a trivial event containing an array of ints. - EventBuilder eventBuilder = new EventBuilder(tag, DataType.INT32, eventNumber++); - EvioEvent event1 = eventBuilder.getEvent(); - //should end up with int array 1..25,1..10 - eventBuilder.appendIntData(event1, fakeIntArray(25)); - eventBuilder.appendIntData(event1, fakeIntArray(10)); - eventWriter.writeEvent(event1); - - //second event, more traditional bank of banks - eventBuilder = new EventBuilder(tag, DataType.BANK, eventNumber++); - EvioEvent event2 = eventBuilder.getEvent(); - - //add a bank of doubles - EvioBank bank1 = new EvioBank(22, DataType.DOUBLE64, 0); - eventBuilder.appendDoubleData(bank1, fakeDoubleArray(10)); - eventBuilder.addChild(event2, bank1); - eventWriter.writeEvent(event2); - - //lets modify event2 - event2.getHeader().setNumber(eventNumber++); - EvioBank bank2 = new EvioBank(33, DataType.BANK, 0); - eventBuilder.addChild(event2, bank2); - - EvioBank subBank1 = new EvioBank(34, DataType.SHORT16, 1); - eventBuilder.addChild(bank2, subBank1); - eventBuilder.appendShortData(subBank1, fakeShortArray(5)); - - - - //now add a bank of segments - EvioBank subBank2 = new EvioBank(33, DataType.SEGMENT, 0); - eventBuilder.addChild(bank2, subBank2); - - EvioSegment segment1 = new EvioSegment(34, DataType.SHORT16); - eventBuilder.addChild(subBank2, segment1); - eventBuilder.appendShortData(segment1, fakeShortArray(7)); - - EvioSegment segment2 = new EvioSegment(34, DataType.SHORT16); - eventBuilder.addChild(subBank2, segment2); - eventBuilder.appendShortData(segment2, fakeShortArray(10)); - - - //now add a bank of tag segments - EvioBank subBank3 = new EvioBank(45, DataType.TAGSEGMENT, 0); - eventBuilder.addChild(bank2, subBank3); - - EvioTagSegment tagsegment1 = new EvioTagSegment(34, DataType.INT32); - eventBuilder.addChild(subBank3, tagsegment1); - eventBuilder.appendIntData(tagsegment1, fakeIntArray(3)); - - EvioTagSegment tagsegment2 = new EvioTagSegment(34, DataType.CHARSTAR8); - eventBuilder.addChild(subBank3, tagsegment2); - eventBuilder.appendStringData(tagsegment2, "This is a string"); - - -// System.err.println("EVENT2: " + event2.getHeader()); -// System.err.println("BANK1: " + bank1.getHeader()); -// System.err.println("BANK2: " + bank2.getHeader()); -// System.err.println("SUBBANK1: " + subBank1.getHeader()); -// System.err.println("SUBBANK2: " + subBank2.getHeader()); -// System.err.println("segment1: " + segment1.getHeader()); -// System.err.println("segment2: " + segment2.getHeader()); -// System.err.println("SUBBANK3: " + subBank3.getHeader()); -// System.err.println("tagseg1: " + tagsegment1.getHeader()); - - - //write the event - eventWriter.writeEvent(event2); - - } - catch (EvioException e) { - e.printStackTrace(); - } - - //all done - eventWriter.close(); - - System.out.println("Test completed."); - } - - /** - * Array of ints, sequential, 1..size, for test purposes. - * @param size the size of the array. - * @return the fake int array. - */ - private static int[] fakeIntArray(int size) { - int[] array = new int[size]; - for (int i = 0; i < size; i++) { - array[i] = i+1; - } - return array; - } - - /** - * Array of shorts, sequential, 1..size, for test purposes. - * @param size the size of the array. - * @return the fake short array. - */ - private static short[] fakeShortArray(int size) { - short[] array = new short[size]; - for (int i = 0; i < size; i++) { - array[i] = (short)(i+1); - } - return array; - } - - /** - * Array of characters for test purposes. - * @return the fake char array. - */ - private static char[] fakeCharArray() { - char array[] = {'T','h','i','s',' ','i','s',' ','c','h','a','r',' ', 'd','a','t','a','.'}; - return array; - } - - - - /** - * Array of doubles, sequential, 1..size, for test purposes. - * @param size the size of the array. - * @return the fake double array. - */ - private static double[] fakeDoubleArray(int size) { - double[] array = new double[size]; - for (int i = 0; i < size; i++) { - array[i] = i+1; - } - return array; - } - -}
diff -N EventParser.java --- EventParser.java 27 Jul 2011 23:19:01 -0000 1.1.1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,445 +0,0 @@
-package org.jlab.coda.jevio; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; - -import javax.swing.event.EventListenerList; -import javax.swing.tree.DefaultTreeModel; - -/** - * Uses the singleton pattern to create an object that controls the parsing of events. - * This object, like the EvioFile object, has a method for parsing an event. An EvioFile - * object will ultimately call this method--i.e., the concrete implementation of event - * parsing is in this class. - * - * @author heddle - * - */ -public class EventParser { - - /** - * Listener list for structures (banks, segments, tagsegments) encountered while processing an event. - */ - private EventListenerList evioListenerList; - - /** - * This flag determines whether notification of listeners is active. Normally it is. But in some cases it should be - * temporarily suspended. For example, in a "goto event" process, the listeners will not be notified of the - * intervening events as the file is scanned to get to the target event. - */ - protected boolean notificationActive = true; - - /** - * Singleton parser. - */ - private static EventParser parser = new EventParser(); - - /** - * Returns the singleton <code>EventParser</code> object. - * - * @return the singleton event parser. - */ - public static EventParser getInstance() { - return parser; - } - - /** - * A single global structure filter. This may prove to be a limitation: perhaps we want one per listener. - */ - private IEvioFilter evioFilter; - - /** - * This is the workhorse method for parsing the event. It will drill down and uncover all structures - * (banks, segments, and tagsegments) and notify any interested listeners in a SAX-Like manner. <br> - * Note: applications may choose not to provide a listener. In that case, when the event is parsed, its structures - * may be accessed through the event's tree model, i.e., via <code>event.getTreeModel()</code>. - * - * @param evioEvent the event to parse. - * @throws EvioException - */ - public synchronized void parseEvent(EvioEvent evioEvent) throws EvioException { - - if (evioEvent == null) { - throw new EvioException("Null event in parseEvent."); - } - - //let listeners know we started - notifyStart(evioEvent); - - // The event itself is a stucture (EvioEvent extends EvioBank) so just - // parse it as such. The recursive drill down will take care of the rest. - parseStructure(evioEvent, evioEvent); - - //let listeners know we stopped - notifyStop(evioEvent); - } - - /** - * Parse a structure. If it is a structure of structures, such as a bank of banks or a segment of tag segments, - * parse recursively. Listeners are notified AFTER all their children have been handled, not before. Thus the - * LAST structure that will send notification is the outermost bank--the event bank itself. - * - * @param evioEvent the parent event being processed. - * @param structure the structure being processed. - * @throws EvioException - */ - private void parseStructure(EvioEvent evioEvent, BaseStructure structure) throws EvioException { - - // update the tree - BaseStructure child = structure; - BaseStructure parent = child.getParent(); - - if (parent == null) { // start of event - evioEvent.treeModel = new DefaultTreeModel(evioEvent); - } - else { - evioEvent.insert(child, parent); - } - - // if it is not a structure of structures, we are done. That will leave the raw bytes in - // the "leaf" structures (e.g., a bank of ints) --which will be interpreted by the various get data methods. - DataType dataType = structure.getHeader().getDataTypeEnum(); - if (!dataType.isStructure()) { - // notify the listeners - notifyEvioListeners(evioEvent, structure); - return; - } - - // Does the present structure contain structures? (as opposed to a leaf, which contains primitives). If - // it is a leaf we are done. That will leave the raw bytes in the "leaf" structures (e.g., a bank of ints) - // --which will be interpreted by the various "get data" methods. - if (dataType.isStructure()) { //NOT a leaf - byte bytes[] = structure.getRawBytes(); - ByteOrder byteOrder = structure.getByteOrder(); - - if (bytes == null) { - if (evioEvent == null) { - throw new EvioException("Null data in parseStructure (Bank)."); - } - } - - int length = bytes.length; - int offset = 0; - - switch (dataType) { - case BANK: - case ALSOBANK: - - // extract all the banks from this bank. - while (offset < length) { - BankHeader header = createBankHeader(bytes, offset, byteOrder); - - // offset still points to beginning of new header. Have to get data for new child bank. - int newByteLen = 4 * (header.getLength() - 1); // -1 to account for extra header word - byte newBytes[] = new byte[newByteLen]; - System.arraycopy(bytes, offset + 8, newBytes, 0, newByteLen); - - // we can now create a new bank - EvioBank childBank = new EvioBank(header); - childBank.setParent(structure); - - childBank.setRawBytes(newBytes); - childBank.setByteOrder(byteOrder); - parseStructure(evioEvent, childBank); - - // position offset to start of next header - offset += 4 * (header.getLength() + 1); // plus 1 for length word - } - break; // structure contains banks - - case SEGMENT: - case ALSOSEGMENT: - - // extract all the segments from this bank. - while (offset < length) { - SegmentHeader header = createSegmentHeader(bytes, offset, byteOrder); - - // offset still points to beginning of new header. Have to get data for new child segment. - int newByteLen = 4 * header.getLength(); - byte newBytes[] = new byte[newByteLen]; - System.arraycopy(bytes, offset + 4, newBytes, 0, newByteLen); - - // we can now create a new segment - EvioSegment childSegment = new EvioSegment(header); - childSegment.setParent(structure); - - childSegment.setRawBytes(newBytes); - childSegment.setByteOrder(byteOrder); - parseStructure(evioEvent, childSegment); - - // position offset to start of next header - offset += 4 * (header.getLength() + 1); // plus 1 for length word - } - - break; // structure contains segments - - case TAGSEGMENT: - case ALSOTAGSEGMENT: - - // extract all the tag segments from this bank. - while (offset < length) { - TagSegmentHeader header = createTagSegmentHeader(bytes, offset, byteOrder); - - // offset still points to beginning of new header. Have to get data for new child tag segment. - int newByteLen = 4 * header.getLength(); - byte newBytes[] = new byte[newByteLen]; - System.arraycopy(bytes, offset + 4, newBytes, 0, newByteLen); - - // we can now create a new tag segment - EvioTagSegment childTagSegment = new EvioTagSegment(header); - childTagSegment.setParent(structure); - - childTagSegment.setRawBytes(newBytes); - childTagSegment.setByteOrder(byteOrder); - parseStructure(evioEvent, childTagSegment); - - // position offset to start of next header - offset += 4 * (header.getLength() + 1); // plus 1 for length word - } - - break; - } - } //end not a leaf - // notify the listeners - notifyEvioListeners(evioEvent, structure); - } // parseStructure - - /** - * Create a bank header from the first eight bytes of the data array. - * - * @param bytes the byte array, probably from a bank that encloses this new bank. - * @param offset the offset to start reading from the byte array. - * @param byteOrder byte order of array, {@link ByteOrder#BIG_ENDIAN} or {@link ByteOrder#LITTLE_ENDIAN} - * @return the new header. - */ - private BankHeader createBankHeader(byte bytes[], int offset, ByteOrder byteOrder) { - BankHeader header = new BankHeader(); - ByteBuffer byteBuffer = ByteBuffer.wrap(bytes).order(byteOrder); - byteBuffer.position(offset); - - header.setLength(byteBuffer.getInt()); - - if (byteOrder == ByteOrder.BIG_ENDIAN) { - // interested in bit pattern, not negative numbers - header.setTag(ByteDataTransformer.shortBitsToInt(byteBuffer.getShort())); - header.setDataType(ByteDataTransformer.byteBitsToInt(byteBuffer.get())); - header.setNumber(ByteDataTransformer.byteBitsToInt(byteBuffer.get())); - } - else { - header.setNumber(ByteDataTransformer.byteBitsToInt(byteBuffer.get())); - header.setDataType(ByteDataTransformer.byteBitsToInt(byteBuffer.get())); - header.setTag(ByteDataTransformer.shortBitsToInt(byteBuffer.getShort())); - } - return header; - } - - /** - * Create a segment header from the first four bytes of the data array. - * - * @param bytes the byte array, probably from a bank that encloses this new segment. - * @param offset the offset to start reading from the byte array. - * @param byteOrder byte order of array, {@link ByteOrder#BIG_ENDIAN} or {@link ByteOrder#LITTLE_ENDIAN} - * @return the new header. - */ - private SegmentHeader createSegmentHeader(byte bytes[], int offset, ByteOrder byteOrder) { - SegmentHeader header = new SegmentHeader(); - ByteBuffer byteBuffer = ByteBuffer.wrap(bytes).order(byteOrder); - byteBuffer.position(offset); - - if (byteOrder == ByteOrder.BIG_ENDIAN) { - header.setTag(ByteDataTransformer.byteBitsToInt(byteBuffer.get())); - header.setDataType(ByteDataTransformer.byteBitsToInt(byteBuffer.get())); - header.setLength(ByteDataTransformer.shortBitsToInt(byteBuffer.getShort())); - } - else { - header.setLength(ByteDataTransformer.shortBitsToInt(byteBuffer.getShort())); - header.setDataType(ByteDataTransformer.byteBitsToInt(byteBuffer.get())); - header.setTag(ByteDataTransformer.byteBitsToInt(byteBuffer.get())); - } - - return header; - } - - /** - * Create a tag segment header from the first four bytes of the data array. - * - * @param bytes the byte array, probably from a bank that encloses this new tag segment. - * @param offset the offset to start reading from the byte array. - * @param byteOrder byte order of array, {@link ByteOrder#BIG_ENDIAN} or {@link ByteOrder#LITTLE_ENDIAN} - * @return the new header. - */ - private TagSegmentHeader createTagSegmentHeader(byte bytes[], int offset, ByteOrder byteOrder) { - TagSegmentHeader header = new TagSegmentHeader(); - ByteBuffer byteBuffer = ByteBuffer.wrap(bytes).order(byteOrder); - byteBuffer.position(offset); - - int temp; - - if (byteOrder == ByteOrder.BIG_ENDIAN) { - temp = ByteDataTransformer.shortBitsToInt(byteBuffer.getShort()); - header.setTag(temp >>> 4); - header.setDataType(temp & 0xF); - header.setLength(ByteDataTransformer.shortBitsToInt(byteBuffer.getShort())); - } - else { - header.setLength(ByteDataTransformer.shortBitsToInt(byteBuffer.getShort())); - temp = ByteDataTransformer.shortBitsToInt(byteBuffer.getShort()); - header.setTag(temp >>> 4); - header.setDataType(temp & 0xF); - } - - return header; - } - - /** - * This is when a structure is encountered while parsing an event. It notifies all listeners about the structure. - * - * @param structure the structure encountered, which may be a Bank, Segment, or TagSegment. - */ - protected void notifyEvioListeners(EvioEvent evioEvent, IEvioStructure structure) { - - // are notifications turned off? - if (!notificationActive) { - return; - } - - if (evioListenerList == null) { - return; - } - - // if there is a global filter, lets use it. - if (evioFilter != null) { - if (!evioFilter.accept(structure.getStructureType(), structure.getHeader())) { - return; - } - } - - // Guaranteed to return a non-null array - Object[] listeners = evioListenerList.getListenerList(); - - // This weird loop is the bullet proof way of notifying all listeners. - for (int i = listeners.length - 2; i >= 0; i -= 2) { - if (listeners[i] == IEvioListener.class) { - ((IEvioListener) listeners[i + 1]).gotStructure(evioEvent, structure); - } - } - } - - /** - * Notify listeners we are starting to parse a new event - * @param evioEvent the event in question; - */ - protected void notifyStart(EvioEvent evioEvent) { - - // are notifications turned off? - if (!notificationActive) { - return; - } - - if (evioListenerList == null) { - return; - } - - // Guaranteed to return a non-null array - Object[] listeners = evioListenerList.getListenerList(); - - // This weird loop is the bullet proof way of notifying all listeners. - for (int i = listeners.length - 2; i >= 0; i -= 2) { - if (listeners[i] == IEvioListener.class) { - ((IEvioListener) listeners[i + 1]).startEventParse(evioEvent); - } - } - } - - /** - * Notify listeners we are done to parsing a new event - * @param evioEvent the event in question; - */ - protected void notifyStop(EvioEvent evioEvent) { - - // are notifications turned off? - if (!notificationActive) { - return; - } - - if (evioListenerList == null) { - return; - } - - // Guaranteed to return a non-null array - Object[] listeners = evioListenerList.getListenerList(); - - // This weird loop is the bullet proof way of notifying all listeners. - for (int i = listeners.length - 2; i >= 0; i -= 2) { - if (listeners[i] == IEvioListener.class) { - ((IEvioListener) listeners[i + 1]).endEventParse(evioEvent); - } - } - } - - /** - * Remove an Evio listener. Evio listeners listen for structures encountered when an event is being parsed. - * - * @param listener The Evio listener to remove. - */ - public void removeEvioListener(IEvioListener listener) { - - if ((listener == null) || (evioListenerList == null)) { - return; - } - - evioListenerList.remove(IEvioListener.class, listener); - } - - /** - * Add an Evio listener. Evio listeners listen for structures encountered when an event is being parsed. - * - * @param listener The Evio listener to add. - */ - public void addEvioListener(IEvioListener listener) { - - if (listener == null) { - return; - } - - if (evioListenerList == null) { - evioListenerList = new EventListenerList(); - } - - evioListenerList.add(IEvioListener.class, listener); - } - - /** - * Get the flag determining whether notification of listeners is active. Normally it is. But in some cases it should - * be temporarily suspended. For example, in a "goto event" process, the listeners will not be notified of the - * intervening events as the file is scanned to get to the target event. - * - * @return <code>true</code> if notification of events to the listeners is active. - */ - public boolean isNotificationActive() { - return notificationActive; - } - - /** - * Set the flag determining whether notification of listeners is active. Normally it is. But in some cases it - * should be temporarily suspended. For example, in a "goto event" process, the listeners will not be notified of - * the intervening events as the file is scanned to get to the target event. - * - * @param notificationActive set <code>true</code> if notification of events to the listeners is active. - */ - public void setNotificationActive(boolean notificationActive) { - this.notificationActive = notificationActive; - } - - /** - * Set the global filter used for filtering structures. If set to <code>null</code>, the default, then all - * structures will be sent to the listeners. - * - * @param evioFilter the filter to set. - * @see IEvioFilter - */ - public void setEvioFilter(IEvioFilter evioFilter) { - this.evioFilter = evioFilter; - } - -}
diff -N EventWriter.java --- EventWriter.java 27 Jul 2011 23:19:01 -0000 1.1.1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,368 +0,0 @@
-package org.jlab.coda.jevio; - -import java.io.DataOutputStream; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; - -/** - * An EventWriter object is used for writing events to a file in evio versions 2 and 3. - * @author heddle - * - */ -public class EventWriter { - - /** - * Offset to where the block length is written in the byte buffer, which always has a physical - * record header at the top. - */ - private static int BLOCK_LENGTH_OFFSET = 0; - - /** - * Offset to where the header length is written in the byte buffer, which always has a physical - * record header at the top. - */ - private static int HEADER_LENGTH_OFFSET = 8; - - /** - * Offset to where the start is written in the byte buffer, which always has a physical - * record header at the top. The start is the offset to the start of the first event that - * starts in a block. - */ - private static int START_OFFSET = 12; - - /** - * Offset to where the end is written in the byte buffer, which always has a physical - * record header at the top. The end is the number of valid words (header + data) and will - * be the same as the blocksize for all blocks but the last. - */ - private static int END_OFFSET = 16; - - /** - * Offset to where the version number is written in the byte buffer, which always has a physical - * record header at the top. - */ - private static int VERSION_OFFSET = 20; - - /** - * Offset to where reserved 1 is written in the byte buffer, which always has a physical - * record header at the top. - */ - private static int RESERVED1_OFFSET = 24; - - /** - * The default size used for writing a file, in ints. Max allowed: 32768. Must be a multiple of 256. - */ - private static int DEFAULT_BLOCK_SIZE = 8192; - - /** - * The output stream used for writing a file - */ - private DataOutputStream dataOutputStream; - - /** - * Block size for anachronistic physical record (block headers). A typical number is 8192. - * Must be a multiple of 256 with a max value of 32768. - */ - private int blockSize; - - /** - * This is an internal byte buffer corresponding to one block (physical record). When this gets full it - * will be flushed to the external output stream (<code>dataOutputStream</code>) that represents the file. - */ - private ByteBuffer blockBuffer; - - /** - * Checks for first event started in current buffer. - */ - private boolean updatedStart; - - /** - * Running count of the block number. - */ - private int blockNumber = 0; - - /** - * We are going to use reserved1 in the block header to hold the ordinal count - * of the last event completed in the current block.<br> - */ - private int lastEventWritten = 0; - - - /** - * Creates an event writer for writing to a file. - * @param file the file to write to. Will be created.<br> - * WARNING: If the file already exists, an attempt will be made to delete it. Appending - * to an existing event file is not supported. - * @throws EvioException - */ - public EventWriter(File file) throws EvioException { - this(file, DEFAULT_BLOCK_SIZE); - } - - /** - * Creates an event writer for writing to a file. - * @param filename name of the file to write to. Will be created.<br> - * WARNING: If the file already exists, an attempt will be made to delete it. Appending - * to an existing event file is not supported. - * @throws EvioException - */ - public EventWriter(String filename) throws EvioException { - this(new File(filename), DEFAULT_BLOCK_SIZE); - } - - /** - * Create an <code>EventWriter</code> for writing events to a file. - * @param file the file to write to. Will be created.<br> - * WARNING: If the file already exists, an attempt will be made to delete it. Appending - * to an existing event file is not supported. - * @param blockSize the blocksize to use. A typical number is 8192. Must be a multiple of 256 with a - * max value of 32768. - * @throws EvioException - */ - public EventWriter(File file, int blockSize) throws EvioException { - this.blockSize = blockSize; - - try { - dataOutputStream = new DataOutputStream(new FileOutputStream(file)); - } - catch (FileNotFoundException e) { - throw new EvioException(e.getMessage()); - } - } - - /** - * Create an <code>EventWriter</code> for writing events to a file. - * @param file the file to write to. Will be created.<br> - * WARNING: If the file already exists, an attempt will be made to delete it. Appending - * to an existing event file is not supported. - * @param blockSize the blocksize to use. A typical number is 8192. Must be a multiple of 256 with a - * max value of 32768. - * @param okToDelete if <code>true</code> and the file already exists, an attempt will be made to delete the existing file. - * Appending to an existing event file is not supported at this time. - */ - public EventWriter(File file, int blockSize, boolean okToDelete) throws EvioException { - this.blockSize = blockSize; - - if (file == null) { - throw new EvioException("Null file in EventWriter constructor"); - } - - // handle existing file - if (file.exists() && file.isFile()) { - if (okToDelete) { - boolean deleted = file.delete(); - if (!deleted) { - throw new EvioException("File in EventWriter constructor already exists, and could not be deleted. \n" + - "File: " + file.getPath()); - } - } - else { // user requested no delete - throw new EvioException("File in EventWriter constructor already exists, and user requested no deletion. \n" + - "File: " + file.getPath()); - } - } - - - try { - dataOutputStream = new DataOutputStream(new FileOutputStream(file)); - } - catch (FileNotFoundException e) { - throw new EvioException("Fow whatever reason, the file could not be opened. \n " + - "It could mean there is no permission to open the file for writing \n" + - "or that the file was a directory." + - "File: " + file.getPath()); - } - } - - - /** - * Get a clean buffer. This is called at the start and also after every physical record - * is flushed to the file. - */ - private void getCleanBuffer() { - if (blockBuffer == null) { - blockBuffer = ByteBuffer.allocate(4*blockSize); // apparently this buffer is backed by array - blockBuffer.order(ByteOrder.nativeOrder()); - } - else { - blockBuffer.clear(); - } - - updatedStart = false; - - //write header words, some of which will be overwritten later when the values are determined, - blockBuffer.putInt(blockSize); - blockBuffer.putInt(blockNumber++); - blockBuffer.putInt(8); // header size always 8 - blockBuffer.putInt(0); // start will be updated - blockBuffer.putInt(blockSize); // end is usually blocksize - blockBuffer.putInt(2); // version is 2 or 3 (same format so just pick 2) - blockBuffer.putInt(0); // reserved1 will be updated - blockBuffer.putInt(BlockHeader.MAGIC_NUMBER); // should be MAGIC_NUMBER - } - - - /** - * Close the underlying data output stream, and with it the file. - */ - public void close() { - try { - // write final bytes, if there are any to be written - int position = blockBuffer.position(); - - if (position > 0) { - dataOutputStream.write(blockBuffer.array()); - } - - // finish writing file - dataOutputStream.close(); - } - catch (IOException e) { - e.printStackTrace(); - } - } - - - /** - * Write a bank to the file in evio version 2, 3 format. - * - * @param bank the bank to write. - * @throws EvioException - */ - public void writeEvent(EvioBank bank) throws EvioException { - if (bank == null) { - throw new EvioException("Attempt to write null event using EventWriter"); - } - - // if first event is being written, create buffer - if (blockBuffer == null) { - getCleanBuffer(); - } - - //TODO call event.setComputedLength to make sure all headers have correct length? - int bytelen = bank.getTotalBytes(); - ByteBuffer eventBuffer = ByteBuffer.allocate(bytelen); - eventBuffer.order(ByteOrder.nativeOrder()); - - bank.write(eventBuffer); - - // is the first event started in this buffer? If not, this is the first event that starts in this - // block and we have to modify the start field accordingly - if (!updatedStart) { - updateStart(blockBuffer.position() / 4); - updatedStart = true; - } - - // update the reserved1 field because another event is starting in this physical record (block) - updateReserved1(++lastEventWritten); - - // reset to top of event buffer - eventBuffer.position(0); - - // the big question is: is there or is there not enough space in the block buffer to finish - // writing the event? If not we write as much as possible, flush, and repeat until we do - // have enough space to finish writing the event. - while (eventBuffer.remaining() > blockBuffer.remaining()) { - updateEnd(blockSize); - // finish filling current block buffer - int remaining = blockBuffer.remaining(); - for (int i = 0; i < remaining; i++) { - blockBuffer.put(eventBuffer.get()); - } - - //byte buffer is now full. Flush and reset - try { - dataOutputStream.write(blockBuffer.array()); - getCleanBuffer(); - } - catch (IOException e) { - e.printStackTrace(); - } - } - // now we DO have enough space for remaining, if there is any more to write. - if (eventBuffer.remaining() > 0) { - // we are completing an event - blockBuffer.put(eventBuffer.array(), eventBuffer.position(), eventBuffer.remaining()); - updateEnd(blockBuffer.position() / 4); - } - } - - /** - * Update the block length field in the header using an absolute put. - * @param length the new value for block length. - */ - private void updateBlockLength(int length) { - blockBuffer.putInt(BLOCK_LENGTH_OFFSET, length); - } - - /** - * Update the start field in the header using an absolute put. - * @param start the new value for start. - */ - private void updateStart(int start) { - blockBuffer.putInt(START_OFFSET, start); - } - - /** - * Update the end field in the header using an absolute put. - * @param end the new value for end. - */ - private void updateEnd(int end) { - blockBuffer.putInt(END_OFFSET, end); - } - - /** - * Update the reserved1 field in the header using an absolute put. - * @param reserved1 the new value for reserved1. - */ - private void updateReserved1(int reserved1) { - blockBuffer.putInt(RESERVED1_OFFSET, reserved1); - } - - - /** - * Main program for testing. - * - * @param args ignored command line arguments. - */ - public static void main(String args[]) { -// String infile = "C:\\Documents and Settings\\heddle\\My Documents\\out.ev"; -// String outfile = "C:\\Documents and Settings\\heddle\\My Documents\\out_copy.ev"; - String infile = "../../testdata/out.ev"; - String outfile = "../../testdata/out_copy.ev"; - int count = 0; - - try { - //an EvioFile object is used for reading - EvioFile inFile = new EvioFile(new File(infile)); - //an EvioWriter object is used for writing - EventWriter eventWriter = new EventWriter(new File(outfile)); - //EventWriter eventWriter = new EventWriter(new File(outfile), 8192, true); - - EvioEvent event; - while ((event = inFile.parseNextEvent()) != null) { -// System.out.println("EVENT LEN: " + event.getHeader().getLength()); - eventWriter.writeEvent(event); - count++; - } - - eventWriter.close(); - } - catch (EvioException e) { - e.printStackTrace(); - } - catch (IOException e) { - e.printStackTrace(); - } - System.out.println("copied: " + count + " events."); - - //compare the two files - EvioFile.compareEventFiles(new File(infile), new File(outfile)); - } - - -}
diff -N EvioBank.java --- EvioBank.java 27 Jul 2011 23:19:01 -0000 1.1.1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,147 +0,0 @@
-package org.jlab.coda.jevio; - -import javax.xml.stream.XMLStreamException; -import javax.xml.stream.XMLStreamWriter; - -/** - * This holds a CODA Bank structure. Mostly it has a header (a <code>BankHeader</code>) and the raw data stored as an - * byte array. - * - * @author heddle - * - */ -public class EvioBank extends BaseStructure { - - /** - * The XML record tag for a segment. - */ - public static final String ELEMENT_NAME = "bank"; - - /** For general convenience, allow an object to be attached to an evio bank. */ - transient protected Object attachment; - - - /** - * Null constructor for a bank. - */ - public EvioBank() { - super(new BankHeader()); - } - - /** - * Constructor using a provided BankHeader - * - * @param bankHeader the header to use. - * @see BankHeader - */ - public EvioBank(BankHeader bankHeader) { - super(bankHeader); - } - - /** - * This is the general constructor to use for a Bank. - * @param tag the tag for the bank header. - * @param dataType the (enum) data type for the content of the bank. - * @param num sometimes, but not necessarily, an ordinal enumeration. - */ - public EvioBank(int tag, DataType dataType, int num) { - this(new BankHeader(tag, dataType, num)); - } - - /** - * This is the general constructor to use for a Bank. - * @param tag the tag for the bank header. - * @param dataType the (int) data type for the content of the bank. - * @param num sometimes, but not necessarily, an ordinal enumeration. - */ - public EvioBank(int tag, int dataType, int num) { - this(new BankHeader(tag, dataType, num)); - } - - /** - * Get the attached object. - * @return the attached object - */ - public Object getAttachment() { - return attachment; - } - - /** - * Set the attached object. - * @param attachment object to attach to this bank - */ - public void setAttachment(Object attachment) { - this.attachment = attachment; - } - - /** - * This implements the abstract method from <code>BaseStructure</code>. It is a convenience method use instead of - * "instanceof" to see what type of structure we have. Note: this returns the type of this structure, not the type - * of data this structure holds. - * - * @return the <code>StructureType</code> of this structure, which is a StructureType.BANK. - * @see StructureType - */ - @Override - public StructureType getStructureType() { - return StructureType.BANK; - } - - /** - * Write this bank structure out as an XML record. - * @param xmlWriter the writer used to write the events. - */ - @Override - public void toXML(XMLStreamWriter xmlWriter) { - - try { - commonXMLStart(xmlWriter); - if (DataType.getDataType(header.dataType).isStructure()) { - xmlWriter.writeAttribute("content", xmlContentAttributeName); - } - xmlWriter.writeAttribute("data_type", String.format("0x%x", header.dataType)); - xmlWriter.writeAttribute("tag", "" + header.tag); - xmlWriter.writeAttribute("num", "" + header.number); - xmlWriter.writeAttribute("length", "" + header.length); - xmlWriter.writeAttribute("ndata", "" + getNumberDataItems()); - increaseXmlIndent(); - commonXMLDataWrite(xmlWriter); - decreaseXmlIndent(); - commonXMLClose(xmlWriter); - } - catch (XMLStreamException e) { - e.printStackTrace(); - } - } - - /** - * Get the element name for the bank for writing to XML. - * @return the element name for the structure for writing to XML. - */ - @Override - public String getXMLElementName() { - return ELEMENT_NAME; - } - - /** - * Write myself out as a byte array of evio format data - * in the byte order given by {@link #getByteOrder}. - * This method is much more efficient than using {@link #write(java.nio.ByteBuffer)}. - * - * @return byte array containing evio format data of this bank in currently set byte order - */ - public byte[] toArray() { - - byte[] bArray = new byte[rawBytes.length + header.getHeaderLength()*4]; - - // write the header - header.toArray(bArray, 0, byteOrder); - - // write the rest - System.arraycopy(rawBytes, 0, bArray, header.getHeaderLength()*4, rawBytes.length); - - return bArray; - } - - -}
diff -N EvioDictionaryEntry.java --- EvioDictionaryEntry.java 27 Jul 2011 23:19:01 -0000 1.1.1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,200 +0,0 @@
-package org.jlab.coda.jevio; - -import java.util.StringTokenizer; - -/** - * An entry into the evio dictionary. - * - * @author heddle - * - */ -public class EvioDictionaryEntry implements Comparable<EvioDictionaryEntry> { - - /** - * The tag will have to match the tag field in a segment. - */ - private int tag; - - /** - * The result of the number field being tokenized, with "." serving as the delimiter. These are tokens. - */ - private int numbers[]; - - /** - * The nice name for this dictionary entry--the description. - */ - private String description; - - /** - * Constructor. - * - * @param tag the string tag, will be converted into an int. - * @param num the string num field, which might be <code>null</code>, and which will be tokenized (for possible - * ancestor matching) and converted into an array of ints. - * @param description the nice name for this dictionary entry--the description. - */ - public EvioDictionaryEntry(String tag, String num, String description) { - this.description = description; - - // the tag field should clean--no hierarchy - this.tag = Integer.parseInt(tag); - - // The <code>num</code> value is a string, rather than an int, because it might represent - // a bank hierarchy. For example, a number of "2.3.1" means that a bank matches this - // entry if a) its num field in the header is 1, and b) its parent's num field is 3, and - // c) it's grandparent's num field is 2. - if (num != null) { - String tokens[] = tokens(num, "."); - - numbers = new int[tokens.length]; - // flip the order so numbers[0] is primary match. - int j = 0; - for (int i = tokens.length - 1; i >= 0; i--) { - numbers[j] = Integer.parseInt(tokens[i]); - j++; - } - } - } - - /** - * Checks if a structure matches this dictionary entry. This is more complicated than at first glance, because a - * matching of not just the structure but also (for banks) the num fields of its immediate ancestors might be - * required. - * - * @param structure the structure to test. - * @return <code>true</code> if the structure matches. - */ - public boolean match(BaseStructure structure) { - - if (structure instanceof EvioEvent) { - if ((numbers == null) || (numbers.length != 1)) { - return false; - } - BaseStructureHeader header = structure.header; - return (tag == header.tag) && (numbers[0] == header.number); - } - else if (structure instanceof EvioBank) { - if (structure.header.tag != tag) { - return false; - } - - if (numbers == null) { - return false; - } - - for (int i = 0; i < numbers.length; i++) { - BaseStructureHeader header = structure.header; - if (numbers[i] != header.number) { - return false; - } - - structure = structure.getParent(); - if (structure == null) { - // Once we've reached the top event, - // parent = null, but match is good. timmer 9/30/2010 - if (i >= numbers.length-1) { - return true; - } - return false; - } - if (structure instanceof EvioSegment) { - return false; - } - if (structure instanceof EvioTagSegment) { - return false; - } - } - return true; - } - else { - BaseStructureHeader header = structure.header; - return (tag == header.tag); - } - } - - /** - * We sort so that the entries with the most number of ancestors match. - * - * @param entry the object to compare against. - */ - @Override - public int compareTo(EvioDictionaryEntry entry) { - if (entry.numbers == null) return -1; - if (numbers == null) return 1; - - // we want the entrys with the longer ancestor trail up top - if (numbers.length > entry.numbers.length) { - return -1; - } - if (numbers.length < entry.numbers.length) { - return 1; - } - // same number of tokens - for (int i = 0; i < numbers.length; i++) { - if (numbers[i] < entry.numbers[i]) { - return -1; - } - if (numbers[i] > entry.numbers[i]) { - return 1; - } - } - - return 0; - } - - /** - * This method breaks a string into an array of tokens. - * - * @param str the string to decompose. - * @param token the token character. - * @return an array of tokens. - */ - private String[] tokens(String str, String token) { - StringTokenizer t = new StringTokenizer(str, token); - int num = t.countTokens(); - String tokens[] = new String[num]; - - for (int i = 0; i < num; i++) { - tokens[i] = t.nextToken(); - } - - return tokens; - } - - /** - * Get the nice, hopefully descriptive name for this entry. - * - * @return the nice, hopefully descriptive name for this entry. - */ - public String getDescription() { - return description; - } - - /** - * Get a string representation of this entry. - * - * @return a string representation of this entry. - */ - @Override - public String toString() { - String ns = null; - if (numbers != null) { - for (int i = numbers.length - 1; i >= 0; i--) { - if (ns == null) { - ns = ""; - } - ns += numbers[i]; - if (i != 0) { - ns += "."; - } - } - } - if (ns == null) { - return String.format("tag: %-4d description: %s", tag, description); - } - else { - return String.format("tag: %-4d num: %-10s description: %s", tag, ns, description); - } - } - -}
diff -N EvioEvent.java --- EvioEvent.java 27 Jul 2011 23:19:01 -0000 1.1.1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,248 +0,0 @@
-package org.jlab.coda.jevio; - -import java.util.List; -import java.util.Vector; - -import javax.swing.tree.DefaultTreeModel; -import javax.xml.stream.XMLStreamException; -import javax.xml.stream.XMLStreamWriter; - -/** - * An event is really just the outer, primary bank. That is, the first structure in an event (aka logical record, aka - * buffer) must be a bank, probably a bank of banks. - * - * The Event trivially extends bank, just so there can be a distinct <code>EvioEvent</code> class, for clarity. - * - * @author heddle - * - */ -public class EvioEvent extends EvioBank { - - /** - * The XML record tag for an event. - */ - public static final String ELEMENT_NAME = "event"; - - /** - * As the event is parsed, it is parsed into a tree. - */ - protected DefaultTreeModel treeModel; - - /** - * This is not the "num" field from the header, but rather a number [1..] indicating - * which event this was in the event file from which it was read. - */ - private int eventNumber; - - - /** - * Explicit null constructor for evio event. - */ - public EvioEvent() { - } - - /** - * Constructor using a provided BankHeader. - * - * @param bankHeader the header to use. - * @see BankHeader - */ - public EvioEvent(BankHeader bankHeader) { - super(bankHeader); - } - - /** - * This is a general constructor to use for an EvioEvent. - * - * @param tag the tag for the event header (which is just a bank header). - * @param dataType the (enum) data type for the content of the bank. - * @param num sometimes, but not necessarily, an ordinal enumeration. - */ - public EvioEvent(int tag, DataType dataType, int num) { - this(new BankHeader(tag, dataType, num)); - } - - /** - * This is a general constructor to use for an EvioEvent. - * - * @param tag the tag for the event header (which is just a bank header). - * @param dataType the (int) data type for the content of the bank. - * @param num sometimes, but not necessarily, an ordinal enumeration. - */ - public EvioEvent(int tag, int dataType, int num) { - this(new BankHeader(tag, dataType, num)); - } - - /** - * Create a string representation of the event. - * @return a string representation of the event. - */ - @Override - public String toString() { - - String description = getDescription(); - if (NameProvider.NO_NAME_STRING.equals(description)) { - description = null; - } - - String s = "<Event> " + " len (ints): " + header.length + " " + " tag: " + header.tag + " num: " + header.number; - if (description != null) { - s += " [" + description + "]"; - } - return s; - } - - /** - * Get the tree model representing this event. This would have been generated - * as the event was being parsed. - * @return the tree model representing this event. - */ - public DefaultTreeModel getTreeModel() { - return treeModel; - } - - /** - * Inserts a child structure into the event's JTree. This is called when the event is being parsed, - * and when an event is being created. - * @param child the child structure being added to the tree. - * @param parent the parent structure of the new child. - */ - public void insert(BaseStructure child, BaseStructure parent) { - treeModel.insertNodeInto(child, parent, parent.getChildCount()); - } - - /** - * Visit all the structures in this event (including the event itself--which is considered its own descendant). - * This is similar to listening to the event as it is being parsed, but is done to a complete (already) parsed event. - * @param listener an listener to notify as each structure is visited. - */ - public void vistAllStructures(IEvioListener listener) { - visitAllDescendants(this, listener, null); - } - - /** - * Visit all the structures in this event (including the event itself--which is considered its own descendant) in a depth first manner. - * @param listener an listener to notify as each structure is visited. - * @param filter an optional filter that must "accept" structures before they are passed to the listener. If <code>null</code>, all - * structures are passed. In this way, specific types of structures can be captured. - */ - public void vistAllStructures(IEvioListener listener, IEvioFilter filter) { - visitAllDescendants(this, listener, filter); - } - - /** - * Visit all the descendants of a given structure (which is considered a descendant of itself.) - * - * @param structure the starting structure. - * @param listener an listener to notify as each structure is visited. - * @param filter an optional filter that must "accept" structures before they are passed to the listener. If - * <code>null</code>, all structures are passed. In this way, specific types of structures can be - * captured. - */ - private void visitAllDescendants(BaseStructure structure, IEvioListener listener, IEvioFilter filter) { - - if (listener != null) { - boolean accept = true; - if (filter != null) { - accept = filter.accept(structure.getStructureType(), structure.header); - } - - if (accept) { - listener.gotStructure(this, structure); - } - } - - if (!(structure.isLeaf())) { - for (BaseStructure child : structure.getChildren()) { - visitAllDescendants(child, listener, filter); - } - } - } - - /** - * Visit all the descendant structures, and collect those that pass a filter. - * @param filter the filter that must be passed. If <code>null</code>, this will return all the structures. - * @return a collection of all structures that are accepted by a filter. - */ - public List<BaseStructure> getMatchingStructures(IEvioFilter filter) { - final Vector<BaseStructure> structures = new Vector<BaseStructure>(25, 10); - - IEvioListener listener = new IEvioListener() { - @Override - public void startEventParse(EvioEvent evioEvent) { } - - @Override - public void endEventParse(EvioEvent evioEvent) { } - - @Override - public void gotStructure(EvioEvent evioEvent, IEvioStructure structure) { - structures.add((BaseStructure)structure); - } - - }; - - vistAllStructures(listener, filter); - - if (structures.size() == 0) { - return null; - } - return structures; - } - - /** - * This returns a number [1..] indicating which event this was in the event file from which - * it was read. It is not the "num" field from the header. - * @return a number [1..] indicating which event this was in the event file from which - * it was read. - */ - public int getEventNumber() { - return eventNumber; - } - - /** - * This sets a number [1..] indicating which event this was in the event file from which - * it was read. It is not the "num" field from the header. - * @param eventNumber a number [1..] indicating which event this was in the event file from which - * it was read. - */ - public void setEventNumber(int eventNumber) { - this.eventNumber = eventNumber; - } - - /** - * Write this event structure out as an XML record. - * @param xmlWriter the writer used to write the events. - */ - @Override - public void toXML(XMLStreamWriter xmlWriter) { - - try { - int totalLen = header.length + 1; - xmlWriter.writeComment(" Buffer " + getEventNumber() + " contains " + totalLen + " words (" + 4*totalLen + " bytes)"); - commonXMLStart(xmlWriter); - xmlWriter.writeAttribute("format", "evio"); - xmlWriter.writeAttribute("count", "" + getEventNumber()); - if (DataType.getDataType(header.dataType).isStructure()) { - xmlWriter.writeAttribute("content", xmlContentAttributeName); - } - xmlWriter.writeAttribute("data_type", String.format("0x%x", header.dataType)); - xmlWriter.writeAttribute("length", "" + header.length); - xmlWriter.writeAttribute("tag", "" + header.tag); - xmlWriter.writeAttribute("num", "" + header.number); - commonXMLClose(xmlWriter); - } - catch (XMLStreamException e) { - e.printStackTrace(); - } - } - - /** - * Get the element name for the bank for writing to XML. - * @return the element name for the structure for writing to XML. - */ - @Override - public String getXMLElementName() { - return ELEMENT_NAME; - } - -}
diff -N EvioException.java --- EvioException.java 27 Jul 2011 23:19:01 -0000 1.1.1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,43 +0,0 @@
-package org.jlab.coda.jevio; - -/** - * This is a general exception used to indicate a problem in the Jevio package. - * - * @author heddle - * - */ -@SuppressWarnings("serial") -public class EvioException extends Exception { - - /** - * Create an EVIO Exception indicating an error specific to the EVIO system. - * {@inheritDoc}<p/> - * - * @param message {@inheritDoc}<p/> - */ - public EvioException(String message) { - super(message); - } - - /** - * Create an EVIO Exception with the specified message and cause. - * {@inheritDoc}<p/> - * - * @param message {@inheritDoc}<p/> - * @param cause {@inheritDoc}<p/> - */ - public EvioException(String message, Throwable cause) { - super(message, cause); - } - - /** - * Create an EVIO Exception with the specified cause. - * {@inheritDoc}<p/> - * - * @param cause {@inheritDoc}<p/> - */ - public EvioException(Throwable cause) { - super(cause); - } - -}
diff -N EvioFile.java --- EvioFile.java 27 Jul 2011 23:19:01 -0000 1.1.1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,1203 +0,0 @@
-package org.jlab.coda.jevio; - -import java.io.*; -import java.nio.*; -import java.nio.channels.FileChannel; - -import javax.xml.stream.FactoryConfigurationError; -import javax.xml.stream.XMLOutputFactory; -import javax.xml.stream.XMLStreamException; -import javax.xml.stream.XMLStreamWriter; - -/** - * This is the a class of interest to the user. Create an <code>EvioFile</code> from a <code>File</code> - * object corresponding to an event file, and from this class you can test the file for consistency and, - * more importantly, you can call <code>parseNextEvent</code> to get new events and to stream the embedded - * structures to an IEvioListener. - * - * The streaming effect of parsing an event is that the parser will read the event and hand off structures, - * such as banks, to any IEvioListeners. For those familiar with XML, the event is processed SAX-like. - * It is up to the listener to decide what to do with the structures. - * <p> - * As an alternative to stream processing, after an event is parsed, the user can use the events treeModel - * for access to the structures. For those familiar with XML, the event is processed DOM-like. - * <p> - * NOTE: Even though this class has a constructor that accepts an i/o mode, that is for backwards - * compatibility only. An <code>EvioFile</code> is used for reading and parsing events only. - * To write an event file, use an <code>EventWriter</code> object. - * - * @author heddle - * - */ -public class EvioFile { - - /** - * This <code>enum</code> denotes the status of a read. <br> - * SUCCESS indicates a successful read. <br> - * END_OF_FILE indicates that we cannot read because an END_OF_FILE has occurred. Technically this means that what - * ever we are trying to read is larger than the buffer's unread bytes.<br> - * EVIO_EXCEPTION indicates that an EvioException was thrown during a read, possibly due to out of range values, - * such as a negative start position.<br> - * UNKNOWN_ERROR indicates that an unrecoverable error has occurred. - */ - public static enum ReadStatus { - SUCCESS, END_OF_FILE, EVIO_EXCEPTION, UNKNOWN_ERROR - } - - /** - * This <code>enum</code> denotes the status of a write.<br> - * SUCCESS indicates a successful write. <br> - * CANNOT_OPEN_FILE indicates that we cannot write because the destination file cannot be opened.<br> - * EVIO_EXCEPTION indicates that an EvioException was thrown during a write.<br> - * UNKNOWN_ERROR indicates that an unrecoverable error has occurred. - */ - public static enum WriteStatus { - SUCCESS, CANNOT_OPEN_FILE, EVIO_EXCEPTION, UNKNOWN_ERROR - } - - /** - * Offset to get magic number from start of file. - */ - private static final int MAGIC_OFFSET = 28; - - /** - * The buffer representing a map of the input file. - */ - private MappedByteBuffer mappedByteBuffer; - - /** - * Endianness of the data, either {@link ByteOrder#BIG_ENDIAN} or {@link ByteOrder#LITTLE_ENDIAN}. - */ - private ByteOrder byteOrder; - - /** - * The current block header. - */ - private BlockHeader blockHeader = new BlockHeader(); - - /** - * Root element tag for XML file - */ - private static final String ROOT_ELEMENT = "evio-data"; - - /** - * Used to assign a transient number [1..n] to events as they are - */ - private int eventNumber = 0; - - /** - * This is the number of events in the file. It is not computed unless asked for, and if asked for it is computed - * and cached in this variable. - */ - private int eventCount = -1; - - /** - * Absolute path of the underlying file. - */ - private String path; - - - /** - * Creates an event file for reading. - * - * @param file the file that contains EVIO events. - * @throws IOException - */ - public EvioFile(File file) throws IOException { - FileInputStream fileInputStream = new FileInputStream(file); - path = new String(file.getAbsolutePath()); - FileChannel inputChannel = fileInputStream.getChannel(); - mapFile(inputChannel); - inputChannel.close(); // this object is no longer needed - // set buffer to beginning - mappedByteBuffer.position(0); - } - - /** - * Creates an event file. - * - * @param path the full path to the file that contains events. - * For writing event files, use an <code>EventWriter</code> object. - * @see EventWriter - * @throws IOException - */ - public EvioFile(String path) throws IOException { - this(new File(path)); - } - - /** - * Get the path to the file. - * @return path to the file - */ - public String getPath() { - return path; - } - - /** - * Get the number of events remaining in the file. - * - * @return number of events remaining in the file - * @throws EvioException if failed reading from coda v3 file - */ - public int getNumEventsRemaining() throws EvioException { - return getEventCount() - eventNumber; - } - - /** - * Maps the file into memory. The data are not actually loaded in memory-- subsequent reads will read - * random-access-like from the file. - * - * @param inputChannel the input channel. - */ - private synchronized void mapFile(FileChannel inputChannel) throws IOException { - long sz = inputChannel.size(); -//System.out.println("mapFile: size = " + sz); - mappedByteBuffer = inputChannel.map(FileChannel.MapMode.READ_ONLY, 0L, sz); - } - - /** - * Obtain the file size using the memory mapped buffer's capacity, which should be the same. - * - * @return the file size in bytes--actually the mapped memory size. - */ - public int fileSize() { - return mappedByteBuffer.capacity(); - } - - /** - * Get the memory mapped buffer corresponding to the event file. - * - * @return the memory mapped buffer corresponding to the event file. - */ - public MappedByteBuffer getMappedByteBuffer() { - return mappedByteBuffer; - } - - /** - * Reads the block (physical record) header. Assumes the mapped buffer is positioned - * at the start of the next block header (physical record.)<br> - * - * A Bank header is 8, 32-bit ints. The first int is the size of the block in ints - * (not counting the length itself, i.e., the number of ints to follow). - * - * Most users should have no need for this method, since most applications do care about the block - * (physical record) header. - */ - protected synchronized ReadStatus nextBlockHeader() { - // have enough remaining? - if (mappedByteBuffer.remaining() < 32) { - mappedByteBuffer.clear(); - return ReadStatus.END_OF_FILE; - } - - // set the byte order to match the file's ordering - try { - // Check the magic number for endianness. This requires - // peeking ahead 7 ints or 24 bytes. Set the endianness - // once we figure out what it is (buffer defaults to big endian). - byteOrder = mappedByteBuffer.order(); - int magicNumber = mappedByteBuffer.getInt(MAGIC_OFFSET); -//System.out.println("nextBlockHeader: actual magic number = " + Integer.toHexString(BlockHeader.MAGIC_NUMBER)); -//System.out.println("nextBlockHeader: read magic number as " + Integer.toHexString(magicNumber)); - - if (magicNumber != BlockHeader.MAGIC_NUMBER) { - // Originally checked ByteOrder.nativeOrder() which is NOT what you want - timmer - if (byteOrder == ByteOrder.BIG_ENDIAN) { - byteOrder = ByteOrder.LITTLE_ENDIAN; -//System.out.println("nextBlockHeader: reset byte order to " + ByteOrder.LITTLE_ENDIAN); - } - else { - byteOrder = ByteOrder.BIG_ENDIAN; -//System.out.println("nextBlockHeader: reset byte order to " + ByteOrder.BIG_ENDIAN); - } - mappedByteBuffer.order(byteOrder); - } - else { -//System.out.println("nextBlockHeader: byte order = " + byteOrder); - } - - try { - // cache the starting position - blockHeader.setBufferStartingPosition(mappedByteBuffer.position()); - - // Now read the header data. It's a little trickier now that there are - // several versions to be concerned about. Read all quantities into - // temp variables, set the version FIRST, then set the other quantities last - // as they may depend on the version number. - int[] header = new int[8]; - for (int i=0; i<8; i++) { - header[i] = mappedByteBuffer.getInt(); - } - - int version = header[5] & 0xff; - if (version != 2 && version != 3) { - // we got the wrong evio version here, throw an exception - throw new EvioException("Reading file of unsupported evio version (" + version + ")"); - } - - blockHeader.setVersion(version); - blockHeader.setSize(header[0]); - blockHeader.setNumber(header[1]); - blockHeader.setHeaderLength(header[2]); - blockHeader.setStart(header[3]); - blockHeader.setEnd(header[4]); - blockHeader.setReserved1(header[6]); // also event count in verson 4 - blockHeader.setMagicNumber(header[7]); - } - catch (EvioException e) { - e.printStackTrace(); - return ReadStatus.EVIO_EXCEPTION; - } - } - catch (BufferUnderflowException a) { -System.err.println("ERROR endOfBuffer " + a); - mappedByteBuffer.clear(); - return ReadStatus.UNKNOWN_ERROR; - } - - return ReadStatus.SUCCESS; - } - - - /** - * Get the next event in the file. As useful as this sounds, most applications will probably call - * {@link #parseNextEvent() parseNextEvent} instead, since it combines combines getting the next - * event with parsing the next event.<p> - * - * @return the next event in the file. On error it throws an EvioException. On end of file, it returns - * <code>null</code>. - * @throws EvioException - */ - public synchronized EvioEvent nextEvent() throws EvioException { - EvioEvent event = new EvioEvent(); - BaseStructureHeader header = event.getHeader(); - - // Are we at the top of the file? - if (mappedByteBuffer.position() == 0) { - ReadStatus status = nextBlockHeader(); - if (status != ReadStatus.SUCCESS) { - throw new EvioException("Failed reading block header in nextEvent."); - } -//System.out.println("nextEvent: BLOCK HEADER :\n" + blockHeader.toString()); - } - - // How many bytes remain in this block? - // Must see if we have to deal with crossing physical record boundaries. - int bytesRemaining = blockBytesRemaining(); - if (bytesRemaining < 0) { - throw new EvioException("Number of block bytes remaining is negative."); - } - - // Are we exactly at the end of the block (physical record)? - if (bytesRemaining == 0) { - ReadStatus status = nextBlockHeader(); - if (status == ReadStatus.SUCCESS) { -//System.out.println("nextEvent: BLOCK HEADER:\n" + blockHeader.toString()); - return nextEvent(); - } - else if (status == ReadStatus.END_OF_FILE) { - return null; - } - else { - throw new EvioException("Failed reading block header in nextEvent."); - } - } - // Or have we already read in the last event? - else if (blockHeader.getBufferEndingPosition() == mappedByteBuffer.position()) { - return null; - } - - // No matter what, we can get the length of the next event. - // A non positive length indicates eof; - int length = mappedByteBuffer.getInt(); - if (length < 1) { - return null; - } - - header.setLength(length); - bytesRemaining -= 4; // just read in 4 bytes - - // If we were unlucky, after reading the length there are no bytes remaining in this bank. - if (bytesRemaining == 0) { - ReadStatus status = nextBlockHeader(); - if (status == ReadStatus.END_OF_FILE) { - return null; - } - else if (status != ReadStatus.SUCCESS) { - throw new EvioException("Failed reading block header in nextEvent."); - } - bytesRemaining = blockBytesRemaining(); - } - - // Now should be good to go, except data may cross block boundary - // in any case, should be able to read the rest of the header. - if (byteOrder == ByteOrder.BIG_ENDIAN) { - // interested in bit pattern, not negative numbers - header.setTag(ByteDataTransformer.shortBitsToInt(mappedByteBuffer.getShort())); - header.setDataType(ByteDataTransformer.byteBitsToInt(mappedByteBuffer.get())); - header.setNumber(ByteDataTransformer.byteBitsToInt(mappedByteBuffer.get())); - } - else { - header.setNumber(ByteDataTransformer.byteBitsToInt(mappedByteBuffer.get())); - header.setDataType(ByteDataTransformer.byteBitsToInt(mappedByteBuffer.get())); - header.setTag(ByteDataTransformer.shortBitsToInt(mappedByteBuffer.getShort())); - } - bytesRemaining -= 4; // just read in 4 bytes - - // get the raw data - int eventDataSizeInts = header.getLength() - 1; - int eventDataSizeBytes = 4 * eventDataSizeInts; - - try { - byte bytes[] = new byte[eventDataSizeBytes]; - - int bytesToGo = eventDataSizeBytes; - int offset = 0; - - // be in while loop if have to cross block boundary[ies]. - while (bytesToGo > bytesRemaining) { - mappedByteBuffer.get(bytes, offset, bytesRemaining); - - ReadStatus status = nextBlockHeader(); - if (status == ReadStatus.END_OF_FILE) { - return null; - } - else if (status != ReadStatus.SUCCESS) { - throw new EvioException("Failed reading block header after crossing boundary in nextEvent."); - } -//System.out.println("nextEvent: BLOCK HEADER:\n" + blockHeader.toString()); - bytesToGo -= bytesRemaining; - offset += bytesRemaining; - bytesRemaining = blockBytesRemaining(); - } - - // last (perhaps only) read. - mappedByteBuffer.get(bytes, offset, bytesToGo); - event.setRawBytes(bytes); - event.setByteOrder(byteOrder); // add this to track endianness, timmer - event.setEventNumber(++eventNumber); - return event; - } - catch (OutOfMemoryError ome) { - System.err.println("Out Of Memory\n" + - "eventDataSizeBytes = " + eventDataSizeBytes + "\n" + - "bytes Remaining = " + bytesRemaining + "\n" + - "event Count: " + eventCount); - return null; - } - catch (Exception e) { - return null; - } - } - - /** - * This is the workhorse method. It retrieves the next event from the file, and then parses is SAX-like. It will - * drill down and uncover all structures (banks, segments, and tagsegments) and notify any interested listeners. - * - * @return the event that was parsed. On error it throws an EvioException. On end of file, it returns - * <code>null</code>. - * @throws EvioException - */ - public synchronized EvioEvent parseNextEvent() throws EvioException { - EvioEvent event = nextEvent(); - if (event != null) { - parseEvent(event); - } - return event; - } - - /** - * This will parse an event, SAX-like. It will drill down and uncover all structures (banks, segments, and - * tagsegments) and notify any interested listeners. - * - * As useful as this sounds, most applications will probably call {@link #parseNextEvent() parseNextEvent} instead, - * since it combines combines getting the next event with parsing the next event . - * - * @param evioEvent the event to parse. - * @throws EvioException - */ - public synchronized void parseEvent(EvioEvent evioEvent) throws EvioException { - EventParser.getInstance().parseEvent(evioEvent); - } - - /** - * Get the number of bytes remaining in the current block (physical record). This is used for pathology checks like - * crossing the block boundary. - * - * @return the number of bytes remaining in the current block (physical record). - */ - private int blockBytesRemaining() { - try { - return blockHeader.bytesRemaining(mappedByteBuffer.position()); - } - catch (EvioException e) { - e.printStackTrace(); - return -1; - } - } - - /** - * The equivalent of rewinding the file. What it actually does is set the position of the mapped memory buffer back - * to 0. This method, along with the two <code>position</code> and the <code>close</code> method, allows - * applications to treat this in a normal random access file manner. - */ - public void rewind() { - mappedByteBuffer.position(0); - eventNumber = 0; - } - - /** - * This is equivalent to obtaining the current position in the file. What it actually does is return the position of - * the mapped memory buffer. This method, along with the <code>rewind</code>, <code>position(int)</code> and the - * <code>close</code> method, allows applications to treat this in a normal random access file manner. - * - * @return the position of the file. - */ - public int position() { - return mappedByteBuffer.position(); - } - - /** - * This is equivalent to setting the current position in the file. What it actually does is set the position of the - * mapped memory buffer. This method, along with the <code>rewind</code>, <code>position()</code> and the - * <code>close</code> method, allows applications to treat this in a normal random access file manner. - * - * @param position the new position of the file. - */ - public void position(int position) { - mappedByteBuffer.position(position); - } - - /** - * This is equivalent to closing the file. What it actually does is clear all data from the mapped memory buffer, - * and sets its position to 0. This method, along with the <code>rewind</code> and the two <code>position()</code> - * methods, allows applications to treat this in a normal random access file manner. - */ - public void close() { - mappedByteBuffer.clear(); - } - - /** - * This returns the current (active) block (physical record) header. Since most users have no interest in physical - * records, this method should not be used often. Mostly it is used by the test programs in the - * <code>EvioFileTest</code> class. - * - * @return the current block header. - */ - public BlockHeader getCurrentBlockHeader() { - return blockHeader; - } - - /** - * Go to a specific event in the file. The events are numbered 1..N. This number is transient--it is not part of the - * event as stored in the evio file. - * - * @param evNumber the event number in a 1..N counting sense, from the start of the file. - */ - public EvioEvent gotoEventNumber(int evNumber) { - - if (evNumber < 1) { - return null; - } - - // rewind - rewind(); - EvioEvent event; - - try { - // get the first evNumber - 1 events without parsing - for (int i = 1; i < evNumber; i++) { - event = nextEvent(); - if (event == null) { - throw new EvioException("Asked to go to event: " + evNumber + ", which is beyond the end of file"); - } - } - // get one more event, the evNumber'th event, with parsing - return parseNextEvent(); - } - catch (EvioException e) { - e.printStackTrace(); - } - return null; - } - - /** - * Rewrite the entire file to XML. - * - * @param path the path to the XML file. - * @return the status of the write. - */ - public WriteStatus toXMLFile(String path) { - return toXMLFile(path, null); - } - - /** - * Rewrite the entire file to XML. - * - * @param path the path to the XML file. - * @param progressListener and optional progress listener, can be <code>null</code>. - * @return the status of the write. - * @see IEvioProgressListener - */ - public WriteStatus toXMLFile(String path, IEvioProgressListener progressListener) { - FileOutputStream fos; - - try { - fos = new FileOutputStream(path); - } - catch (FileNotFoundException e) { - e.printStackTrace(); - return WriteStatus.CANNOT_OPEN_FILE; - } - - XMLStreamWriter xmlWriter = null; - try { - xmlWriter = XMLOutputFactory.newInstance().createXMLStreamWriter(fos); - xmlWriter.writeStartDocument(); - xmlWriter.writeCharacters("\n"); - xmlWriter.writeComment("Event source file: " + path); - - // start the root element - xmlWriter.writeCharacters("\n"); - xmlWriter.writeStartElement(ROOT_ELEMENT); - xmlWriter.writeAttribute("numevents", "" + getEventCount()); - - // now loop through the events - // rewind - rewind(); - EvioEvent event; - try { - while ((event = parseNextEvent()) != null) { - event.toXML(xmlWriter); - // anybody interested in progress? - if (progressListener != null) { - progressListener.completed(event.getEventNumber(), getEventCount()); - } - } - } - catch (EvioException e) { - e.printStackTrace(); - return WriteStatus.UNKNOWN_ERROR; - } - - // done. Close root element, end the document, and flush. - xmlWriter.writeCharacters("\n"); - xmlWriter.writeEndElement(); - xmlWriter.writeEndDocument(); - xmlWriter.flush(); - xmlWriter.close(); - - try { - fos.close(); - } - catch (IOException e) { - e.printStackTrace(); - } - } - catch (XMLStreamException e) { - e.printStackTrace(); - return WriteStatus.UNKNOWN_ERROR; - } - catch (FactoryConfigurationError e) { - return WriteStatus.UNKNOWN_ERROR; - } - catch (EvioException e) { - return WriteStatus.EVIO_EXCEPTION; - } - - // TODO something better than just rewind again? - rewind(); - System.out.println("XML write was successful"); - return WriteStatus.SUCCESS; - } - - /** - * This is the number of events in the file. It is not computed unless asked for, and if asked for it is computed - * and cached. - * - * @return the number of events in the file. - * @throws EvioException - */ - public int getEventCount() throws EvioException { - - if (eventCount < 0) { - rewind(); - eventCount = 0; - - while ((nextEvent()) != null) { - eventCount++; - } - - rewind(); - } - - return eventCount; - } - - /** - * Method used for diagnostics. It compares two event files. It checks the following (in order):<br> - * <ol> - * <li> That neither file is null. - * <li> That both files exist. - * <li> That neither file is a directory. - * <li> That both files can be read. - * <li> That both files are the same size. - * <li> That both files contain the same number of events. - * <li> Finally, that they are the same in a byte-by-byte comparison. - * </ol> - * NOTE: Two files with the same events but different physical record size will be reported as different. They will fail the same size test. - * @return <code>true</code> if the files are, byte-by-byte, identical. - */ - public static boolean compareEventFiles(File evFile1, File evFile2) { - - if ((evFile1 == null) || (evFile2 == null)) { - System.out.println("In compareEventFiles, one or both files are null."); - return false; - } - - if (!evFile1.exists() || !evFile2.exists()) { - System.out.println("In compareEventFiles, one or both files do not exist."); - return false; - } - - if (evFile1.isDirectory() || evFile2.isDirectory()) { - System.out.println("In compareEventFiles, one or both files is a directory."); - return false; - } - - if (!evFile1.canRead() || !evFile2.canRead()) { - System.out.println("In compareEventFiles, one or both files cannot be read."); - return false; - } - - String name1 = evFile1.getName(); - String name2 = evFile2.getName(); - - long size1 = evFile1.length(); - long size2 = evFile2.length(); - - if (size1 == size2) { - System.out.println(name1 + " and " + name2 + " have the same length: " + size1); - } - else { - System.out.println(name1 + " and " + name2 + " have the different lengths."); - System.out.println(name1 + ": " + size1); - System.out.println(name2 + ": " + size2); - return false; - } - - try { - EvioFile evioFile1 = new EvioFile(evFile1); - EvioFile evioFile2 = new EvioFile(evFile2); - int evCount1 = evioFile1.getEventCount(); - int evCount2 = evioFile2.getEventCount(); - if (evCount1 == evCount2) { - System.out.println(name1 + " and " + name2 + " have the same #events: " + evCount1); - } - else { - System.out.println(name1 + " and " + name2 + " have the different #events."); - System.out.println(name1 + ": " + evCount1); - System.out.println(name2 + ": " + evCount2); - return false; - } - } - catch (EvioException e) { - e.printStackTrace(); - return false; - } - catch (IOException e) { - e.printStackTrace(); - return false; - } - - - System.out.print("Byte by byte comparison..."); - System.out.flush(); - - int onetenth = (int)(1 + size1/10); - - //now a byte-by-byte comparison - try { - FileInputStream fis1 = new FileInputStream(evFile1); - FileInputStream fis2 = new FileInputStream(evFile1); - - for (int i = 0; i < size1; i++) { - try { - int byte1 = fis1.read(); - int byte2 = fis2.read(); - - if (byte1 != byte2) { - System.out.println(name1 + " and " + name2 + " different at byte offset: " + i); - return false; - } - - if ((i % onetenth) == 0) { - System.out.print("."); - System.out.flush(); - } - } - catch (IOException e) { - e.printStackTrace(); - return false; - } - } - - System.out.println(""); - - try { - fis1.close(); - fis2.close(); - } - catch (IOException e) { - e.printStackTrace(); - } - } - catch (FileNotFoundException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - - System.out.println("files " + name1 + " and " + evFile2.getPath() + " are identical."); - return true; - } - - - /** - * Array of ints, sequential, 1..size, for test purposes. - * @param size the size of the array. - * @return the fake int array. - */ - private static int[] fakeIntArray(int size) { - int[] array = new int[size]; - for (int i = 0; i < size; i++) { - array[i] = 0x040302010; - } - return array; - } - - /** For testing only */ - public static void main(String args[]) { -// //create an event writer to write out the test events. - String fileName = "../../testdata/littleOut.ev"; -// EventWriter eventWriter = null; -// File file = new File(fileName); -// -// //count the events we make for testing -// int eventNumber = 1; -// -// //use a tag of 11 for events--for no particular reason -// int tag = 11; -// -// try { -// eventWriter = new EventWriter(file); -// //first event-- a trivial event containing an array of ints. -// EventBuilder eventBuilder = new EventBuilder(tag, DataType.INT32, eventNumber++); -// EvioEvent event1 = eventBuilder.getEvent(); -// //should end up with int array 1..25,1..10 -// eventBuilder.appendIntData(event1, fakeIntArray(10)); -// eventWriter.writeEvent(event1); -// } -// catch (EvioException e) { -// e.printStackTrace(); -// } -// -// // all done writing -// eventWriter.close(); - - -// byte[] b = new byte[9]; -// b[0] = 67; -// b[1] = 79; -// b[2] = 0; -// b[3] = 68; -// b[4] = 65; -// b[5] = 28; -// b[6] = 29; -// b[7] = 30; -// b[8] = 31; -// -// try { -// String s = new String(b, "US-ASCII"); -// System.out.println("My string = " + s + ", length of string = " + s.length()); -// -// byte[] bs = s.getBytes("US-ASCII"); -// for (byte bb : bs){ -// System.out.println("b = " + bb); -// } -// -// if (s.equals("CODA")) { -// System.out.println("CO0DA = CODA"); -// } -// else { -// System.out.println("CO0DA != CODA"); -// } -// -// StringBuffer stringData = new StringBuffer(s); -// System.out.println("Buffer size = " + stringData.length()); -// -// } -// catch (UnsupportedEncodingException e) { -// e.printStackTrace(); -// } -// System.exit(0); - - // Write Big Endian file (11 ints -> 8 block header ints, 2 bank header ints, 1 data int) - ByteBuffer buf = ByteBuffer.allocate(4*8192); - - // block header is first - buf.putInt(8192); // full block size - buf.putInt(1); // block number - buf.putInt(8); // header length - buf.putInt(8); // start of next event - buf.putInt(60); // end of last event - buf.putInt(2); // version number - buf.putInt(0); // reserved - buf.putInt(0xc0da0100); // magic number - - //------------------------------ - // From here on we have an event - //------------------------------ - - // bank of banks next - buf.putInt(51); // bank length - //use a tag of 11 for events--for no particular reason - int tag = 11; - int num = 3; - int type = 0x10 /* bank of banks */; - buf.putInt( (num & 0xff) | ((type << 8) & 0xff00) | (tag << 16) ); // second bank header word - - // bank of banks next - buf.putInt(18); // bank length - tag = 20; - num = 2; - type = 0x10 /* bank of banks */; - buf.putInt( (num & 0xff) | ((type << 8) & 0xff00) | (tag << 16) ); // second bank header word - - // bank of ints next - buf.putInt(16); // bank length - tag = 21; - num = 1; - type = 0xb /* bank of int32s */; - buf.putInt( (num & 0xff) | ((type << 8) & 0xff00) | (tag << 16) ); // second bank header word - buf.putInt(0x1); - buf.putInt(0x2); - buf.putInt(0x3); - buf.putInt(0x4); - buf.putInt(0x5); - - buf.putInt(0x10); - buf.putInt(0x20); - buf.putInt(0x30); - buf.putInt(0x40); - buf.putInt(0x50); - - buf.putInt(0x100); - buf.putInt(0x200); - buf.putInt(0x300); - buf.putInt(0x400); - buf.putInt(0x500); - - //------------------------ - - // bank of segments next - buf.putInt(3); // bank length - tag = 22; - num = 2; - type = 0xd /* bank of segments */; - buf.putInt( (num & 0xff) | ((type << 8) & 0xff00) | (tag << 16) ); // second bank header word - - // segment of ints next - int len = 1; // seg length - tag = 23; - type = 0xb /* segment of ints */; - buf.putInt( (len & 0xffff) | ((type << 16) & 0xff0000) | (tag << 24) ); // segment header word - buf.putInt(0x06050403); - - //------------------------ - - // bank of tagsegments next - buf.putInt(3); // bank length - tag = 24; - num = 2; - type = 0xc /* bank of tagsegments */; - buf.putInt( (num & 0xff) | ((type << 8) & 0xff00) | (tag << 16) ); // second bank header word - - // segment of ints next - len = 1; // tagseg length - tag = 25; - type = 0xb /* tagsegment of ints */; - buf.putInt( len & 0xffff | ((type << 16) & 0xf0000) | (tag << 20) ); // segment header word - buf.putInt(0x07060504); - - - // bank of ints next - buf.putInt(2); // bank length - tag = 12; - num = 2; - type = 0x1 /* bank of uint32s */; - buf.putInt( (num & 0xff) | ((type << 8) & 0xff00) | (tag << 16) ); // second bank header word - buf.putInt(0x04030201); - - // bank of shorts next - buf.putInt(4); // bank length - tag = 13; - num = 2; - type = 0x4 /* bank of shorts */; - buf.putInt( (num & 0xff) | ((type << 8) & 0xff00) | (tag << 16) ); // second bank header word - buf.putShort((short)0x0403); - buf.putShort((short)0x0201); - buf.putShort((short)0x0001); - buf.putShort((short)0x0002); - buf.putShort((short)0x0003); - buf.putShort((short)0x0004); - - // bank of longs next - buf.putInt(3); // bank length - tag = 14; - num = 2; - type = 0x9 /* bank of longs */; - buf.putInt( (num & 0xff) | ((type << 8) & 0xff00) | (tag << 16) ); // second bank header word - buf.putLong(0x1234123412341234L); - - // bank of floats next - buf.putInt(2); // bank length - tag = 15; - num = 2; - type = 0x2 /* bank of floats */; - buf.putInt( (num & 0xff) | ((type << 8) & 0xff00) | (tag << 16) ); // second bank header word - buf.putFloat(1.23e-4F); - - // bank of doubles next - buf.putInt(3); // bank length - //use a tag of 11 for events--for no particular reason - tag = 16; - num = 2; - type = 0x8 /* bank of doubles */; - buf.putInt( (num & 0xff) | ((type << 8) & 0xff00) | (tag << 16) ); // second bank header word - buf.putDouble(-5.6789e-300); - - // bank of strings - buf.putInt(3); // bank length - //use a tag of 11 for events--for no particular reason - tag = 17; - num = 2; - type = 0x3 /* bank of strings */; - buf.putInt( (num & 0xff) | ((type << 8) & 0xff00) | (tag << 16) ); // second bank header word - byte[] b = new byte[8]; - b[0] = 67; - b[1] = 79; - b[2] = 68; - b[3] = 65; - b[4] = 51; - b[5] = 15; - buf.put(b); - - // now, write this into a file[truncated at 1000 lines; 207 more skipped]
diff -N EvioFileTest.java --- EvioFileTest.java 27 Jul 2011 23:19:01 -0000 1.1.1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,160 +0,0 @@
-package org.jlab.coda.jevio; - -import org.jlab.coda.jevio.EvioFile.ReadStatus; - -/** - * A set of static functions that test evio files. It also has some other diagnostic methods for getting counts. - * - * @author heddle - * - */ -public class EvioFileTest { - - /** - * This enum is used for file testing. <br> - * PASS indicates that a given test passed. <br> - * FAIL indicates that a given test failed. - */ - public static enum TestResult { - PASS, FAIL - } - - /** - * Get a total count of the number of physical records. - * - * @param evioFile the file to be processed. - * @return the total count of blocks (physical records.) - */ - public static int totalBlockCount(EvioFile evioFile) { - evioFile.rewind(); - ReadStatus status = ReadStatus.SUCCESS; - int count = 0; - - while (status == ReadStatus.SUCCESS) { - status = evioFile.nextBlockHeader(); - if (status == ReadStatus.SUCCESS) { - evioFile.position(evioFile.getCurrentBlockHeader().nextBufferStartingPosition()); - count++; - } - } - - System.out.println("total block count: " + count); - - evioFile.rewind(); - return count; - } // totalBlockCount - - /** - * Tests whether we can look through the file and find all the block headers. - * - * @param evioFile the file to be tested. - * @return the result of this test, either PASS or FAIL. - */ - public static TestResult readAllBlockHeadersTest(EvioFile evioFile) { - evioFile.rewind(); - ReadStatus status = ReadStatus.SUCCESS; - int blockCount = 0; - - while (status == ReadStatus.SUCCESS) { - status = evioFile.nextBlockHeader(); - if (status == ReadStatus.SUCCESS) { - evioFile.position(evioFile.getCurrentBlockHeader().nextBufferStartingPosition()); - blockCount++; - } - } - - TestResult result; - - // should have read to the end of the file - if (status == ReadStatus.END_OF_FILE) { - System.out.println("Total blocks read: " + blockCount); - result = TestResult.PASS; - } - else { - result = TestResult.FAIL; - } - - System.out.println("readAllBlockHeadersTest: " + result); - - evioFile.rewind(); - return result; - } // readAllBlockHeadersTest - - /** - * Tests whether we can look through the file read all the events. - * - * @param evioFile the file to be tested. - * @return the result of this test, either <code>TestResult.PASS</code> or <code>TestResult.FAIL</code>. - */ - public static TestResult readAllEventsTest(EvioFile evioFile) { - // store current file position - int oldPosition = evioFile.position(); - - evioFile.rewind(); - EvioEvent event; - int count = 0; - TestResult result = TestResult.PASS; - - try { - while ((event = evioFile.nextEvent()) != null) { - count++; - BaseStructureHeader header = event.getHeader(); - - System.out.println(count + ") size: " + header.getLength() + " type: " + header.getDataTypeName() - + " \"" + event.getDescription() + "\""); - } - } - catch (EvioException e) { - e.printStackTrace(); - result = TestResult.FAIL; - } - - System.out.println("readAllBlockHeadersTest: " + result); - - // restore file position - evioFile.position(oldPosition); - return result; - } // readAllEventsTest - - /** - * Tests whether we can parse events from the file. - * - * @param evioFile the file to be tested. - * @param num the number to parse. Will try to parse this many (unless it runs out.) Use -1 to parse all events. - * Note: if <code>num</code> is greater than the number of events in the file, it doesn't constitute an - * error. - * @return the result of this test, either <code>TestResult.PASS</code> or <code>TestResult.FAIL</code>. - */ - public static TestResult parseEventsTest(EvioFile evioFile, int num) { - // store current file position - int oldPosition = evioFile.position(); - - if (num < 0) { - num = Integer.MAX_VALUE; - } - - evioFile.rewind(); - EvioEvent event; - int count = 0; - TestResult result = TestResult.PASS; - - try { - while ((count < num) && ((event = evioFile.nextEvent()) != null)) { - evioFile.parseEvent(event); - count++; - } - } - catch (EvioException e) { - e.printStackTrace(); - result = TestResult.FAIL; - } - - System.out.println("parseEventsTest parsed: " + count + " events"); - System.out.println("parseEventsTest result: " + result); - - // restore file position - evioFile.position(oldPosition); - return result; - } // readAllEventsTest - -}
diff -N EvioSegment.java --- EvioSegment.java 27 Jul 2011 23:19:01 -0000 1.1.1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,105 +0,0 @@
-package org.jlab.coda.jevio; - -import javax.xml.stream.XMLStreamWriter; -import javax.xml.stream.XMLStreamException; - -/** - * This holds a CODA Segment structure. Mostly it has a header (a <code>SegementHeader</code>) and the raw data stored as an - * byte array. - * - * @author heddle - * - */ -public class EvioSegment extends BaseStructure { - - /** - * The XML record tag for a segment. - */ - public static final String ELEMENT_NAME = "segment"; - - /** - * Null constructor creates an empty SegmentHeader. - * - * @see SegmentHeader - */ - public EvioSegment() { - this(new SegmentHeader()); - } - - /** - * Constructor using a provided SegmentHeader - * - * @param segmentHeader the header to use. - * @see SegmentHeader - */ - public EvioSegment(SegmentHeader segmentHeader) { - super(segmentHeader); - } - - /** - * This is the general constructor to use for a Segment. - * @param tag the tag for the segment header. - * @param dataType the (enum) data type for the content of the segment. - */ - public EvioSegment(int tag, DataType dataType) { - this(new SegmentHeader(tag, dataType)); - } - - /** - * This is the general constructor to use for a Segment. - * @param tag the tag for the segment header. - * @param dataType the (int) data type for the content of the segment. - */ - public EvioSegment(int tag, int dataType) { - this(new SegmentHeader(tag, dataType)); - } - - /** - * This implements the abstract method from <code>BaseStructure</code>. It is a convenience method use instead of - * "instanceof" to see what type of structure we have. Note: this returns the type of this structure, not the type - * of data this structure holds. - * - * @return the <code>StructureType</code> of this structure, which is a StructureType.SEGMENT. - * @see StructureType - */ - @Override - public StructureType getStructureType() { - return StructureType.SEGMENT; - } - - /** - * Write this segment structure out as an XML record. - * @param xmlWriter the writer used to write the events. - */ - @Override - public void toXML(XMLStreamWriter xmlWriter) { - - try { - commonXMLStart(xmlWriter); - if (DataType.getDataType(header.dataType).isStructure()) { - xmlWriter.writeAttribute("content", xmlContentAttributeName); - } - xmlWriter.writeAttribute("data_type", String.format("0x%x", header.dataType)); - xmlWriter.writeAttribute("tag", "" + header.tag); - xmlWriter.writeAttribute("length", "" + header.length); - xmlWriter.writeAttribute("ndata", "" + getNumberDataItems()); - increaseXmlIndent(); - commonXMLDataWrite(xmlWriter); - decreaseXmlIndent(); - commonXMLClose(xmlWriter); - } - catch (XMLStreamException e) { - e.printStackTrace(); - } - } - - /** - * Get the element name for the bank for writing to XML. - * @return the element name for the structure for writing to XML. - */ - @Override - public String getXMLElementName() { - return ELEMENT_NAME; - } - -}
diff -N EvioTagSegment.java --- EvioTagSegment.java 27 Jul 2011 23:19:01 -0000 1.1.1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,106 +0,0 @@
-package org.jlab.coda.jevio; - -import javax.xml.stream.XMLStreamWriter; -import javax.xml.stream.XMLStreamException; - -/** - * This holds a CODA TagSegment structure. Mostly it has a header (a <code>TagSegementHeader</code>) and the raw data stored as an - * byte array. - * - * @author heddle - * - */ -public class EvioTagSegment extends BaseStructure { - - /** - * The XML record tag for a tag segment. - */ - public static final String ELEMENT_NAME = "tagsegment"; - - - /** - * Null constructor creates an empty TagSegmentHeader. - * - * @see TagSegmentHeader - */ - public EvioTagSegment() { - this(new TagSegmentHeader()); - } - - /** - * Constructor using a provided TagSegmentHeader - * - * @param tagSegmentHeader the header to use. - * @see TagSegmentHeader - */ - public EvioTagSegment(TagSegmentHeader tagSegmentHeader) { - super(tagSegmentHeader); - } - - /** - * This is the general constructor to use for a TagSegment. - * @param tag the tag for the tag segment header. - * @param dataType the (enum) data type for the content of the tag segment. - */ - public EvioTagSegment(int tag, DataType dataType) { - this(new TagSegmentHeader(tag, dataType)); - } - - /** - * This is the general constructor to use for a TagSegment. - * @param tag the tag for the tag segment header. - * @param dataType the (int) data type for the content of the tag segment. - */ - public EvioTagSegment(int tag, int dataType) { - this(new TagSegmentHeader(tag, dataType)); - } - - /** - * This implements the abstract method from <code>BaseStructure</code>. It is a convenience method use instead of - * "instanceof" to see what type of structure we have. Note: this returns the type of this structure, not the type - * of data this structure holds. - * - * @return the <code>StructureType</code> of this structure, which is a StructureType.TAGSEGMENT. - * @see StructureType - */ - @Override - public StructureType getStructureType() { - return StructureType.TAGSEGMENT; - } - - /** - * Write this tag segment structure out as an XML record. - * @param xmlWriter the writer used to write the events. - */ - @Override - public void toXML(XMLStreamWriter xmlWriter) { - - try { - commonXMLStart(xmlWriter); - if (DataType.getDataType(header.dataType).isStructure()) { - xmlWriter.writeAttribute("content", xmlContentAttributeName); - } - xmlWriter.writeAttribute("data_type", String.format("0x%x", header.dataType)); - xmlWriter.writeAttribute("tag", "" + header.tag); - xmlWriter.writeAttribute("length", "" + header.length); - xmlWriter.writeAttribute("ndata", "" + getNumberDataItems()); - increaseXmlIndent(); - commonXMLDataWrite(xmlWriter); - decreaseXmlIndent(); - commonXMLClose(xmlWriter); - } - catch (XMLStreamException e) { - e.printStackTrace(); - } - } - - /** - * Get the element name for the bank for writing to XML. - * @return the element name for the structure for writing to XML. - */ - @Override - public String getXMLElementName() { - return ELEMENT_NAME; - } - -}
diff -N EvioXMLDictionary.java --- EvioXMLDictionary.java 27 Jul 2011 23:19:01 -0000 1.1.1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,221 +0,0 @@
-package org.jlab.coda.jevio; - -import java.io.File; -import java.io.IOException; -import java.io.ByteArrayInputStream; -import java.util.Collections; -import java.util.Vector; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; - -import org.w3c.dom.Document; -import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.xml.sax.SAXException; - -/** - * This was developed to read the xml dictionary that Maurizio uses for GEMC. It implements INameProvider, just like all - * other dictionary readers. - * - * @author heddle - * - */ -@SuppressWarnings("serial") -public class EvioXMLDictionary extends Vector<EvioDictionaryEntry> implements INameProvider { - - /** - * There is only one type of element. This is its stange name. - */ - private static String ENTRY = "xmldumpDictEntry"; - - /** - * The "name" attribute name. - */ - private static String NAME = "name"; - - /** - * The "tag" attribute name. - */ - private static String TAG = "tag"; - - /** - * The "num" attribute name. - */ - private static String NUM = "num"; - - /** - * Create an EvioXMLDictionary. This is not a standard CODA disctionary, but a format developed for use by GEMC. - * - * @param file file containing xml. - */ - public EvioXMLDictionary(File file) { - this(getDomObject(file)); - } - - /** - * Create an EvioXMLDictionary. This is not a standard CODA disctionary, but a format developed for use by GEMC. - * - * @param xmlString string containing xml. - */ - public EvioXMLDictionary(String xmlString) { - this(getDomObject(xmlString)); - } - - /** - * Create an EvioXMLDictionary. This is not a standard CODA disctionary, but a format developed for use by GEMC. - * - * @param domDocument DOM object representing xml dictionary. - */ - public EvioXMLDictionary(Document domDocument) { - super(100); - - // try to get the XML dom document - if (domDocument != null) { - NodeList list = domDocument.getElementsByTagName(ENTRY); - - if (list != null) { - for (int index = 0; index < list.getLength(); index++) { - Node node = list.item(index); - if (node != null) { - if (node.hasAttributes()) { - String name = null; - String tag = null; - String num = null; - - NamedNodeMap map = node.getAttributes(); - - // get the name - Node nameNode = map.getNamedItem(NAME); - if (nameNode != null) { - name = nameNode.getNodeValue(); - } - - // get the tag - Node tagNode = map.getNamedItem(TAG); - if (tagNode != null) { - tag = tagNode.getNodeValue(); - } - - // get the num - Node numNode = map.getNamedItem(NUM); - if (numNode != null) { - num = numNode.getNodeValue(); - } - - add (new EvioDictionaryEntry(tag, num, name)); - } // end node has attributes - } // end node not null - } // end loop over list - } - } - - //sort - Collections.sort(this); - -//System.out.println(this); - - } // end Constructor - - - /** - * Returns the pretty name of some evio structure. Typically this is involve - * the use of the "tag" and, if present, "num" fields. There may also be a hierarchical - * dependence. - * - * @param structure the structure to find the name of. - * @return a descriptive name, e.g., "Edep". - */ - @Override - public String getName(BaseStructure structure) { - for (EvioDictionaryEntry entry : this) { - if (entry.match(structure)) { - return entry.getDescription(); - } - } - return NameProvider.NO_NAME_STRING; - } - - /** - * Return a dom object corresponding to an xml file. - * - * @param file the XML File object - * @return the dom object (or <code>null</code>.) - */ - private static Document getDomObject(File file) { - // get the factory - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - Document dom = null; - - try { - - // Using factory get an instance of document builder - DocumentBuilder db = dbf.newDocumentBuilder(); - - // parse using builder to get DOM representation of the XML file - dom = db.parse(file); - - } - catch (ParserConfigurationException e) { - e.printStackTrace(); - } - catch (SAXException e) { - e.printStackTrace(); - } - catch (IOException e) { - e.printStackTrace(); - } - - return dom; - } - - /** - * Return a dom object corresponding to an xml string. - * - * @param xmlString XML string representing dictionary - * @return the dom object (or <code>null</code>.) - */ - private static Document getDomObject(String xmlString) { - // get the factory - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - Document dom = null; - - try { - - // Using factory get an instance of document builder - DocumentBuilder db = dbf.newDocumentBuilder(); - - // parse using builder to get DOM representation of the XML string - ByteArrayInputStream bais = new ByteArrayInputStream(xmlString.getBytes()); - dom = db.parse(bais); - - } - catch (ParserConfigurationException e) { - e.printStackTrace(); - } - catch (SAXException e) { - e.printStackTrace(); - } - catch (IOException e) { - e.printStackTrace(); - } - - return dom; - } - - /** - * Get a string representation of the dictionary. - * @return a string representation of the dictionary. - */ - @Override - public String toString() { - StringBuffer sb = new StringBuffer(1024); - sb.append("-- Dictionary --\n"); - for (EvioDictionaryEntry entry : this) { - sb.append(entry + "\n"); - } - return sb.toString(); - } -}
diff -N IEvioFilter.java --- IEvioFilter.java 27 Jul 2011 23:19:01 -0000 1.1.1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,29 +0,0 @@
-package org.jlab.coda.jevio; - -/** - * This interface allows applications to create filters so that they only recieve certain structures - * when events are being processed. Below is a filter that accepts any structure that has tag = 400. - * <pre> - * IEvioFilter myFilter = new IEvioFilter() { - * public boolean accept(StructureType structureType, BaseStructureHeader structureHeader) { - * return (structureHeader.getTag() == 400); - * } - * }; - * EventParser.getInstance().setEvioFilter(myFilter); - * </pre> - * @author heddle - * - */ -public interface IEvioFilter { - - /** - * @param structureType the structure type, a <code>StructureType</code> enum, of the structure - * that was just found, e.g., <code>StructureType.BANK</code>. - * @param structureHeader the header for the structure that was just found. From this - * header the tag, num, length, and data type are available, so the application can filter - * based on those quantities. - * @return <code>true</code> if the structure passes the filter and should be given to the listeners. - * @see StructureType - */ - public boolean accept(StructureType structureType, BaseStructureHeader structureHeader); -}
diff -N IEvioListener.java --- IEvioListener.java 27 Jul 2011 23:19:01 -0000 1.1.1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,35 +0,0 @@
-package org.jlab.coda.jevio; - -import java.util.EventListener; - -/** - * In SAX like behavior, implementors will listen for structures encountered when an event is parsed. - * - * @author heddle - * - */ -public interface IEvioListener extends EventListener { - - /** - * Called when a structure is read while parsing an event. - * - * NOTE: the user should NOT modify the event or the structure. - * - * @param evioEvent the data type, BANK, SEGMENT, or TAGSEGMENT - * @param structure the full structure, including header - */ - public void gotStructure(EvioEvent evioEvent, IEvioStructure structure); - - /** - * Starting to parse a new event. - * @param evioEvent the event in question. - */ - public void startEventParse(EvioEvent evioEvent); - - /** - * Done parsing a new event. - * @param evioEvent the event in question. - */ - public void endEventParse(EvioEvent evioEvent); - -}
diff -N IEvioProgressListener.java --- IEvioProgressListener.java 27 Jul 2011 23:19:01 -0000 1.1.1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,11 +0,0 @@
-package org.jlab.coda.jevio; - -public interface IEvioProgressListener { - - /** - * Something is listenening for progress, e.g. the number of events that has been written to XML. - * @param num the current number, - * @param total the total number, i.e, we have completed num out of total. - */ - public void completed(int num, int total); -}
diff -N IEvioStructure.java --- IEvioStructure.java 27 Jul 2011 23:19:01 -0000 1.1.1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,103 +0,0 @@
-package org.jlab.coda.jevio; - -/** - * This interface is implemented by classes representing the basic evio structures: banks, segments, and tagsegments. - * Note there is not "getNum" methods, because not all structures have num fields in their header, only BANKs do. - * - * @author heddle - * - */ -public interface IEvioStructure { - - /** - * Returns the header for this structure - * - * @return the <code>BaseStructureHeader</code> for this structure. - */ - public BaseStructureHeader getHeader(); - - /** - * Return the StructureType for this structure. - * - * @return the StructureType for this structure. - * @see StructureType - */ - public StructureType getStructureType(); - - /** - * Gets the raw data as an integer array, if the type as indicated by the - * header is appropriate. - * NOTE: since Java does not have unsigned primitives, both INT32 and UINT32 data types will be - * returned as int arrays. The application will have to deal with reinterpreting signed ints that are - * negative as unsigned ints - * @return the data as an int array, or <code>null</code> if this makes no sense for the given type. - */ - public int[] getIntData(); - - /** - * Gets the raw data as a double array, if the type as indicated by the - * header is appropriate. - * @return the data as an double array, or <code>null</code> if this makes no sense for the given type. - */ - public double[] getDoubleData(); - - /** - * Gets the raw data as an byte array, if the type as indicated by the - * header is appropriate. - * NOTE: since Java does not have unsigned primitives, CHAR8 and UCHAR8 data types will be - * returned as byte arrays. The application will have to deal with reinterpreting bytes as characters, - * if necessary. - * @return the data as an byte array, or <code>null</code> if this makes no sense for the given type. - */ - public byte[] getByteData(); - - /** - * Gets the raw data as an array of String objects, if the type as indicated by the - * header is appropriate. - * @return the data as an array of String objects, or <code>null</code> if this makes no sense for the given type. - * (The only DataType it makes sense for is CHARSTAR8.) - */ - public String[] getStringData(); - -// /** -// * Gets the raw data as a String, if the type as indicated by the -// * header is appropriate. -// * @return the data as a String, or <code>null</code> if this makes no sense for the given type. -// * (The only DataType it makes sense for is CHARSTAR8.) -// */ -// public String getStringData(); - - /** - * Gets the raw data as a long array, if the type as indicated by the - * header is appropriate. - * NOTE: since Java does not have unsigned primitives, both LONG64 and ULONG64 data types will be - * returned as long arrays. The application will have to deal with reinterpreting signed longs that are - * negative as unsigned longs. - * @return the data as an long array, or <code>null</code> if this makes no sense for the given type. - */ - public long[] getLongData(); - - /** - * Gets the raw data as a float array, if the type as indicated by the - * header is appropriate. - * @return the data as an double array, or <code>null</code> if this makes no sense for the given type. - */ - public float[] getFloatData(); - - /** - * Gets the raw data as a short array, if the type as indicated by the - * header is appropriate. - * @return the data as an short array, or <code>null</code> if this makes no sense for the given type. - */ - public short[] getShortData(); - - /** - * Get the description from the name provider (dictionary), if there is one. - * @return the description from the name provider (dictionary), if there is one. If not, return - * NameProvider.NO_NAME_STRING. - */ - public String getDescription(); - - - -}
diff -N IEvioWriter.java --- IEvioWriter.java 27 Jul 2011 23:19:01 -0000 1.1.1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,18 +0,0 @@
-package org.jlab.coda.jevio; - -import java.nio.ByteBuffer; - -/** - * This is implemented by objects that will be writing themselve's to en evio file. - * @author heddle - * - */ -public interface IEvioWriter { - - /** - * Write myself out a byte buffer. - * @param byteBuffer the byteBuffer to write to. - * @return the number of bytes written. - */ - public int write(ByteBuffer byteBuffer); -}
diff -N INameProvider.java --- INameProvider.java 27 Jul 2011 23:19:01 -0000 1.1.1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,21 +0,0 @@
-package org.jlab.coda.jevio; - -/** - * This interface must be implemented by dictionary readers. For example, a dictionary reader that parses standard CODA - * dictionary plain text files, or a dictionary reader that processes the xml dictionary Maurizio uses for GEMC. - * - * @author heddle - * - */ -public interface INameProvider { - - /** - * Returns the pretty name of some evio structure. Typically this is involve - * the use of the "tag" and, if present, "num" fields. There may also be a hierarchical - * dependence. - * - * @param structure the structure to find the name of. - * @return a descriptive name, e.g., "Edep". - */ - public String getName(BaseStructure structure); -}
diff -N NameProvider.java --- NameProvider.java 27 Jul 2011 23:19:01 -0000 1.1.1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,55 +0,0 @@
-package org.jlab.coda.jevio; - -/** - * This class maintains the single global NameProvider. There is no default name provider, so if the application doesn't - * provide one, the static method <code>getName</code> will always return the constant <code>NO_NAME_STRING</code>, - * which will be something like "NO_NAME_STRING". - * - * Typically at start up an application will locate a dictionary file, use the <code>NameProviderFactory</code> to - * create a <code>INameProvider</code>, and then call the static method @link #setProvider(INameProvider). - * - * @author heddle - * - */ -public class NameProvider { - - /** - * A string used to indicate that no name can be determined. - */ - public static String NO_NAME_STRING = "???"; - - /** - * The singleton - */ - private static INameProvider provider; - - /** - * Private constructor prevents anyone from making one of these. - */ - private NameProvider() { - } - - /** - * Sets the one global (singleton) name provider. - * - * @param aProvider the provider to use. - */ - public static void setProvider(INameProvider aProvider) { - provider = aProvider; - } - - /** - * Returns the pretty name of some evio structure. Typically this is involve - * the use of the "tag" and, if present, "num" fields. There may also be a hierarchical - * dependence. - * - * @param structure the structure to find the name of. - * @return a descriptive name, e.g., "Edep". - */ - public static String getName(BaseStructure structure) { - if (provider == null) { - return NO_NAME_STRING; - } - return provider.getName(structure); - } -}
diff -N NameProviderFactory.java --- NameProviderFactory.java 27 Jul 2011 23:19:01 -0000 1.1.1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,54 +0,0 @@
-package org.jlab.coda.jevio; - -import java.io.File; - -/** - * A Factory class for generating an appropriate INameProvider. It makes its decisions based on the dictionary file that - * it gets handed in its only public method, <code>createNameProvider</code>. For example, if it is given an xml file - * (based on a ".xml" extension) it guesses that you want a reader that can handle the xml diction file developed for - * GEMC. - * - * @author heddle - * - */ -public class NameProviderFactory { - - /** - * Creates a NameProvider based on the file name. - * - * @param file dictionary file. - * @return a NameProvider appropriate for the fileName. - */ - public static INameProvider createNameProvider(File file) { - INameProvider provider = null; - - if (file != null) { - // only handle xml files for now - if (file.getName().endsWith(".xml")) { - return new EvioXMLDictionary(file); - } - // TODO provide provider for standard CODA dictionaries - } - - return provider; - } - - - /** - * Creates a NameProvider based on the file name. - * - * @param xmlString xml dictionary string. - * @return a NameProvider appropriate for the fileName. - */ - public static INameProvider createNameProvider(String xmlString) { - INameProvider provider = null; - - if (xmlString != null) { - return new EvioXMLDictionary(xmlString); - // TODO provide provider for standard CODA dictionaries - } - - return provider; - } - -}
diff -N SegmentHeader.java --- SegmentHeader.java 27 Jul 2011 23:19:01 -0000 1.1.1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,98 +0,0 @@
-package org.jlab.coda.jevio; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; - -/** - * This the the header for an evio segment structure (<code>EvioSegment</code>). It does not contain the raw data, just the - * header. - * - * @author heddle - * - */ -public final class SegmentHeader extends BaseStructureHeader { - - - /** - * Null constructor. - */ - public SegmentHeader() { - } - - /** - * Constructor. - * @param tag the tag for the segment header. - * @param dataType the data type for the content of the segment. - */ - public SegmentHeader(int tag, DataType dataType) { - super(tag, dataType); - } - - /** - * Constructor. - * @param tag the tag for the segment header. - * @param dataType the (int) data type for the content of the segment. - */ - public SegmentHeader(int tag, int dataType) { - super(tag, dataType); - } - - /** - * {@inheritDoc} - */ - public int getHeaderLength() {return 1;} - - /** - * {@inheritDoc} - */ - protected void toArray(byte[] bArray, int offset, ByteOrder order) { - if (order == ByteOrder.BIG_ENDIAN) { - bArray[offset] = byteValue(tag); - bArray[offset+1] = byteValue(dataType); - ByteDataTransformer.shortToBytes(shortValue(length), bArray, offset+2); - } - else { - ByteDataTransformer.shortToBytes(Short.reverseBytes(shortValue(length)), bArray, offset); - bArray[offset+2] = byteValue(dataType); - bArray[offset+3] = byteValue(tag); - } - } - - /** - * Obtain a string representation of the bank header. - * - * @return a string representation of the bank header. - */ - @Override - public String toString() { - StringBuffer sb = new StringBuffer(512); - sb.append(String.format("segment length: %d\n", length)); - sb.append(String.format("number: %d\n", number)); - sb.append(String.format("data type: %s\n", getDataTypeName())); - sb.append(String.format("tag: %d\n", tag)); - return sb.toString(); - } - - /** - * Write myself out a byte buffer. This write is relative--i.e., it uses the current position of the buffer. - * - * @param byteBuffer the byteBuffer to write to. - * @return the number of bytes written, which for a SegmentHeader is 4. - */ - @Override - public int write(ByteBuffer byteBuffer) { - if (byteBuffer.order() == ByteOrder.BIG_ENDIAN) { - byteBuffer.put(byteValue(tag)); - byteBuffer.put(byteValue(dataType)); - byteBuffer.putShort(shortValue(length)); - } - else { - byteBuffer.putShort(shortValue(length)); - byteBuffer.put(byteValue(dataType)); - byteBuffer.put(byteValue(tag)); - } - return 4; - } - - -}
\ No newline at end of file
diff -N StructureFinder.java --- StructureFinder.java 27 Jul 2011 23:19:01 -0000 1.1.1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,78 +0,0 @@
-package org.jlab.coda.jevio; - -import java.util.List; - -/** - * This is a set of convenient static methods used to find lists of structures within an event that - * match certain criteria. For most part it uses the <code>List<BaseStructure> getMatchingStructures(IEvioFilter)</code> - * method on the provided <code>EvioEvent</code> object by constructing the appropriate filter. - * @author heddle - * - */ -public class StructureFinder { - - - /** - * Collect all the structures in an event that pass a filter. - * @param event the event being queried. - * @param filter the filter that must be passed. If <code>null</code>, this will return all the structures. - * @return a collection of all structures that are accepted by a filter for the provided event. - */ - public static List<BaseStructure> getMatchingStructures(EvioEvent event, IEvioFilter filter) { - if (event == null) { - return null; - } - return event.getMatchingStructures(filter); - } - - /** - * Collect all the banks in an event that match a provided tag and number in their header. Only Banks are returned, - * because only Banks have a number field. - * @param event the event being queried. - * @param tag the tag to match. - * @param number the number to match. - * @return a collection of all Banks that are accepted by a filter for the provided event. - */ - public static List<BaseStructure> getMatchingBanks(EvioEvent event, final int tag, final int number) { - IEvioFilter filter = new IEvioFilter() { - @Override - public boolean accept(StructureType type, BaseStructureHeader header) { - return (type == StructureType.BANK) && (tag == header.tag) && (number == header.number); - } - }; - return getMatchingStructures(event, filter); - } - - /** - * Collect all the structures in an event that match a provided tag in their header. - * @param event the event being queried. - * @param tag the tag to match. - * @return a collection of all structures that are accepted by a filter for the provided event. - */ - public static List<BaseStructure> getMatchingStructures(EvioEvent event, final int tag) { - IEvioFilter filter = new IEvioFilter() { - @Override - public boolean accept(StructureType type, BaseStructureHeader header) { - return (tag == header.tag); - } - }; - return getMatchingStructures(event, filter); - } - - /** - * Collect all the non-banks (i.e., Segments and TagSegments) in an event that match a provided tag in their header. No Banks are returned, - * @param event the event being queried. - * @param tag the tag to match. - * @return a collection of all non-bank structures that are accepted by a filter for the provided event. - */ - public static List<BaseStructure> getMatchingNonBanks(EvioEvent event, final int tag) { - IEvioFilter filter = new IEvioFilter() { - @Override - public boolean accept(StructureType type, BaseStructureHeader header) { - return (type != StructureType.BANK) && (tag == header.tag); - } - }; - return getMatchingStructures(event, filter); - } - -}
diff -N StructureType.java --- StructureType.java 27 Jul 2011 23:19:01 -0000 1.1.1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,63 +0,0 @@
-package org.jlab.coda.jevio; - -/** - * This an enum used to convert structure type numerical values to a more meaningful name. For example, the structure - * type with value 0xe corresponds to the enum BANK. Mostly this is used for printing. - * - * @author heddle - * - */ -public enum StructureType { - - UNKNOWN32(0x0), - TAGSEGMENT(0xc), - SEGMENT(0xd), - BANK(0xe); - - private int value; - - private StructureType(int value) { - this.value = value; - } - - /** - * Get the enum's value. - * - * @return the value, e.g., 0xe for a BANK - */ - public int getValue() { - return value; - } - - /** - * Obtain the name from the value. - * - * @param value the value to match. - * @return the name, or "UNKNOWN". - */ - public static String getName(int value) { - StructureType structuretypes[] = StructureType.values(); - for (StructureType dt : structuretypes) { - if (dt.value == value) { - return dt.name(); - } - } - return "UNKNOWN"; - } - - /** - * Obtain the enum from the value. - * - * @param value the value to match. - * @return the matching enum, or <code>null</code>. - */ - public static StructureType getStructureType(int value) { - StructureType structuretypes[] = StructureType.values(); - for (StructureType dt : structuretypes) { - if (dt.value == value) { - return dt; - } - } - return null; - } -}
diff -N TagSegmentHeader.java --- TagSegmentHeader.java 27 Jul 2011 23:19:01 -0000 1.1.1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,97 +0,0 @@
-package org.jlab.coda.jevio; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; - -/** - * This the the header for an evio tag segment structure (<code>EvioTagSegment</code>). It does not contain the raw data, just the - * header. - * - * @author heddle - * - */ -public final class TagSegmentHeader extends BaseStructureHeader { - - /** - * Null constructor. - */ - public TagSegmentHeader() { - } - - /** - * Constructor. - * @param tag the tag for the tag segment header. - * @param dataType the data type for the content of the tag segment. - */ - public TagSegmentHeader(int tag, DataType dataType) { - super(tag, dataType); - } - - /** - * Constructor. - * @param tag the tag for the tag segment header. - * @param dataType the (int) data type for the content of the tag segment. - */ - public TagSegmentHeader(int tag, int dataType) { - super(tag, dataType); - } - - - /** - * {@inheritDoc} - */ - public int getHeaderLength() {return 1;} - - /** - * {@inheritDoc} - */ - protected void toArray(byte[] bArray, int offset, ByteOrder order) { - short compositeWord = (short) ((tag << 4) | (dataType & 0xf)); - - if (order == ByteOrder.BIG_ENDIAN) { - ByteDataTransformer.shortToBytes(compositeWord, bArray, offset); - ByteDataTransformer.shortToBytes(shortValue(length), bArray, offset+2); - } - else { - ByteDataTransformer.shortToBytes(Short.reverseBytes(shortValue(length)), bArray, offset); - ByteDataTransformer.shortToBytes(Short.reverseBytes(compositeWord), bArray, offset+2); - } - } - - /** - * Obtain a string representation of the bank header. - * - * @return a string representation of the bank header. - */ - @Override - public String toString() { - StringBuffer sb = new StringBuffer(512); - sb.append(String.format("tag-seg length: %d\n", length)); - sb.append(String.format("number: %d\n", number)); - sb.append(String.format("data type: %s\n", getDataTypeName())); - sb.append(String.format("tag: %d\n", tag)); - return sb.toString(); - } - - /** - * Write myself out a byte buffer. This write is relative--i.e., it uses the current position of the buffer. - * - * @param byteBuffer the byteBuffer to write to. - * @return the number of bytes written, which for a TagSegmentHeader is 4. - */ - @Override - public int write(ByteBuffer byteBuffer) { - short compositeWord = (short) ((tag << 4) | (dataType & 0xf)); - - if (byteBuffer.order() == ByteOrder.BIG_ENDIAN) { - byteBuffer.putShort(compositeWord); - byteBuffer.putShort(shortValue(length)); - } - else { - byteBuffer.putShort(shortValue(length)); - byteBuffer.putShort(compositeWord); - } - return 4; - } - -}
\ No newline at end of file
Use REPLY-ALL to reply to list
To unsubscribe from the LCD-CVS list, click the following link:
https://listserv.slac.stanford.edu/cgi-bin/wa?SUBED1=LCD-CVS&A=1