mirror of https://github.com/apache/poi.git
patch from bug #45844: Addtional diagnostics for SlideShowRecordDumper
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@697520 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
105aed722f
commit
d0821af510
|
@ -37,6 +37,10 @@
|
|||
|
||||
<!-- Don't forget to update status.xml too! -->
|
||||
<release version="3.2-alpha1" date="2008-??-??">
|
||||
<action dev="POI-DEVELOPERS" type="add">45844 - Addtional diagnostics for HSLF SlideShowRecordDumper</action>
|
||||
<action dev="POI-DEVELOPERS" type="fix">45829 - HSSFPicture.getImageDimension() failed when DPI of image is zero</action>
|
||||
<action dev="POI-DEVELOPERS" type="fix">45815 - Bit mask values in StyleTextPropAtom were not preserved across read-write</action>
|
||||
<action dev="POI-DEVELOPERS" type="add">45814 - Specify RecordType for slide show Handout (4041)</action>
|
||||
<action dev="POI-DEVELOPERS" type="fix">45805 - Fixed 16-bit signed/unsigned bug in HSSFSheet.getColWidth etc</action>
|
||||
<action dev="POI-DEVELOPERS" type="fix">45780 - Fixed HSSFSheet.shiftRows to also update Area refs</action>
|
||||
<action dev="POI-DEVELOPERS" type="fix">45804 - Update HSMF to handle Outlook 3.0 msg files, which have a different string chunk type</action>
|
||||
|
|
|
@ -34,6 +34,10 @@
|
|||
<!-- Don't forget to update changes.xml too! -->
|
||||
<changes>
|
||||
<release version="3.2-alpha1" date="2008-??-??">
|
||||
<action dev="POI-DEVELOPERS" type="add">45844 - Addtional diagnostics for HSLF SlideShowRecordDumper</action>
|
||||
<action dev="POI-DEVELOPERS" type="fix">45829 - HSSFPicture.getImageDimension() failed when DPI of image is zero</action>
|
||||
<action dev="POI-DEVELOPERS" type="fix">45815 - Bit mask values in StyleTextPropAtom were not preserved across read-write</action>
|
||||
<action dev="POI-DEVELOPERS" type="add">45814 - Specify RecordType for slide show Handout (4041)</action>
|
||||
<action dev="POI-DEVELOPERS" type="fix">45805 - Fixed 16-bit signed/unsigned bug in HSSFSheet.getColWidth etc</action>
|
||||
<action dev="POI-DEVELOPERS" type="fix">45780 - Fixed HSSFSheet.shiftRows to also update Area refs</action>
|
||||
<action dev="POI-DEVELOPERS" type="fix">45804 - Update HSMF to handle Outlook 3.0 msg files, which have a different string chunk type</action>
|
||||
|
|
|
@ -20,8 +20,20 @@ package org.apache.poi.hslf.dev;
|
|||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.apache.poi.hslf.HSLFSlideShow;
|
||||
import org.apache.poi.hslf.record.Record;
|
||||
import org.apache.poi.util.HexDump;
|
||||
import org.apache.poi.ddf.DefaultEscherRecordFactory;
|
||||
import org.apache.poi.ddf.EscherRecord;
|
||||
import org.apache.poi.ddf.EscherContainerRecord;
|
||||
import org.apache.poi.ddf.EscherTextboxRecord;
|
||||
import org.apache.poi.hslf.record.EscherTextboxWrapper;
|
||||
import org.apache.poi.hslf.record.TextCharsAtom;
|
||||
import org.apache.poi.hslf.record.TextBytesAtom;
|
||||
import org.apache.poi.hslf.record.StyleTextPropAtom;
|
||||
import org.apache.poi.hslf.record.Record;
|
||||
|
||||
/**
|
||||
* This class provides a way to view the contents of a powerpoint file.
|
||||
|
@ -31,6 +43,8 @@ import org.apache.poi.hslf.record.Record;
|
|||
* @author Nick Burch
|
||||
*/
|
||||
public final class SlideShowRecordDumper {
|
||||
private boolean optVerbose;
|
||||
private boolean optEscher;
|
||||
private HSLFSlideShow doc;
|
||||
|
||||
/**
|
||||
|
@ -39,18 +53,45 @@ public final class SlideShowRecordDumper {
|
|||
*/
|
||||
public static void main(String args[]) throws IOException
|
||||
{
|
||||
if(args.length == 0) {
|
||||
System.err.println("Useage: SlideShowRecordDumper <filename>");
|
||||
String filename = "";
|
||||
boolean verbose = false;
|
||||
boolean escher = false;
|
||||
|
||||
int ndx=0;
|
||||
for (; ndx<args.length; ndx++) {
|
||||
if (!args[ndx].substring(0,1).equals("-"))
|
||||
break;
|
||||
|
||||
if (args[ndx].equals("-escher")) {
|
||||
escher = true;
|
||||
} else if (args[ndx].equals("-verbose")) {
|
||||
verbose = true;
|
||||
} else {
|
||||
printUsage();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// parsed any options, expect exactly one remaining arg (filename)
|
||||
if (ndx != args.length-1) {
|
||||
printUsage();
|
||||
return;
|
||||
}
|
||||
|
||||
String filename = args[0];
|
||||
filename = args[ndx];
|
||||
|
||||
SlideShowRecordDumper foo = new SlideShowRecordDumper(filename);
|
||||
SlideShowRecordDumper foo = new SlideShowRecordDumper(filename, verbose, escher);
|
||||
|
||||
foo.printDump();
|
||||
}
|
||||
|
||||
public static void printUsage() {
|
||||
System.err.println("Usage: SlideShowRecordDumper [-escher] [-verbose] <filename>");
|
||||
System.err.println("Valid Options:");
|
||||
System.err.println("-escher\t\t: dump contents of escher records");
|
||||
System.err.println("-verbose\t: dump binary contents of each record");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a Powerpoint dump from fileName. Parses the document
|
||||
|
@ -59,8 +100,10 @@ public final class SlideShowRecordDumper {
|
|||
* @param fileName The name of the file to read.
|
||||
* @throws IOException if there is a problem while parsing the document.
|
||||
*/
|
||||
public SlideShowRecordDumper(String fileName) throws IOException
|
||||
public SlideShowRecordDumper(String fileName, boolean verbose, boolean escher) throws IOException
|
||||
{
|
||||
optVerbose = verbose;
|
||||
optEscher = escher;
|
||||
doc = new HSLFSlideShow(fileName);
|
||||
}
|
||||
|
||||
|
@ -95,12 +138,96 @@ public final class SlideShowRecordDumper {
|
|||
}
|
||||
|
||||
public int getDiskLen(Record r) throws IOException {
|
||||
if (r == null) return 0;
|
||||
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
r.writeOut(baos);
|
||||
byte[] b = baos.toByteArray();
|
||||
return b.length;
|
||||
}
|
||||
|
||||
public String getPrintableRecordContents(Record r) throws IOException {
|
||||
if (r==null) return "<<null>>";
|
||||
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
r.writeOut(baos);
|
||||
byte[] b = baos.toByteArray();
|
||||
return HexDump.dump(b, 0, 0);
|
||||
}
|
||||
|
||||
public String printEscherRecord( EscherRecord er ) {
|
||||
String nl = System.getProperty( "line.separator" );
|
||||
StringBuffer buf = new StringBuffer();
|
||||
|
||||
if (er instanceof EscherContainerRecord) {
|
||||
buf.append(printEscherContainerRecord( (EscherContainerRecord)er ));
|
||||
} else if (er instanceof EscherTextboxRecord) {
|
||||
buf.append("EscherTextboxRecord:" + nl);
|
||||
|
||||
EscherTextboxWrapper etw = new EscherTextboxWrapper((EscherTextboxRecord)er);
|
||||
Record children[] = etw.getChildRecords();
|
||||
for (int j=0; j<children.length; j++) {
|
||||
if (children[j] instanceof StyleTextPropAtom) {
|
||||
|
||||
// need preceding Text[Chars|Bytes]Atom to initialize the data structure
|
||||
if (j > 0 && (children[j-1] instanceof TextCharsAtom ||
|
||||
children[j-1] instanceof TextBytesAtom)) {
|
||||
|
||||
int size = (children[j-1] instanceof TextCharsAtom) ?
|
||||
((TextCharsAtom)children[j-1]).getText().length() :
|
||||
((TextBytesAtom)children[j-1]).getText().length();
|
||||
|
||||
StyleTextPropAtom tsp = (StyleTextPropAtom)children[j];
|
||||
tsp.setParentTextSize(size);
|
||||
|
||||
} else {
|
||||
buf.append("Error! Couldn't find preceding TextAtom for style\n");
|
||||
}
|
||||
|
||||
buf.append(children[j].toString() + nl );
|
||||
} else {
|
||||
buf.append(children[j].toString() + nl );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
buf.append( er.toString() );
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public String printEscherContainerRecord( EscherContainerRecord ecr ) {
|
||||
String indent = "";
|
||||
|
||||
String nl = System.getProperty( "line.separator" );
|
||||
|
||||
StringBuffer children = new StringBuffer();
|
||||
if ( ecr.getChildRecords().size() > 0 )
|
||||
{
|
||||
children.append( " children: " + nl );
|
||||
|
||||
int count = 0;
|
||||
for ( Iterator iterator = ecr.getChildRecords().iterator(); iterator.hasNext(); )
|
||||
{
|
||||
String newIndent = " ";
|
||||
|
||||
EscherRecord record = (EscherRecord) iterator.next();
|
||||
children.append(newIndent + "Child " + count + ":" + nl);
|
||||
|
||||
children.append( printEscherRecord(record) );
|
||||
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
indent + ecr.getClass().getName() + " (" + ecr.getRecordName() + "):" + nl +
|
||||
indent + " isContainer: " + ecr.isContainerRecord() + nl +
|
||||
indent + " options: 0x" + HexDump.toHex( ecr.getOptions() ) + nl +
|
||||
indent + " recordId: 0x" + HexDump.toHex( ecr.getRecordId() ) + nl +
|
||||
indent + " numchildren: " + ecr.getChildRecords().size() + nl +
|
||||
indent + children.toString();
|
||||
}
|
||||
|
||||
|
||||
public void walkTree(int depth, int pos, Record[] records) throws IOException {
|
||||
int indent = depth;
|
||||
|
@ -109,6 +236,11 @@ public final class SlideShowRecordDumper {
|
|||
|
||||
for(int i=0; i<records.length; i++) {
|
||||
Record r = records[i];
|
||||
if (r == null) {
|
||||
System.out.println(ind + "At position " + pos + " (" + makeHex(pos,6) + "):");
|
||||
System.out.println(ind + "Warning! Null record found.");
|
||||
continue;
|
||||
}
|
||||
|
||||
// Figure out how big it is
|
||||
int len = getDiskLen(r);
|
||||
|
@ -132,6 +264,25 @@ public final class SlideShowRecordDumper {
|
|||
System.out.println(ind + " Record is of type " + cname);
|
||||
System.out.println(ind + " Type is " + r.getRecordType() + " (" + hexType + " -> " + rHexType + " )");
|
||||
System.out.println(ind + " Len is " + (len-8) + " (" + makeHex((len-8),8) + "), on disk len is " + len );
|
||||
|
||||
// print additional information for drawings and atoms
|
||||
if (optEscher && cname.equals("PPDrawing")) {
|
||||
DefaultEscherRecordFactory factory = new DefaultEscherRecordFactory();
|
||||
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
r.writeOut(baos);
|
||||
byte[] b = baos.toByteArray();
|
||||
|
||||
EscherRecord er = factory.createRecord(b, 0);
|
||||
er.fillFields(b, 0, factory);
|
||||
|
||||
System.out.println( printEscherRecord( er ) );
|
||||
|
||||
} else if(optVerbose && r.getChildRecords() == null) {
|
||||
String recData = getPrintableRecordContents(r);
|
||||
System.out.println(ind + recData );
|
||||
}
|
||||
|
||||
System.out.println();
|
||||
|
||||
// If it has children, show them
|
||||
|
|
|
@ -36,6 +36,8 @@ public class TextPropCollection {
|
|||
private LinkedList textPropList;
|
||||
private int maskSpecial = 0;
|
||||
|
||||
public int getSpecialMask() { return maskSpecial; }
|
||||
|
||||
/** Fetch the number of characters this styling applies to */
|
||||
public int getCharactersCovered() { return charactersCovered; }
|
||||
/** Fetch the TextProps that define this styling */
|
||||
|
|
|
@ -32,6 +32,7 @@ import org.apache.poi.hslf.model.textproperties.TextProp;
|
|||
import org.apache.poi.hslf.model.textproperties.TextPropCollection;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
import org.apache.poi.util.POILogger;
|
||||
import org.apache.poi.util.HexDump;
|
||||
|
||||
/**
|
||||
* A StyleTextPropAtom (type 4001). Holds basic character properties
|
||||
|
@ -417,25 +418,62 @@ public class StyleTextPropAtom extends RecordAtom
|
|||
*/
|
||||
public String toString(){
|
||||
StringBuffer out = new StringBuffer();
|
||||
|
||||
out.append("StyleTextPropAtom:\n");
|
||||
if (!initialised) {
|
||||
out.append("Uninitialised, dumping Raw Style Data\n");
|
||||
} else {
|
||||
|
||||
out.append("Paragraph properties\n");
|
||||
|
||||
for (Iterator it1 = getParagraphStyles().iterator(); it1.hasNext();) {
|
||||
TextPropCollection pr = (TextPropCollection)it1.next();
|
||||
out.append(" chars covered: " + pr.getCharactersCovered() + "\n");
|
||||
out.append(" chars covered: " + pr.getCharactersCovered());
|
||||
out.append(" special mask flags: 0x" + HexDump.toHex(pr.getSpecialMask()) + "\n");
|
||||
for (Iterator it2 = pr.getTextPropList().iterator(); it2.hasNext(); ) {
|
||||
TextProp p = (TextProp)it2.next();
|
||||
out.append(" " + p.getName() + " = " + p.getValue() + "\n");
|
||||
out.append(" " + p.getName() + " = " + p.getValue() );
|
||||
out.append(" (0x" + HexDump.toHex(p.getValue()) + ")\n");
|
||||
}
|
||||
|
||||
out.append(" para bytes that would be written: \n");
|
||||
|
||||
try {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
pr.writeOut(baos);
|
||||
byte[] b = baos.toByteArray();
|
||||
out.append(HexDump.dump(b, 0, 0));
|
||||
} catch (Exception e ) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
out.append("Character properties\n");
|
||||
for (Iterator it1 = getCharacterStyles().iterator(); it1.hasNext();) {
|
||||
TextPropCollection pr = (TextPropCollection)it1.next();
|
||||
out.append(" chars covered: " + pr.getCharactersCovered() + "\n");
|
||||
out.append(" chars covered: " + pr.getCharactersCovered() );
|
||||
out.append(" special mask flags: 0x" + HexDump.toHex(pr.getSpecialMask()) + "\n");
|
||||
for (Iterator it2 = pr.getTextPropList().iterator(); it2.hasNext(); ) {
|
||||
TextProp p = (TextProp)it2.next();
|
||||
out.append(" " + p.getName() + " = " + p.getValue() + "\n");
|
||||
out.append(" " + p.getName() + " = " + p.getValue() );
|
||||
out.append(" (0x" + HexDump.toHex(p.getValue()) + ")\n");
|
||||
}
|
||||
|
||||
out.append(" char bytes that would be written: \n");
|
||||
|
||||
try {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
pr.writeOut(baos);
|
||||
byte[] b = baos.toByteArray();
|
||||
out.append(HexDump.dump(b, 0, 0));
|
||||
} catch (Exception e ) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out.append(" original byte stream \n");
|
||||
out.append( HexDump.dump(rawContents, 0, 0) );
|
||||
|
||||
return out.toString();
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
package org.apache.poi.hslf.record;
|
||||
|
||||
import org.apache.poi.util.HexDump;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
import org.apache.poi.util.StringUtil;
|
||||
import java.io.IOException;
|
||||
|
@ -101,4 +102,15 @@ public class TextBytesAtom extends RecordAtom
|
|||
// Write out our text
|
||||
out.write(_text);
|
||||
}
|
||||
|
||||
/**
|
||||
* dump debug info; use getText() to return a string
|
||||
* representation of the atom
|
||||
*/
|
||||
public String toString() {
|
||||
StringBuffer out = new StringBuffer();
|
||||
out.append( "TextBytesAtom:\n");
|
||||
out.append( HexDump.dump(_text, 0, 0) );
|
||||
return out.toString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
package org.apache.poi.hslf.record;
|
||||
|
||||
import org.apache.poi.util.HexDump;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
import org.apache.poi.util.StringUtil;
|
||||
import java.io.IOException;
|
||||
|
@ -97,4 +98,15 @@ public class TextCharsAtom extends RecordAtom
|
|||
// Write out our text
|
||||
out.write(_text);
|
||||
}
|
||||
|
||||
/**
|
||||
* dump debug info; use getText() to return a string
|
||||
* representation of the atom
|
||||
*/
|
||||
public String toString() {
|
||||
StringBuffer out = new StringBuffer();
|
||||
out.append( "TextCharsAtom:\n");
|
||||
out.append( HexDump.dump(_text, 0, 0) );
|
||||
return out.toString();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue