Commit in jevio-base/src/main/java/org/jlab/coda/jevio on MAIN | |||
BaseStructure.java | +120 | -9 | 1.3 -> 1.4 |
CompositeData.java | +1579 | -171 | 1.2 -> 1.3 |
EvioFile.java | +3 | -1 | 1.3 -> 1.4 |
graphics/EventTreePanel.java | +6 | -4 | 1.1 -> 1.2 |
test/CompositeTester.java | +118 | -89 | 1.1 -> 1.2 |
+1826 | -274 |
update to latest coda distrib of jevio 4.0
diff -u -r1.3 -r1.4 --- BaseStructure.java 28 Feb 2012 19:41:35 -0000 1.3 +++ BaseStructure.java 8 Mar 2012 20:39:26 -0000 1.4 @@ -851,7 +851,95 @@
/**
- * Extract an array of strings from raw evio string data.
+ * This method returns the number of bytes in a raw + * evio format of the given string array. + * + * @param strings array of String objects to size + * @return the number of bytes in a raw evio format of the given string array + * @return 0 if arg is null or has zero length + */ + static public int stringsToRawSize(String[] strings) { + + if (strings == null || strings.length < 1) { + return 0; + } + + int dataLen = 0; + for (String s : strings) { + dataLen += s.length() + 1; // don't forget the null + } + + // Add any necessary padding to 4 byte boundaries. + // IMPORTANT: There must be at least one '\004' + // character at the end. This distinguishes evio + // string array version from earlier version. + int[] pads = {4,3,2,1}; + dataLen += pads[dataLen%4]; + + return dataLen; + } + + + /** + * This method transforms an array of Strings into raw evio format data. + * + * @param strings array of String objects to transform + * @return byte array containing evio format string array + * @return null if arg is null or has zero length + */ + static public byte[] stringsToRawBytes(String[] strings) { + + if (strings == null || strings.length < 1) { + return null; + } + + // create some storage + int dataLen = 0; + for (String s : strings) { + dataLen += s.length() + 1; // don't forget the null + } + dataLen += 4; // allow room for maximum padding of 4's + StringBuilder stringData = new StringBuilder(dataLen); + + for (String s : strings) { + // add string + stringData.append(s); + // add ending null + stringData.append('\000'); + } + + // Add any necessary padding to 4 byte boundaries. + // IMPORTANT: There must be at least one '\004' + // character at the end. This distinguishes evio + // string array version from earlier version. + int[] pads = {4,3,2,1}; + switch (pads[stringData.length()%4]) { + case 4: + stringData.append("\004\004\004\004"); + break; + case 3: + stringData.append("\004\004\004"); + break; + case 2: + stringData.append("\004\004"); + break; + case 1: + stringData.append('\004'); + default: + } + + // set raw data + try { + return stringData.toString().getBytes("US-ASCII"); + } + catch (UnsupportedEncodingException e) { /* never happen */ } + + return null; + } + + + /** + * This method extracts an array of strings from raw evio string data.
* * @param rawBytes raw evio string data * @param offset offset into raw data array
@@ -1347,14 +1435,12 @@
if (compositeData == null) { try { getCompositeData();
- //xmlWriter.writeCData(compositeData.toXMLString("", true)); - System.out.println(compositeData.toXMLString("", true));
} catch (EvioException e) {
- e.printStackTrace(); - System.out.println("Warning: " + e.getMessage());
+ return;
} }
+ compositeData.toXML(xmlWriter, this, true);
break; }
@@ -1654,6 +1740,7 @@
break; case COMPOSITE:
+ // compositeData object always has rawBytes defined
if (rawBytes != null) { if (byteOrder == byteBuffer.order()) { byteBuffer.put(rawBytes, 0, rawBytes.length);
@@ -1663,16 +1750,13 @@
byte[] swappedRaw = new byte[rawBytes.length]; try { CompositeData.swapAll(rawBytes, 0, swappedRaw, 0,
- rawBytes.length, byteOrder);
+ rawBytes.length/4, byteOrder);
} catch (EvioException e) { /* never happen */ } // write them to buffer byteBuffer.put(swappedRaw, 0, swappedRaw.length); } }
- else { - // composite type can only be read, not created with evio API - }
break;
@@ -2070,5 +2154,32 @@
setAllHeaderLengths(); }
+ /** + * Sets the CompositeData object of this structure. No "append" mode for + * this type of data exists. + * + * @param data CompositeData object + * @throws EvioException + */ + public void appendCompositeData(CompositeData data) throws EvioException { + + DataType dataType = header.getDataType(); + if (dataType != DataType.COMPOSITE) { + throw new EvioException("Tried to set composite data in a structure of type: " + dataType); + } + + if (data == null) { + return; + } + + compositeData = data; + numberDataItems = data.getItems().size(); + rawBytes = data.getRawBytes(); + byteOrder = data.getByteOrder(); + + lengthsUpToDate(false); + setAllHeaderLengths(); + } +
}
diff -u -r1.2 -r1.3 --- CompositeData.java 28 Feb 2012 23:45:42 -0000 1.2 +++ CompositeData.java 8 Mar 2012 20:39:26 -0000 1.3 @@ -37,10 +37,14 @@
*/ package org.jlab.coda.jevio;
+ +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamWriter;
import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.ArrayList; import java.util.List;
+import java.util.ListIterator;
/** * This is the class defining the composite data type.
@@ -63,6 +67,9 @@
/** List of the types of the extracted data items. */ private List<DataType> types;
+ /** List of the "N" values extracted from the raw data. */ + private List<Integer> nList; +
/** Tagsegment header of tagsegment containing format string. */ private TagSegmentHeader tsHeader;
@@ -78,7 +85,7 @@
/** Length of only data in bytes. */ private int dataBytes;
- /** Offset in rawBytes to place of data. */
+ /** Offset (in 32bit words) in rawBytes to place of data. */
private int dataOffset; /** Byte order of raw bytes. */
@@ -88,12 +95,98 @@
private int getIndex;
-
/** Zero arg constructor used for cloning. */ private CompositeData() {}
+ + /** + * Constructor used for creating this object from scratch. + * + * @param format format String defining data + * @param formatTag tag used in tagsegment containing format + * @param data data in given format + * @param dataTag tag used in bank containing data + * @param dataNum num used in bank containing data + * + * @throws EvioException data or format arg = null; + * if improper format string + */ + public CompositeData(String format, int formatTag, + CompositeData.Data data, int dataTag, int dataNum) + throws EvioException { + + boolean debug = true; + + this.format = format; + byteOrder = ByteOrder.BIG_ENDIAN; + + if (debug) System.out.println("Analyzing composite data:"); + + // Check args + if (format == null || data == null) { + throw new EvioException("format and/or data arg is null"); + } + + // Analyze format string + formatInts = compositeFormatToInt(format); + if (formatInts.size() < 1) { + throw new EvioException("bad format string data"); + } + + items = data.dataItems; + types = data.dataTypes; + nList = data.nList; + + // Create the tag segment + EvioTagSegment tagSegment = new EvioTagSegment(formatTag, DataType.CHARSTAR8); + try { + // Add format string + tagSegment.appendStringData(format); + } + catch (EvioException e) {/* never happen */ } + tsHeader = (TagSegmentHeader) tagSegment.getHeader(); + + // Now create data bank + EvioBank bank = new EvioBank(dataTag, DataType.COMPOSITE, dataNum); + bHeader = (BankHeader) bank.getHeader(); + bHeader.setPadding(data.getPadding()); + + // How big is the data in bytes (including padding) ? + dataBytes = data.getDataSize(); + + // Set data length in bank header (includes 2nd bank header word) + bHeader.setLength(1 + dataBytes/4); + + // Length of everything except data (32 bit words) + dataOffset = bHeader.getHeaderLength() + + tsHeader.getHeaderLength() + + tsHeader.getLength(); + + // Length of everything in bytes + int totalByteLen = dataBytes + 4*dataOffset; + + // Create a big enough array to hold everything + rawBytes = new byte[totalByteLen]; + + // Create ByteBuffer object around array + ByteBuffer allDataBuffer = ByteBuffer.wrap(rawBytes, 0, totalByteLen); + + // Write tagsegment to buffer + tagSegment.write(allDataBuffer); + + // Write bank header to buffer + bHeader.write(allDataBuffer); + + // Write data into the dataBuffer + dataToRawBytes(allDataBuffer, data, formatInts); + + // Set data buffer for completenesss + dataBuffer = ByteBuffer.wrap(rawBytes, 4*dataOffset, dataBytes).slice(); + } + +
/**
- * Constructor.
+ * Constructor used when reading existing data.
* * @param rawBytes raw data defining this composite type item * @param byteOrder byte order of rawBytes
@@ -101,7 +194,7 @@
public CompositeData(byte[] rawBytes, ByteOrder byteOrder) throws EvioException {
- boolean debug = true;
+ boolean debug = false;
if (rawBytes == null) { throw new EvioException("null argument(s)");
@@ -131,7 +224,7 @@
// Read the format string it contains String[] strs = BaseStructure.unpackRawBytesToStrings(rawBytes, 4*dataOffset);
-
+
if (strs.length < 1) { throw new EvioException("bad format string data"); }
@@ -176,7 +269,7 @@
// Turn dataBuffer into list of items and their types process();
- }
+ }
/**
@@ -241,6 +334,642 @@
return cd; }
+ + + /** + * This class is used to provide all data when constructing a CompositeData object. + * Doing things this way keeps all internal data members self-consistent. + */ + public static class Data { + + /** Keep a running total of how many bytes the data take without padding. + * This includes both the dataItems and N values and thus assumes all N + * values will be written. */ + private int dataBytes; + + /** The number of bytes needed to complete a 4-byte boundary. */ + private int paddingBytes; + + /** Convenient way to calculate padding. */ + private int[] pads = {0,3,2,1}; + + /** List of data objects. */ + private ArrayList<Object> dataItems = new ArrayList<Object>(100); + + /** List of types of data objects. */ + private ArrayList<DataType> dataTypes = new ArrayList<DataType>(100); + + /** List of "N" values - multiplier values read from data instead + * of being part of the format string. */ + private ArrayList<Integer> nList = new ArrayList<Integer>(100); + +// private String format; +// private List<Integer> formatInts; +// private int formatIndex; +// private int parenLevel; + +// /** The number of times items of a particular type get added. */ +// private int repeat = 1; + +// public Data(String format) throws EvioException { +// this.format = format; +// this.formatInts = compositeFormatToInt(format); +// if (formatInts.size() <= 0) throw new EvioException("empty format list"); +// } + + /** Constructor. */ + public Data() {} + + + /** + * This method keeps track of the raw data size in bytes. + * Also keeps track of padding. + * @param bytes number of bytes to add. + */ + private void addBytesToData(int bytes) { + dataBytes += bytes; + // Pad to 4 byte boundaries. + paddingBytes = pads[dataBytes%4]; + } + + /** + * This method gets the raw data size in bytes. + * @return raw data size in bytes. + */ + synchronized public int getDataSize() { + return (dataBytes + paddingBytes); + } + + /** + * This method gets the padding (in bytes). + * @return padding (in bytes). + */ + synchronized public int getPadding() { + return paddingBytes; + } + + /** + * This method add an "N" or multiplier value to the data + * in the sequence determined by the format string. + * Does not needed to be added in sequence with other data. + * @param N N or multiplier value + */ + synchronized public void addN(int N) { + nList.add(N); + addBytesToData(4); + } + + + /** + * This method add an array of "N" or multiplier values to the data + * in the sequence determined by the format string. Does not needed + * to be added in sequence with other data. + * @param N array of N or multiplier values + */ + synchronized public void addN(int[] N) { + for (int n : N) { + nList.add(n); + addBytesToData(4); + } + } + + + /** + * Add a signed 32 bit integer to the data. + * @param i integer to add. + */ + synchronized public void addInt(int i) { + dataItems.add(i); + dataTypes.add(DataType.INT32); + addBytesToData(4); + } + + /** + * Add an array of signed 32 bit integers to the data. + * @param i array of integers to add. + */ + synchronized public void addInt(int[] i) { + for (int ii : i) { + dataItems.add(ii); + dataTypes.add(DataType.INT32); + } + addBytesToData(4*i.length); + } + + /** + * Add an unsigned 32 bit integer to the data. + * In Java, there is no unsigned types. It is the + * responsibility of the user to handle this type properly. + * @param i unsigned integer to add. + */ + synchronized public void addUint(int i) { + dataItems.add(i); + dataTypes.add(DataType.UINT32); + addBytesToData(4); + } + + /** + * Add an array of unsigned 32 bit integers to the data. + * In Java, there is no unsigned types. It is the + * responsibility of the user to handle this type properly. + * @param i array of unsigned integers to add. + */ + synchronized public void addUint(int[] i) { + for (int ii : i) { + dataItems.add(ii); + dataTypes.add(DataType.UINT32); + } + addBytesToData(4*i.length); + } + + + + /** + * Add a 16 bit short to the data. + * @param s short to add. + */ + synchronized public void addShort(short s) { + dataItems.add(s); + dataTypes.add(DataType.SHORT16); + addBytesToData(2); + } + + /** + * Add an array of 16 bit shorts to the data. + * @param s array of shorts to add. + */ + synchronized public void addShort(short[] s) { + for (short ss : s) { + dataItems.add(ss); + dataTypes.add(DataType.SHORT16); + } + addBytesToData(2*s.length); + } + + /** + * Add an unsigned 16 bit short to the data. + * @param s unsigned short to add. + */ + synchronized public void addUshort(short s) { + dataItems.add(s); + dataTypes.add(DataType.USHORT16); + addBytesToData(2); + } + + /** + * Add an array of unsigned 16 bit shorts to the data. + * @param s array of unsigned shorts to add. + */ + synchronized public void addUshort(short[] s) { + for (short ss : s) { + dataItems.add(ss); + dataTypes.add(DataType.USHORT16); + } + addBytesToData(2*s.length); + } + + + + /** + * Add a 64 bit long to the data. + * @param l long to add. + */ + synchronized public void addLong(long l) { + dataItems.add(l); + dataTypes.add(DataType.LONG64); + addBytesToData(8); + } + + /** + * Add an array of 64 bit longs to the data. + * @param l array of longs to add. + */ + synchronized public void addLong(long[] l) { + for (long ll : l) { + dataItems.add(ll); + dataTypes.add(DataType.LONG64); + } + addBytesToData(8*l.length); + } + + /** + * Add an unsigned 64 bit long to the data. + * @param l unsigned long to add. + */ + synchronized public void addUlong(long l) { + dataItems.add(l); + dataTypes.add(DataType.ULONG64); + addBytesToData(8); + } + + /** + * Add an array of unsigned 64 bit longs to the data. + * @param l array of unsigned longs to add. + */ + synchronized public void addUlong(long[] l) { + for (long ll : l) { + dataItems.add(ll); + dataTypes.add(DataType.ULONG64); + } + addBytesToData(8*l.length); + } + + + + /** + * Add an 8 bit byte (char) to the data. + * @param b byte to add. + */ + synchronized public void addChar(byte b) { + dataItems.add(b); + dataTypes.add(DataType.CHAR8); + addBytesToData(1); + } + + /** + * Add an array of 8 bit bytes (chars) to the data. + * @param b array of bytes to add. + */ + synchronized public void addChar(byte[] b) { + for (byte bb : b) { + dataItems.add(bb); + dataTypes.add(DataType.CHAR8); + } + addBytesToData(b.length); + } + + /** + * Add an unsigned 8 bit byte (uchar) to the data. + * @param b unsigned byte to add. + */ + synchronized public void addUchar(byte b) { + dataItems.add(b); + dataTypes.add(DataType.UCHAR8); + addBytesToData(1); + } + + /** + * Add an array of unsigned 8 bit bytes (uchars) to the data. + * @param b array of unsigned bytes to add. + */ + synchronized public void addUchar(byte[] b) { + for (byte bb : b) { + dataItems.add(bb); + dataTypes.add(DataType.UCHAR8); + } + addBytesToData(b.length); + } + + + + /** + * Add a 32 bit float to the data. + * @param f float to add. + */ + synchronized public void addFloat(float f) { + dataItems.add(f); + dataTypes.add(DataType.FLOAT32); + addBytesToData(4); + } + + /** + * Add an array of 32 bit floats to the data. + * @param f array of floats to add. + */ + synchronized public void addFloat(float[] f) { + for (float ff : f) { + dataItems.add(ff); + dataTypes.add(DataType.FLOAT32); + } + addBytesToData(4*f.length); + } + + + + /** + * Add a 64 bit double to the data. + * @param d double to add. + */ + synchronized public void addDouble(double d) { + dataItems.add(d); + dataTypes.add(DataType.DOUBLE64); + addBytesToData(8); + } + + /** + * Add an array of 64 bit doubles to the data. + * @param d array of doubles to add. + */ + synchronized public void addDouble(double[] d) { + for (double dd : d) { + dataItems.add(dd); + dataTypes.add(DataType.DOUBLE64); + } + addBytesToData(8*d.length); + } + + + + /** + * Add a string to the data. + * @param s string to add. + */ + synchronized public void addString(String s) { + String[] ss = new String[] {s}; + dataItems.add(ss); + dataTypes.add(DataType.CHARSTAR8); + addBytesToData(BaseStructure.stringsToRawSize(ss)); + } + + /** + * Add an array of strings to the data. + * @param s array of strings to add. + */ + synchronized public void addString(String[] s) { + dataItems.add(s); + dataTypes.add(DataType.CHARSTAR8); + addBytesToData(BaseStructure.stringsToRawSize(s)); + } + + + +// /** +// * This method checks to see if the data being added corresponds to the +// * data format given. If not, an exception is thrown. +// * +// * @throws EvioException if item's data type does <b>not</> correspond +// * with the given format string +// */ +// public void checkDataFormat(DataType itemType) throws EvioException { +// +// boolean debug = false; +// int formatIndex, ncnf, kcnf, iterm; +// +// class LV { +// int left; // index of formatInts[] element containing left parenthesis "(" +// int nrepeat; // how many times format in parenthesis must be repeated +// int irepeat; // right parenthesis ")" counter, or how many times format +// // in parenthesis already repeated +// }; +// +// LV[] lv = new LV[10]; +// for (int i=0; i < lv.length; i++) { +// lv[i] = new LV(); +// } +// +// int nfmt = formatInts.size(); +// +// formatIndex = 0; // formatInts[] index +// ncnf = 0; // how many times must repeat a format +// iterm = 0; +// +// +// // get next format code +// while (true) { +// formatIndex++; +// // end of format statement reached, back to iterm - last parenthesis or format begining +// if (formatIndex > nfmt) { +// formatIndex = 0; +// } +// // meet right parenthesis, so we're finished processing format(s) in parenthesis +// else if (formatInts.get(formatIndex - 1) == 0) { +// // increment counter +// lv[parenLevel -1].irepeat++; +// +// // if format in parenthesis was processed the required number of times +// if (lv[parenLevel -1].irepeat >= lv[parenLevel -1].nrepeat) { +// // store left parenthesis index minus 1 +// iterm = lv[parenLevel -1].left - 1; +// +// // If end of format, will start from format index imt=iterm. +// // By default we continue from the beginning of the format (iterm=0). +// +// // done with this level - decrease parenthesis level +// parenLevel--; +// } +// // go for another round of processing by setting 'imt' to the left parenthesis +// else { +// // points ifmt[] index to the left parenthesis from the same level 'lev' +// formatIndex = lv[parenLevel -1].left; +// } +// } +// else { +// // how many times to repeat format code +// ncnf = formatInts.get(formatIndex -1)/16; +// // format code +// kcnf = formatInts.get(formatIndex -1) - 16*ncnf; +// +// // left parenthesis, SPECIAL case: #repeats must be taken from data +// if (kcnf == 15) { +// // set it to regular left parenthesis code +// kcnf = 0; +// +// // "N" value being added +// if (itemType != DataType.INT32 | itemType != DataType.UINT32) { +// throw new EvioException("Wrong data type for N"); +// } +// return; +// } +// +// // left parenthesis - set new lv[] +// if (kcnf == 0) { +// // store ifmt[] index +// lv[parenLevel].left = formatIndex; +// // how many time will repeat format code inside parenthesis +// lv[parenLevel].nrepeat = ncnf; +// // cleanup place for the right parenthesis (do not get it yet) +// lv[parenLevel].irepeat = 0; +// // increase parenthesis level +// parenLevel++; +// } +// // format F or I or ... +// else { +// // there are no parenthesis, just simple format, go to processing +// if (parenLevel == 0) { +// } +// // have parenthesis, NOT the pre-last format element (last assumed ')' ?) +// else if (formatIndex != (nfmt-1)) { +// } +// // have parenthesis, NOT the first format after the left parenthesis +// else if (formatIndex != lv[parenLevel -1].left+1) { +// } +// else { +// // If none of above, we are in the end of format +// // so set format repeat to a big number. +// ncnf = 999999999; +// } +// break; +// } +// } +// } +// +// +// // if 'ncnf' is zero, get "N" from list (always in 'int' format) +// if (ncnf == 0) { +// // "N" value being added +// if (itemType != DataType.INT32 | itemType != DataType.UINT32) { +// throw new EvioException("Wrong data type for N"); +// } +// return; +// } +// +// +// // At this point we are ready to process next piece of data;. +// // We have following entry info: +// // kcnf - format type +// // ncnf - how many times format repeated +// +// // Convert data type kcnf +// switch (kcnf) { +// // 64 Bits +// case 8: +// for (int j=0; j < ncnf; j++) { +// if (itemType != DataType.DOUBLE64) { +// throw new EvioException("Data type mismatch"); +// } +// } +// break; +// +// case 9: +// for (int j=0; j < ncnf; j++) { +// if (itemType != DataType.LONG64) { +// throw new EvioException("Data type mismatch"); +// } +// } +// break; +// +// case 10: +// for (int j=0; j < ncnf; j++) { +// if (itemType != DataType.ULONG64) { +// throw new EvioException("Data type mismatch"); +// } +// } +// break; +// +// // 32 Bits +// case 1: +// for (int j=0; j < ncnf; j++) { +// if (itemType != DataType.INT32) { +// throw new EvioException("Data type mismatch"); +// } +// } +// break; +// +// case 11: +// for (int j=0; j < ncnf; j++) { +// if (itemType != DataType.UINT32) { +// throw new EvioException("Data type mismatch"); +// } +// } +// break; +// +// case 2: +// for (int j=0; j < ncnf; j++) { +// if (itemType != DataType.FLOAT32) { +// throw new EvioException("Data type mismatch"); +// } +// } +// break; +// +// case 12: +// for (int j=0; j < ncnf; j++) { +// if (itemType != DataType.HOLLERIT) { +// throw new EvioException("Data type mismatch"); +// } +// } +// break; +// +// // 16 bits +// case 4: +// for (int j=0; j < ncnf; j++) { +// if (itemType != DataType.SHORT16) { +// throw new EvioException("Data type mismatch"); +// } +// } +// break; +// +// case 5: +// for (int j=0; j < ncnf; j++) { +// if (itemType != DataType.USHORT16) { +// throw new EvioException("Data type mismatch"); +// } +// } +// break; +// +// // 8 bits +// case 6: +// for (int j=0; j < ncnf; j++) { +// if (itemType != DataType.CHAR8) { +// throw new EvioException("Data type mismatch"); +// } +// } +// break; +// +// case 7: +// for (int j=0; j < ncnf; j++) { +// if (itemType != DataType.UCHAR8) { +// throw new EvioException("Data type mismatch"); +// } +// } +// break; +// +// // String array +// case 3: +// for (int j=0; j < ncnf; j++) { +// if (itemType != DataType.CHARSTAR8) { +// throw new EvioException("Data type mismatch"); +// } +// } +// break; +// +// default: +// } +// +// +// } +// + + } + + + /** + * This method helps the CompositeData object creator by + * finding the proper format string parameter for putting + * this array of Strings into its data. + * + * @param strings array of strings to eventually put into a + * CompositeData object. + * @return string representing its format to be used in the + * CompositeData object's format string + * @return null if arg is null or has 0 length + */ + public static String stringsToFormat(String[] strings) { + byte[] rawBuf = BaseStructure.stringsToRawBytes(strings); + if (rawBuf != null) { + return rawBuf.length + "a"; + } + + return null; + } + + + /** + * This method gets the raw data byte order. + * @return raw data byte order. + */ + public ByteOrder getByteOrder() { + return byteOrder; + } + + + /** + * This method gets the raw byte representation of this object's data. + * @return raw byte representation of this object's data. + */ + public byte[] getRawBytes() { + return rawBytes; + } +
/** * This method gets a list of all the data items inside the composite. * @return list of all the data items inside the composite.
@@ -410,7 +1139,7 @@
* 0 0 ')' * # 1 #'i' unsigned int * # 2 #'F' floating point
- * # 3 #'a' 8-bit char (C++)
+ * # 3 #'a' 8-bit ASCII char (C++)
* # 4 #'S' short * # 5 #'s' unsigned short * # 6 #'C' char
@@ -426,7 +1155,7 @@
* will be repeated until all data processed; if there are no parenthesis * in format, data processing will be started from the beginnig of the format * (FORTRAN agreement)
- * 2. The number of repeats '#' must be the number between 2 and 15; if the number
+ * 2. The number of repeats '#' must be a number between 2 and 15; if the number
* of repeats is symbol 'N' instead of the number, it will be taken from data * assuming 'int' format *
@@ -457,11 +1186,14 @@
if (ch == ' ') continue; if (debug) {
- System.out.println(ch);
+ System.out.println("ch = " + ch);
} // if char = digit, following before comma will be repeated 'number' times if (Character.isDigit(ch)) {
+ if (debug) { + System.out.println("the number of repeats before, nr = " + nr); + }
if (nr < 0) throw new EvioException("no negative repeats"); nr = 10*max(0,nr) + Character.digit(ch,10); if (nr > 15) throw new EvioException("no more than 15 repeats allowed");
@@ -624,7 +1356,7 @@
// Move to beginning of tagseg header int srcDataOffset = srcOff; int destDataOffset = destOff;
-
+ System.out.println("srcDataOffset = " + srcDataOffset + ", len (Bytes) = " + (4*length) + ", src array len = " + src.length);
ByteBuffer srcBuffer = ByteBuffer.wrap( src, srcDataOffset, 4*length); ByteBuffer destBuffer = ByteBuffer.wrap(dest, destDataOffset, 4*length);
@@ -637,8 +1369,8 @@
int headerLen = tsHeader.getHeaderLength(); int dataLength = tsHeader.getLength() - (headerLen - 1);
-System.out.println("theaderLen = "+headerLen+ ", theader.getLn() = " + - tsHeader.getLength()+ ", tdataLen = " + dataLength);
+//System.out.println("theaderLen = "+headerLen+ ", theader.getLn() = " + +// tsHeader.getLength()+ ", tdataLen = " + dataLength);
// Oops, no format data if (dataLength < 1) {
@@ -681,8 +1413,9 @@
headerLen = bHeader.getHeaderLength(); dataLength = bHeader.getLength() - (headerLen - 1);
-System.out.println("bheaderLen = "+headerLen+ ", bheader.getLn() = " + - bHeader.getLength()+ ", bdataLen = " + dataLength);
+//System.out.println("bheaderLen = "+headerLen+ ", bheader.getLn() = " + +// bHeader.getLength()+ ", bdataLen = " + dataLength); +
// Oops, no data if (dataLength < 1) { throw new EvioException("no data");
@@ -1045,6 +1778,292 @@
/**
+ * This method takes a list of data objects and a transformed format string + * and uses that to write data into a buffer/array in raw form. + * + * @param rawBuf data buffer in which to put the raw bytes + * @param data data to convert to raw bytes + * @param ifmt format list as produced by {@link #compositeFormatToInt(String)} + * + * @throws EvioException if nBytes or nfmt args < 0 ; if srcBuf or destBuf is too + * small + */ + public static void dataToRawBytes(ByteBuffer rawBuf, CompositeData.Data data, + List<Integer> ifmt) + throws EvioException { + + boolean debug = false; + int imt, ncnf, kcnf, lev, iterm; + + class LV { + int left; // index of ifmt[] element containing left parenthesis "(" + int nrepeat; // how many times format in parenthesis must be repeated + int irepeat; // right parenthesis ")" counter, or how many times format + // in parenthesis already repeated + }; + + // check args + if (ifmt == null || data == null || rawBuf == null) throw new EvioException("arg is null"); + + // size of format list + // TODO: bug, ifmt may be NULLLLLL in other METHODS ...... + int nfmt = ifmt.size(); + if (nfmt <= 0) throw new EvioException("empty format list"); + + LV[] lv = new LV[10]; + for (int i=0; i < lv.length; i++) { + lv[i] = new LV(); + } + + imt = 0; // ifmt[] index + ncnf = 0; // how many times must repeat a format + lev = 0; // parenthesis level + iterm = 0; + + ListIterator<Integer> nListIter = data.nList.listIterator(); + + int itemIndex = 0; + int itemCount = data.dataItems.size(); + + // write each item + for (itemIndex = 0; itemIndex < itemCount;) { + + // get next format code + while (true) { + imt++; + // end of format statement reached, back to iterm - last parenthesis or format begining + if (imt > nfmt) { + //imt = iterm; + imt = 0; + } + // meet right parenthesis, so we're finished processing format(s) in parenthesis + else if (ifmt.get(imt-1) == 0) { + // increment counter + lv[lev-1].irepeat++; + + // if format in parenthesis was processed the required number of times + if (lv[lev-1].irepeat >= lv[lev-1].nrepeat) { + // store left parenthesis index minus 1 + iterm = lv[lev-1].left - 1; + + // If end of format, will start from format index imt=iterm. + // By default we continue from the beginning of the format (iterm=0). + + // done with this level - decrease parenthesis level + lev--; + } + // go for another round of processing by setting 'imt' to the left parenthesis + else { + // points ifmt[] index to the left parenthesis from the same level 'lev' + imt = lv[lev-1].left; + } + } + else { + // how many times to repeat format code + ncnf = ifmt.get(imt-1)/16; + // format code + kcnf = ifmt.get(imt-1) - 16*ncnf; + + // left parenthesis, SPECIAL case: #repeats must be taken from data + if (kcnf == 15) { + // set it to regular left parenthesis code + kcnf = 0; + + // get "N" value from List + if (!nListIter.hasNext()) { + throw new EvioException("Not enough N values provided"); + } + ncnf = nListIter.next(); +if (debug) System.out.println("N 1 from list = " + ncnf); + + // put into buffer (relative put) + rawBuf.putInt(ncnf); + } + + // left parenthesis - set new lv[] + if (kcnf == 0) { + // store ifmt[] index + lv[lev].left = imt; + // how many time will repeat format code inside parenthesis + lv[lev].nrepeat = ncnf; + // cleanup place for the right parenthesis (do not get it yet) + lv[lev].irepeat = 0; + // increase parenthesis level + lev++; + } + // format F or I or ... + else { + // there are no parenthesis, just simple format, go to processing + if (lev == 0) { + } + // have parenthesis, NOT the pre-last format element (last assumed ')' ?) + else if (imt != (nfmt-1)) { + } + // have parenthesis, NOT the first format after the left parenthesis[truncated at 1000 lines; 1082 more skipped]
diff -u -r1.3 -r1.4 --- EvioFile.java 28 Feb 2012 19:41:36 -0000 1.3 +++ EvioFile.java 8 Mar 2012 20:39:26 -0000 1.4 @@ -28,6 +28,8 @@
* 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. *
+ * @deprecated Use the EvioReader class instead which can read both files and buffers. + *
* @author heddle * */
@@ -934,4 +936,4 @@
return true; }
-}^M
+}
\ No newline at end of file
diff -u -r1.1 -r1.2 --- EventTreePanel.java 28 Feb 2012 19:41:37 -0000 1.1 +++ EventTreePanel.java 8 Mar 2012 20:39:27 -0000 1.2 @@ -373,10 +373,12 @@
case COMPOSITE: try { CompositeData cData = structure.getCompositeData();
-// for (String str : stringdata) { -// String s = String.format("[%02d] %s\n", index++, str); -// textArea.append(s != null ? s : "null data\n"); -// }
+ if (cData != null) { + textArea.append(cData.toString(intsInHex)); + } + else { + textArea.append("null data\n"); + }
} catch (EvioException e) { // internal format error
diff -u -r1.1 -r1.2 --- CompositeTester.java 28 Feb 2012 19:41:37 -0000 1.1 +++ CompositeTester.java 8 Mar 2012 20:39:27 -0000 1.2 @@ -21,7 +21,7 @@
/** For testing only */
- public static void main(String args[]) {
+ public static void main0(String args[]) {
int[] bank = new int[24];
@@ -32,86 +32,6 @@
bank[0] = 23; // bank length bank[1] = 6 << 16 | 0xF << 8 | 3; // tag = 6, bank contains composite type, num = 3
- /* first part of composite type (for format) = tagseg (tag & type ignored, len used) */ - // tagseg[1] = 5 << 20 | 0x3 << 16 | 3; /* tag = 5, seg has char data, len = 2 */ - /* ASCII chars values in latest evio string (array) format, 2(2I,F) */ - // tagseg[2] = 0x49 << 24 | 0x32 << 16 | 0x28 << 8 | 0x32 ; /* I 2 ( 2 */ - // tagseg[3] = 0 << 24 | 0x29 << 16 | 0x46 << 8 | 0x2C ; /* \0 ) F , */ - // tagseg[4] = 4 << 24 | 4 << 16 | 4 << 8 | 4 ; /* \4 \4 \4 \4 */ - - /* second part of composite type (for data) = bank (tag, num, type ignored, len used) */ - /* - intWord = &(bank[20]); - intWord[0] = 7; - intWord[1] = 6 << 16 | 0xF << 8 | 1; - data = 123.456; - intWord[2] = 0x1111; - intWord[3] = 0x2222; - intWord[4] = *(int *)&data; - intWord[5] = 0x11111111; - intWord[6] = 0x22222222; - intWord[7] = *(int *)&data; - */ - - // first part of composite type (for format) = tagseg (tag & type ignored, len used) - // tagseg[1] = 5 << 20 | 0x3 << 16 | 3; /* tag = 5, seg has char data, len = 3 - // ASCII chars values in latest evio string (array) format, I,N(I,F) - // tagseg[2] = 0x28 << 24 | 0x4E << 16 | 0x2C << 8 | 0x49; // ( N , I - // tagseg[3] = 0x29 << 24 | 0x46 << 16 | 0x2C << 8 | 0x49; // ) F , I - // tagseg[4] = 4 << 24 | 4 << 16 | 4 << 8 | 0 ; // \4 \4 \4 \0 - - // second part of composite type (for data) = bank (tag, num, type ignored, len used) - /* - intWord = &(bank[20]); - intWord[0] = 7; - intWord[1] = 6 << 16 | 0xF << 8 | 1; - data = 123.456; - intWord[2] = 0x3333; - intWord[3] = 0x2; - intWord[4] = 0x1111; - intWord[5] = *(int *)&data; - intWord[6] = 0x2222; - intWord[7] = *(int *)&data; - */ - - /* - // first part of composite type (for format) = tagseg (tag & type ignored, len used) - bank[2] = 5 << 20 | 0x3 << 16 | 3; // tag = 5, seg has char data, len = 3 - // ASCII chars values in latest evio string (array) format, N(N(I,2S)) with N=2 - bank[3] = 0x28 << 24 | 0x4E << 16 | 0x28 << 8 | 0x4E; // ( N ( N - bank[4] = 0x53 << 24 | 0x32 << 16 | 0x2C << 8 | 0x49; // S 2 , I - bank[5] = 4 << 24 | 0 << 16 | 0x29 << 8 | 0x29 ; // \4 \0 ) ) - - // second part of composite type (for data) = bank (tag, num, type ignored, len used) - bank[6] = 12; - bank[7] = 6 << 16 | 0xF << 8 | 1; - bank[8] = 0x2; // N - bank[9] = 0x2; // N - bank[10] = 0x00001111; - bank[11] = 0x11223344; - bank[12] = 0x00002222; - bank[13] = 0x55667788; - - bank[14] = 0x2; // N - bank[15] = 0x00003333; - bank[16] = 0x00991188; - bank[17] = 0x00004444; - bank[18] = 0x22773366; - - int[] bankData = new int[11]; - bankData[0] = 0x2; // N - bankData[1] = 0x2; // N - bankData[2] = 0x00001111; - bankData[3] = 0x11223344; - bankData[4] = 0x00002222; - bankData[5] = 0x55667788; - - bankData[6] = 0x2; // N - bankData[7] = 0x00003333; - bankData[8] = 0x00991188; update - bankData[9] = 0x00004444; - bankData[10] = 0x22773366; - */
// N(I,D,F,2S,8a) // first part of composite type (for format) = tagseg (tag & type ignored, len used)
@@ -196,10 +116,6 @@
// System.out.println();
- - - -
// swap again System.out.println("Call CompositeData.swapAll()"); CompositeData.swapAll(byteArray, 0, null, 0, allData.length, ByteOrder.LITTLE_ENDIAN);
@@ -228,7 +144,7 @@
for (String s : strs) System.out.println("String = " + s); // use toString() method to print out
- System.out.println("\ntoXmlString =\n" + cData.toXMLString(" ", true));
+// System.out.println("\ntoXmlString =\n" + cData.toXMLString(" ", true));
} catch (EvioException e) {
@@ -237,9 +153,120 @@
}
- /** For testing only */
+ + /** + * Simple example of providing a format string and some data + * in order to create a CompositeData object. + */
public static void main1(String args[]) {
+ // Create a CompositeData object ... + + // Format to write an int and a string + // To get the right format code for the string, use a helper method + String myString = "string"; + String stringFormat = CompositeData.stringsToFormat(new String[] {myString}); + + // Put the 2 formats together + String format = "I," + stringFormat; + + System.out.println("format = " + format); + + // Now create some data + CompositeData.Data myData = new CompositeData.Data(); + myData.addInt(2); + myData.addString(myString); + + // Create CompositeData object + CompositeData cData = null; + try { + cData = new CompositeData(format, 1, myData, 0 ,0); + } + catch (EvioException e) { + e.printStackTrace(); + System.exit(-1); + } + + // Print it out + printCompositeDataObject(cData); + } + + + /** + * More complicated example of providing a format string and some data + * in order to create a CompositeData object. + */ + public static void main2(String args[]) { + + // Create a CompositeData object ... + + // Format to write a N shorts, 1 float, 1 double a total of N times + String format = "N(NS,F,D)"; + + System.out.println("format = " + format); + + // Now create some data + CompositeData.Data myData = new CompositeData.Data(); + myData.addN(2); + myData.addN(3); + myData.addShort(new short[] {1,2,3}); // use array for convenience + myData.addFloat(1.0F); + myData.addDouble(Math.PI); + myData.addN(1); + myData.addShort((short)4); // use array for convenience + myData.addFloat(2.0F); + myData.addDouble(2.*Math.PI); + + // Note: N's do not needed to be added in sync with the other data. + // In other words, one could do: + // myData.addN(2); + // myData.addN(3); + // myData.addN(1); + // myData.addShort(new short[] {1,2,3}); ... etc. + // + // or + // + // myData.addN(new int[] {2,3,1}); + // myData.addShort(new short[] {1,2,3}); ... etc. + // + + + // Create CompositeData object + CompositeData cData = null; + try { + cData = new CompositeData(format, 1, myData, 0 ,0); + } + catch (EvioException e) { + e.printStackTrace(); + System.exit(-1); + } + + // Print it out + printCompositeDataObject(cData); + + try { + EvioEvent ev = new EvioEvent(0, DataType.COMPOSITE, 0); + ev.appendCompositeData(cData); + + // Write it to this file + String fileName = "./composite.dat"; + + EventWriter writer = new EventWriter(fileName); + writer.writeEvent(ev); + writer.close(); + } + catch (Exception e) { + e.printStackTrace(); + } + + + } + + + + /** For testing only */ + public static void main(String args[]) { +
//create an event writer to write out the test events. String fileName = "/daqfs/home/timmer/coda/evio-4.0.sergey/Linux-x86_64/bin/sample.dat";
@@ -248,8 +275,10 @@
try { EvioReader evioReader = new EvioReader(fileName);
- EvioEvent ev = evioReader.parseNextEvent(); - System.out.println("EVENT:\n" + ev.toXML());
+ EvioEvent ev; + while ( (ev = evioReader.parseNextEvent()) != null) { + System.out.println("EVENT:\n" + ev.toXML()); + }
} catch (EvioException e) { e.printStackTrace();
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