use of org.apache.poi.ddf.EscherRecord in project poi by apache.
the class EscherAggregate method serialize.
/**
* Serializes this aggregate to a byte array. Since this is an aggregate
* record it will effectively serialize the aggregated records.
*
* @param offset The offset into the start of the array.
* @param data The byte array to serialize to.
* @return The number of bytes serialized.
*/
public int serialize(int offset, byte[] data) {
// Determine buffer size
List<EscherRecord> records = getEscherRecords();
int size = getEscherRecordSize(records);
byte[] buffer = new byte[size];
// Serialize escher records into one big data structure and keep note of ending offsets.
final List<Integer> spEndingOffsets = new ArrayList<Integer>();
final List<EscherRecord> shapes = new ArrayList<EscherRecord>();
int pos = 0;
for (Object record : records) {
EscherRecord e = (EscherRecord) record;
pos += e.serialize(pos, buffer, new EscherSerializationListener() {
public void beforeRecordSerialize(int offset, short recordId, EscherRecord record) {
}
public void afterRecordSerialize(int offset, short recordId, int size, EscherRecord record) {
if (recordId == EscherClientDataRecord.RECORD_ID || recordId == EscherTextboxRecord.RECORD_ID) {
spEndingOffsets.add(offset);
shapes.add(record);
}
}
});
}
shapes.add(0, null);
spEndingOffsets.add(0, 0);
// Split escher records into separate MSODRAWING and OBJ, TXO records. (We don't break on
// the first one because it's the patriach).
pos = offset;
int writtenEscherBytes = 0;
int i;
for (i = 1; i < shapes.size(); i++) {
int endOffset = spEndingOffsets.get(i) - 1;
int startOffset;
if (i == 1)
startOffset = 0;
else
startOffset = spEndingOffsets.get(i - 1);
byte[] drawingData = new byte[endOffset - startOffset + 1];
System.arraycopy(buffer, startOffset, drawingData, 0, drawingData.length);
pos += writeDataIntoDrawingRecord(drawingData, writtenEscherBytes, pos, data, i);
writtenEscherBytes += drawingData.length;
// Write the matching OBJ record
Record obj = shapeToObj.get(shapes.get(i));
pos += obj.serialize(pos, data);
if (i == shapes.size() - 1 && endOffset < buffer.length - 1) {
drawingData = new byte[buffer.length - endOffset - 1];
System.arraycopy(buffer, endOffset + 1, drawingData, 0, drawingData.length);
pos += writeDataIntoDrawingRecord(drawingData, writtenEscherBytes, pos, data, i);
}
}
if ((pos - offset) < buffer.length - 1) {
byte[] drawingData = new byte[buffer.length - (pos - offset)];
System.arraycopy(buffer, (pos - offset), drawingData, 0, drawingData.length);
pos += writeDataIntoDrawingRecord(drawingData, writtenEscherBytes, pos, data, i);
}
for (NoteRecord noteRecord : tailRec.values()) {
Record rec = (Record) noteRecord;
pos += rec.serialize(pos, data);
}
int bytesWritten = pos - offset;
if (bytesWritten != getRecordSize())
throw new RecordFormatException(bytesWritten + " bytes written but getRecordSize() reports " + getRecordSize());
return bytesWritten;
}
use of org.apache.poi.ddf.EscherRecord in project poi by apache.
the class EscherAggregate method getRecordSize.
/**
* @return record size, including header size of obj, text, note, drawing, continue records
*/
public int getRecordSize() {
// To determine size of aggregate record we have to know size of each DrawingRecord because if DrawingRecord
// is split into several continue records we have to add header size to total EscherAggregate size
int continueRecordsHeadersSize = 0;
// Determine buffer size
List<EscherRecord> records = getEscherRecords();
int rawEscherSize = getEscherRecordSize(records);
byte[] buffer = new byte[rawEscherSize];
final List<Integer> spEndingOffsets = new ArrayList<Integer>();
int pos = 0;
for (EscherRecord e : records) {
pos += e.serialize(pos, buffer, new EscherSerializationListener() {
public void beforeRecordSerialize(int offset, short recordId, EscherRecord record) {
}
public void afterRecordSerialize(int offset, short recordId, int size, EscherRecord record) {
if (recordId == EscherClientDataRecord.RECORD_ID || recordId == EscherTextboxRecord.RECORD_ID) {
spEndingOffsets.add(offset);
}
}
});
}
spEndingOffsets.add(0, 0);
for (int i = 1; i < spEndingOffsets.size(); i++) {
if (i == spEndingOffsets.size() - 1 && spEndingOffsets.get(i) < pos) {
continueRecordsHeadersSize += 4;
}
if (spEndingOffsets.get(i) - spEndingOffsets.get(i - 1) <= RecordInputStream.MAX_RECORD_DATA_SIZE) {
continue;
}
continueRecordsHeadersSize += ((spEndingOffsets.get(i) - spEndingOffsets.get(i - 1)) / RecordInputStream.MAX_RECORD_DATA_SIZE) * 4;
}
int drawingRecordSize = rawEscherSize + (shapeToObj.size()) * 4;
if (rawEscherSize != 0 && spEndingOffsets.size() == 1) /**EMPTY**/
{
continueRecordsHeadersSize += 4;
}
int objRecordSize = 0;
for (Record r : shapeToObj.values()) {
objRecordSize += r.getRecordSize();
}
int tailRecordSize = 0;
for (NoteRecord noteRecord : tailRec.values()) {
tailRecordSize += noteRecord.getRecordSize();
}
return drawingRecordSize + objRecordSize + tailRecordSize + continueRecordsHeadersSize;
}
use of org.apache.poi.ddf.EscherRecord in project poi by apache.
the class AbstractEscherHolderRecord method convertToEscherRecords.
private void convertToEscherRecords(int offset, int size, byte[] data) {
escherRecords.clear();
EscherRecordFactory recordFactory = new DefaultEscherRecordFactory();
int pos = offset;
while (pos < offset + size) {
EscherRecord r = recordFactory.createRecord(data, pos);
int bytesRead = r.fillFields(data, pos, recordFactory);
escherRecords.add(r);
pos += bytesRead;
}
}
use of org.apache.poi.ddf.EscherRecord in project poi by apache.
the class DrawingGroupRecord method serialize.
public int serialize(int offset, byte[] data) {
byte[] rawData = getRawData();
if (getEscherRecords().size() == 0 && rawData != null) {
return writeData(offset, data, rawData);
}
byte[] buffer = new byte[getRawDataSize()];
int pos = 0;
for (Iterator<EscherRecord> iterator = getEscherRecords().iterator(); iterator.hasNext(); ) {
EscherRecord r = iterator.next();
pos += r.serialize(pos, buffer, new NullEscherSerializationListener());
}
return writeData(offset, data, buffer);
}
use of org.apache.poi.ddf.EscherRecord in project poi by apache.
the class HPBFDumper method dumpEscherStream.
private void dumpEscherStream(byte[] data) {
DefaultEscherRecordFactory erf = new DefaultEscherRecordFactory();
// Dump
int left = data.length;
while (left > 0) {
EscherRecord er = erf.createRecord(data, 0);
er.fillFields(data, 0, erf);
left -= er.getRecordSize();
System.out.println(er);
}
}
Aggregations