5 modified files
jevio-base/src/main/java/org/jlab/coda/jevio
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();
+ }
+
}
jevio-base/src/main/java/org/jlab/coda/jevio
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]
jevio-base/src/main/java/org/jlab/coda/jevio
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
jevio-base/src/main/java/org/jlab/coda/jevio/graphics
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
jevio-base/src/main/java/org/jlab/coda/jevio/test
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();
CVSspam 0.2.12