*/
public void addCAS(CASImpl cas, OutputStream ostream, Marker trackingMark) {
try {
if (!trackingMark.isValid() ) {
CASRuntimeException exception = new CASRuntimeException(
CASRuntimeException.INVALID_MARKER, new String[] { "Invalid Marker." });
throw exception;
}
MarkerImpl mark = (MarkerImpl) trackingMark;
DataOutputStream dos = new DataOutputStream(ostream);
// get the indexed FSs
this.fsIndex = cas.getDeltaIndexedFSs(mark);
// output the key and version number
//1 = current full serialization; 2 = delta format
//perhaps this should be split into 2 bytes for version and 2 bytes for format.
outputVersion(2, dos);
// output the new FS heap cells
final int heapSize = cas.getHeap().getCellsUsed() - mark.nextFSId;
dos.writeInt(heapSize);
for (int i = mark.nextFSId; i < cas.getHeap().getCellsUsed(); i++) {
dos.writeInt(cas.getHeap().heap[i]);
}
// output the new strings
StringHeapDeserializationHelper shdh = cas.getStringHeap().serialize(mark.nextStringHeapAddr);
outputStringHeap(dos, cas, shdh);
// // compute the number of total size of data in stringHeap
// // total size = char buffer length + length of strings in the string list;
// int stringHeapLength = shdh.charHeapPos;
// int stringListLength = 0;
// for (int i = 0; i < shdh.refHeap.length; i += 3) {
// int ref = shdh.refHeap[i + StringHeapDeserializationHelper.STRING_LIST_ADDR_OFFSET];
// // this is a string in the string list
// // get length and add to total string heap length
// if (ref != 0) {
// // terminate each string with a null
// stringListLength += 1 + cas.getStringHeap().getStringForCode(ref).length();
// }
// }
//
// int stringTotalLength = stringHeapLength + stringListLength;
// if (stringHeapLength == 0 && stringListLength > 0) {
// // nothing from stringHeap
// // add 1 for the null at the beginning
// stringTotalLength += 1;
// }
// dos.writeInt(stringTotalLength);
//
// // write the data in the stringheap, if there is any
// if (stringTotalLength > 0) {
// if (shdh.charHeapPos > 0) {
// dos.writeChars(String.valueOf(shdh.charHeap, 0, shdh.charHeapPos));
// } else {
// // no stringheap data
// // if there is data in the string lists, write a leading 0
// if (stringListLength > 0) {
// dos.writeChar(0);
// }
// }
//
// // word alignment
// if (stringTotalLength % 2 != 0) {
// dos.writeChar(0);
// }
// }
//
// // write out the string ref heap
// // each reference consist of a offset into stringheap and a length
// int refheapsz = ((shdh.refHeap.length - StringHeapDeserializationHelper.FIRST_CELL_REF) / StringHeapDeserializationHelper.REF_HEAP_CELL_SIZE) * 2;
// refheapsz++;
// dos.writeInt(refheapsz);
// dos.writeInt(0);
// for (int i = StringHeapDeserializationHelper.FIRST_CELL_REF; i < shdh.refHeap.length; i += 3) {
// dos.writeInt(shdh.refHeap[i + StringHeapDeserializationHelper.CHAR_HEAP_POINTER_OFFSET]);
// dos.writeInt(shdh.refHeap[i + StringHeapDeserializationHelper.CHAR_HEAP_STRLEN_OFFSET]);
// }
//output modified FS Heap cells
int[] fsHeapModifiedAddrs = cas.getModifiedFSHeapAddrs().toArray();
dos.writeInt(fsHeapModifiedAddrs.length); //num modified
for (int i=0; i < fsHeapModifiedAddrs.length; i++) {
dos.writeInt(fsHeapModifiedAddrs[i]);
dos.writeInt(cas.getHeapValue(fsHeapModifiedAddrs[i]));
}
// output the index FSs
dos.writeInt(this.fsIndex.length);
for (int i = 0; i < this.fsIndex.length; i++) {
dos.writeInt(this.fsIndex[i]);
}
// 8bit heap new
int byteheapsz = cas.getByteHeap().getSize() - mark.nextByteHeapAddr;
dos.writeInt(byteheapsz);
for (int i = mark.nextByteHeapAddr; i < cas.getByteHeap().getSize(); i++) {
dos.writeByte(cas.getByteHeap().heap[i]);
}
// word alignment
int align = (4 - (byteheapsz % 4)) % 4;
for (int i = 0; i < align; i++) {
dos.writeByte(0);
}
// 16bit heap new
int shortheapsz = cas.getShortHeap().getSize() - mark.nextShortHeapAddr;
dos.writeInt(shortheapsz);
for (int i = mark.nextShortHeapAddr; i < cas.getShortHeap().getSize(); i++) {
dos.writeShort(cas.getShortHeap().heap[i]);
}
// word alignment
if (shortheapsz % 2 != 0) {
dos.writeShort(0);
}
// 64bit heap new
int longheapsz = cas.getLongHeap().getSize() - mark.nextLongHeapAddr;
dos.writeInt(longheapsz);
for (int i = mark.nextLongHeapAddr; i < cas.getLongHeap().getSize(); i++) {
dos.writeLong(cas.getLongHeap().heap[i]);
}
// 8 bit heap modified cells
int[] byteHeapModifiedAddrs = cas.getModifiedByteHeapAddrs().toArray();
// byte[] byteValues = new byte[byteHeapModifiedAddrs.length];
dos.writeInt(byteHeapModifiedAddrs.length);
for (int i=0; i < byteHeapModifiedAddrs.length; i++) {
dos.writeInt(byteHeapModifiedAddrs[i]);
// byteValues[i] = cas.getByteHeap().getHeapValue(byteHeapModifiedAddrs[i]);
}
for (int i=0; i < byteHeapModifiedAddrs.length; i++) {
dos.writeByte(cas.getByteHeap().getHeapValue(byteHeapModifiedAddrs[i]));
}
// word alignment
align = (4 - (byteheapsz % 4)) % 4;
for (int i = 0; i < align; i++) {
dos.writeByte(0);
}
// 16 bit heap modified cells
int[] shortHeapModifiedAddrs = cas.getModifiedShortHeapAddrs().toArray();
short[] shortValues = new short[shortHeapModifiedAddrs.length];
dos.writeInt(shortHeapModifiedAddrs.length);
for (int i=0; i < shortHeapModifiedAddrs.length; i++) {
dos.writeShort(shortHeapModifiedAddrs[i]);
shortValues[i] = cas.getShortHeap().getHeapValue(shortHeapModifiedAddrs[i]);
}
for (int i=0; i < shortValues.length; i++) {
dos.writeShort(cas.getShortHeap().getHeapValue(shortHeapModifiedAddrs[i]));
}
// word alignment
if (shortheapsz % 2 != 0) {
dos.writeShort(0);
}
// 64 bit heap modified cells
int[] longHeapModifiedAddrs = cas.getModifiedShortHeapAddrs().toArray();
long[] longValues = new long[longHeapModifiedAddrs.length];
dos.writeInt(longHeapModifiedAddrs.length);
for (int i=0; i < longHeapModifiedAddrs.length; i++) {
dos.writeShort(longHeapModifiedAddrs[i]);
longValues[i] = cas.getLongHeap().getHeapValue(longHeapModifiedAddrs[i]);
}
for (int i=0; i < longValues.length; i++) {
dos.writeLong(cas.getLongHeap().getHeapValue(longHeapModifiedAddrs[i]));
}
} catch (IOException e) {
CASRuntimeException exception = new CASRuntimeException(
CASRuntimeException.BLOB_SERIALIZATION, new String[] { e.getMessage() });
throw exception;
}
}