use of org.apache.poi.ddf.DefaultEscherRecordFactory 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);
}
}
use of org.apache.poi.ddf.DefaultEscherRecordFactory in project poi by apache.
the class EscherAggregate method createAggregate.
/**
* Collapses the drawing records into an aggregate.
* read Drawing, Obj, TxtObj, Note and Continue records into single byte array,
* create Escher tree from byte array, create map <EscherRecord, Record>
*
* @param records - list of all records inside sheet
* @param locFirstDrawingRecord - location of the first DrawingRecord inside sheet
* @return new EscherAggregate create from all aggregated records which belong to drawing layer
*/
public static EscherAggregate createAggregate(List<RecordBase> records, int locFirstDrawingRecord) {
// Keep track of any shape records created so we can match them back to the object id's.
// Textbox objects are also treated as shape objects.
final List<EscherRecord> shapeRecords = new ArrayList<EscherRecord>();
EscherRecordFactory recordFactory = new DefaultEscherRecordFactory() {
public EscherRecord createRecord(byte[] data, int offset) {
EscherRecord r = super.createRecord(data, offset);
if (r.getRecordId() == EscherClientDataRecord.RECORD_ID || r.getRecordId() == EscherTextboxRecord.RECORD_ID) {
shapeRecords.add(r);
}
return r;
}
};
// Create one big buffer
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
EscherAggregate agg = new EscherAggregate(false);
int loc = locFirstDrawingRecord;
while (loc + 1 < records.size() && (isDrawingLayerRecord(sid(records, loc)))) {
try {
if (!(sid(records, loc) == DrawingRecord.sid || sid(records, loc) == ContinueRecord.sid)) {
loc++;
continue;
}
if (sid(records, loc) == DrawingRecord.sid) {
buffer.write(((DrawingRecord) records.get(loc)).getRecordData());
} else {
buffer.write(((ContinueRecord) records.get(loc)).getData());
}
} catch (IOException e) {
throw new RuntimeException("Couldn't get data from drawing/continue records", e);
}
loc++;
}
// Decode the shapes
// agg.escherRecords = new ArrayList();
int pos = 0;
while (pos < buffer.size()) {
EscherRecord r = recordFactory.createRecord(buffer.toByteArray(), pos);
int bytesRead = r.fillFields(buffer.toByteArray(), pos, recordFactory);
agg.addEscherRecord(r);
pos += bytesRead;
}
// Associate the object records with the shapes
loc = locFirstDrawingRecord + 1;
int shapeIndex = 0;
while (loc < records.size() && (isDrawingLayerRecord(sid(records, loc)))) {
if (!isObjectRecord(records, loc)) {
loc++;
continue;
}
Record objRecord = (Record) records.get(loc);
agg.shapeToObj.put(shapeRecords.get(shapeIndex++), objRecord);
loc++;
}
// any NoteRecords that follow the drawing block must be aggregated and and saved in the tailRec collection
while (loc < records.size()) {
if (sid(records, loc) == NoteRecord.sid) {
NoteRecord r = (NoteRecord) records.get(loc);
agg.tailRec.put(r.getShapeId(), r);
} else {
break;
}
loc++;
}
int locLastDrawingRecord = loc;
// replace drawing block with the created EscherAggregate
records.subList(locFirstDrawingRecord, locLastDrawingRecord).clear();
records.add(locFirstDrawingRecord, agg);
return agg;
}
use of org.apache.poi.ddf.DefaultEscherRecordFactory in project poi by apache.
the class EscherRecordHolder method fillEscherRecords.
private void fillEscherRecords(byte[] data, int offset, int size) {
EscherRecordFactory recordFactory = new DefaultEscherRecordFactory();
int pos = offset;
while (pos < offset + size) {
EscherRecord r = recordFactory.createRecord(data, pos);
escherRecords.add(r);
int bytesRead = r.fillFields(data, pos, recordFactory);
// There is an empty byte between each top-level record in a Word doc
pos += bytesRead + 1;
}
}
use of org.apache.poi.ddf.DefaultEscherRecordFactory in project poi by apache.
the class PicturesTable method searchForPictures.
/**
* Performs a recursive search for pictures in the given list of escher records.
*
* @param escherRecords the escher records.
* @param pictures the list to populate with the pictures.
*/
private void searchForPictures(List<EscherRecord> escherRecords, List<Picture> pictures) {
for (EscherRecord escherRecord : escherRecords) {
if (escherRecord instanceof EscherBSERecord) {
EscherBSERecord bse = (EscherBSERecord) escherRecord;
EscherBlipRecord blip = bse.getBlipRecord();
if (blip != null) {
pictures.add(new Picture(blip));
} else if (bse.getOffset() > 0) {
try {
// Blip stored in delay stream, which in a word doc, is
// the main stream
EscherRecordFactory recordFactory = new DefaultEscherRecordFactory();
EscherRecord record = recordFactory.createRecord(_mainStream, bse.getOffset());
if (record instanceof EscherBlipRecord) {
record.fillFields(_mainStream, bse.getOffset(), recordFactory);
blip = (EscherBlipRecord) record;
pictures.add(new Picture(blip));
}
} catch (Exception exc) {
logger.log(POILogger.WARN, "Unable to load picture from BLIB record at offset #", Integer.valueOf(bse.getOffset()), exc);
}
}
}
// Recursive call.
searchForPictures(escherRecord.getChildRecords(), pictures);
}
}
use of org.apache.poi.ddf.DefaultEscherRecordFactory in project poi by apache.
the class TestDrawingAggregate method testIncompleteData.
/**
* when reading incomplete data ensure that the serialized bytes match the source
*/
@Test
public void testIncompleteData() throws IOException {
//EscherDgContainer and EscherSpgrContainer length exceeds the actual length of the data
String data = "H4sIAAAAAAAAAGWOOw7CQAxE32YTsSRIWSgQJSUloqSm5g4ICURBg+iBK3APGi6wBWeh9xGYbEps2WON" + "P+OWwpYeIsECMFC8S2jxNvMdlrYQ5xha5N8K6ryHdir6+avwOer5l3hq2NPYWuWN0n1dIsgfbgshuSj1" + "+2eqbvLdxQ0ndhy5KJ/lc1ZZK9okY5X/gSbrHZTH1vE/ozagTcwAAAA=";
byte[] dgBytes = decompress(data);
List<EscherRecord> records = new ArrayList<EscherRecord>();
EscherRecordFactory recordFactory = new DefaultEscherRecordFactory();
int pos = 0;
while (pos < dgBytes.length) {
EscherRecord r = recordFactory.createRecord(dgBytes, pos);
int bytesRead = r.fillFields(dgBytes, pos, recordFactory);
records.add(r);
pos += bytesRead;
}
assertEquals("data was not fully read", dgBytes.length, pos);
// serialize to byte array
ByteArrayOutputStream out = new ByteArrayOutputStream();
for (EscherRecord r : records) {
out.write(r.serialize());
}
assertEquals(HexDump.toHex(dgBytes, 10), HexDump.toHex(out.toByteArray(), 10));
}
Aggregations