diff options
author | Nick Burch <nick@apache.org> | 2008-09-21 16:56:04 +0000 |
---|---|---|
committer | Nick Burch <nick@apache.org> | 2008-09-21 16:56:04 +0000 |
commit | 5bdd4f0cbc41b7bfe67175338bd5fd6bca0e29c9 (patch) | |
tree | 4e0d160b4b87d0a28e811f0a6e1277422eba8bf7 /src/scratchpad | |
parent | 90eb619e34956c35de10db0baca0443c2f7aaa88 (diff) | |
download | poi-5bdd4f0cbc41b7bfe67175338bd5fd6bca0e29c9.tar.gz poi-5bdd4f0cbc41b7bfe67175338bd5fd6bca0e29c9.zip |
Merged revisions 697520 via svnmerge from
https://svn.apache.org/repos/asf/poi/trunk
........
r697520 | yegor | 2008-09-21 15:14:34 +0100 (Sun, 21 Sep 2008) | 1 line
patch from bug #45844: Addtional diagnostics for SlideShowRecordDumper
........
git-svn-id: https://svn.apache.org/repos/asf/poi/branches/ooxml@697548 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/scratchpad')
5 files changed, 241 insertions, 26 deletions
diff --git a/src/scratchpad/src/org/apache/poi/hslf/dev/SlideShowRecordDumper.java b/src/scratchpad/src/org/apache/poi/hslf/dev/SlideShowRecordDumper.java index 74b20993a0..46860213c9 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/dev/SlideShowRecordDumper.java +++ b/src/scratchpad/src/org/apache/poi/hslf/dev/SlideShowRecordDumper.java @@ -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,17 +53,44 @@ 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; } + + filename = args[ndx]; - String filename = args[0]; - - 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"); + } /** @@ -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,10 +236,15 @@ 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); - + // Grab the type as hex String hexType = makeHex((int)r.getRecordType(),4); String rHexType = reverseHex(hexType); @@ -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 diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/TextPropCollection.java b/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/TextPropCollection.java index f876c7d389..f90179b9cc 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/TextPropCollection.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/TextPropCollection.java @@ -35,6 +35,8 @@ public class TextPropCollection { private short reservedField; 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; } @@ -202,4 +204,4 @@ public class TextPropCollection { public void setReservedField(short val){ reservedField = val; } -}
\ No newline at end of file +} diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/StyleTextPropAtom.java b/src/scratchpad/src/org/apache/poi/hslf/record/StyleTextPropAtom.java index 0eebbfc56f..7f084d82e4 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/record/StyleTextPropAtom.java +++ b/src/scratchpad/src/org/apache/poi/hslf/record/StyleTextPropAtom.java @@ -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("Paragraph properties\n"); - for (Iterator it1 = getParagraphStyles().iterator(); it1.hasNext();) { - TextPropCollection pr = (TextPropCollection)it1.next(); - out.append(" chars covered: " + pr.getCharactersCovered() + "\n"); - for (Iterator it2 = pr.getTextPropList().iterator(); it2.hasNext(); ) { - TextProp p = (TextProp)it2.next(); - out.append(" " + p.getName() + " = " + p.getValue() + "\n"); - } - } - - out.append("Character properties\n"); - for (Iterator it1 = getCharacterStyles().iterator(); it1.hasNext();) { - TextPropCollection pr = (TextPropCollection)it1.next(); - out.append(" chars covered: " + pr.getCharactersCovered() + "\n"); - for (Iterator it2 = pr.getTextPropList().iterator(); it2.hasNext(); ) { - TextProp p = (TextProp)it2.next(); - out.append(" " + p.getName() + " = " + p.getValue() + "\n"); - } + + 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()); + 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() ); + 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() ); + 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() ); + 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(); } diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/TextBytesAtom.java b/src/scratchpad/src/org/apache/poi/hslf/record/TextBytesAtom.java index a8ade76885..3e6cf2cbfd 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/record/TextBytesAtom.java +++ b/src/scratchpad/src/org/apache/poi/hslf/record/TextBytesAtom.java @@ -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(); + } } diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/TextCharsAtom.java b/src/scratchpad/src/org/apache/poi/hslf/record/TextCharsAtom.java index 761513ab8d..0e751a73ad 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/record/TextCharsAtom.java +++ b/src/scratchpad/src/org/apache/poi/hslf/record/TextCharsAtom.java @@ -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(); + } } |