View | Details | Raw Unified | Return to bug 45844
Collapse All | Expand All

(-)src/scratchpad/src/org/apache/poi/hslf/model/textproperties/TextPropCollection.java (-1 / +3 lines)
Lines 35-40 Link Here
35
	private short reservedField;
35
	private short reservedField;
36
	private LinkedList textPropList;
36
	private LinkedList textPropList;
37
    private int maskSpecial = 0;
37
    private int maskSpecial = 0;
38
    
39
    public int getSpecialMask() { return maskSpecial; }
38
40
39
	/** Fetch the number of characters this styling applies to */
41
	/** Fetch the number of characters this styling applies to */
40
	public int getCharactersCovered() { return charactersCovered; }
42
	public int getCharactersCovered() { return charactersCovered; }
Lines 202-205 Link Here
202
    public void setReservedField(short val){
204
    public void setReservedField(short val){
203
        reservedField = val;
205
        reservedField = val;
204
    }
206
    }
205
}
207
}
(-)src/scratchpad/src/org/apache/poi/hslf/dev/SlideShowRecordDumper.java (-7 / +158 lines)
Lines 20-27 Link Here
20
import java.io.ByteArrayOutputStream;
20
import java.io.ByteArrayOutputStream;
21
import java.io.IOException;
21
import java.io.IOException;
22
22
23
import java.util.Iterator;
24
23
import org.apache.poi.hslf.HSLFSlideShow;
25
import org.apache.poi.hslf.HSLFSlideShow;
24
import org.apache.poi.hslf.record.Record;
26
import org.apache.poi.hslf.record.Record;
27
import org.apache.poi.util.HexDump;
28
import org.apache.poi.ddf.DefaultEscherRecordFactory;
29
import org.apache.poi.ddf.EscherRecord;
30
import org.apache.poi.ddf.EscherContainerRecord;
31
import org.apache.poi.ddf.EscherTextboxRecord;
32
import org.apache.poi.hslf.record.EscherTextboxWrapper;
33
import org.apache.poi.hslf.record.TextCharsAtom;
34
import org.apache.poi.hslf.record.TextBytesAtom;
35
import org.apache.poi.hslf.record.StyleTextPropAtom;
36
import org.apache.poi.hslf.record.Record;
25
37
26
/**
38
/**
27
 * This class provides a way to view the contents of a powerpoint file.
39
 * This class provides a way to view the contents of a powerpoint file.
Lines 31-36 Link Here
31
 * @author Nick Burch
43
 * @author Nick Burch
32
 */
44
 */
33
public final class SlideShowRecordDumper {
45
public final class SlideShowRecordDumper {
46
  private boolean optVerbose;
47
  private boolean optEscher;
34
  private HSLFSlideShow doc;
48
  private HSLFSlideShow doc;
35
49
36
  /**
50
  /**
Lines 39-55 Link Here
39
   */
53
   */
40
  public static void main(String args[]) throws IOException
54
  public static void main(String args[]) throws IOException
41
  {
55
  {
42
	if(args.length == 0) {
56
	String filename = "";
43
		System.err.println("Useage: SlideShowRecordDumper <filename>");
57
	boolean verbose = false;
58
	boolean escher = false;
59
60
	int ndx=0;
61
	for (; ndx<args.length; ndx++) {		
62
		if (!args[ndx].substring(0,1).equals("-"))
63
			break;
64
				
65
		if (args[ndx].equals("-escher")) {
66
			escher = true;
67
		} else if (args[ndx].equals("-verbose")) {
68
			verbose = true;
69
		} else {
70
			printUsage();
71
			return;
72
		}
73
	}
74
	
75
	// parsed any options, expect exactly one remaining arg (filename)
76
	if (ndx != args.length-1) {
77
		printUsage();
44
		return;
78
		return;
45
	}
79
	}
80
	
81
	filename = args[ndx];
46
82
47
	String filename = args[0];
83
	SlideShowRecordDumper foo = new SlideShowRecordDumper(filename, verbose, escher);
48
84
49
	SlideShowRecordDumper foo = new SlideShowRecordDumper(filename);
50
51
	foo.printDump();
85
	foo.printDump();
52
  }
86
  }
87
  
88
  public static void printUsage() {
89
		System.err.println("Usage: SlideShowRecordDumper [-escher] [-verbose] <filename>");
90
		System.err.println("Valid Options:");
91
		System.err.println("-escher\t\t: dump contents of escher records");
92
		System.err.println("-verbose\t: dump binary contents of each record");
93
  }
53
94
54
95
55
  /**
96
  /**
Lines 59-66 Link Here
59
   * @param fileName The name of the file to read.
100
   * @param fileName The name of the file to read.
60
   * @throws IOException if there is a problem while parsing the document.
101
   * @throws IOException if there is a problem while parsing the document.
61
   */
102
   */
62
  public SlideShowRecordDumper(String fileName) throws IOException
103
  public SlideShowRecordDumper(String fileName, boolean verbose, boolean escher) throws IOException
63
  {
104
  {
105
	optVerbose = verbose;
106
  	optEscher = escher;
64
	doc = new HSLFSlideShow(fileName);
107
	doc = new HSLFSlideShow(fileName);
65
  }
108
  }
66
109
Lines 95-107 Link Here
95
  }
138
  }
96
139
97
  public int getDiskLen(Record r) throws IOException {
140
  public int getDiskLen(Record r) throws IOException {
141
  	if (r == null) return 0;
142
  	
98
	ByteArrayOutputStream baos = new ByteArrayOutputStream();
143
	ByteArrayOutputStream baos = new ByteArrayOutputStream();
99
	r.writeOut(baos);
144
	r.writeOut(baos);
100
	byte[] b = baos.toByteArray();
145
	byte[] b = baos.toByteArray();
101
	return b.length;
146
	return b.length;
102
  }
147
  }
103
148
149
  public String getPrintableRecordContents(Record r) throws IOException {
150
  	if (r==null) return "<<null>>";
151
  	
152
	ByteArrayOutputStream baos = new ByteArrayOutputStream();
153
	r.writeOut(baos);
154
	byte[] b = baos.toByteArray();
155
	return HexDump.dump(b, 0, 0);
156
  }
157
  
158
  public String printEscherRecord( EscherRecord er ) {
159
        String nl = System.getProperty( "line.separator" );
160
        StringBuffer buf = new StringBuffer();
104
161
162
		if (er instanceof EscherContainerRecord) {
163
			buf.append(printEscherContainerRecord( (EscherContainerRecord)er ));
164
		} else if (er instanceof EscherTextboxRecord) {
165
			buf.append("EscherTextboxRecord:" + nl);
166
			
167
			EscherTextboxWrapper etw = new EscherTextboxWrapper((EscherTextboxRecord)er);
168
			Record children[] = etw.getChildRecords();
169
			for (int j=0; j<children.length; j++) {
170
				if (children[j] instanceof StyleTextPropAtom) {
171
					
172
					// need preceding Text[Chars|Bytes]Atom to initialize the data structure
173
					if (j > 0 && (children[j-1] instanceof TextCharsAtom || 
174
								  children[j-1] instanceof TextBytesAtom)) {
175
								  	
176
						int size = (children[j-1] instanceof TextCharsAtom) ? 
177
										((TextCharsAtom)children[j-1]).getText().length() : 
178
										((TextBytesAtom)children[j-1]).getText().length();
179
										
180
						StyleTextPropAtom tsp = (StyleTextPropAtom)children[j];
181
						tsp.setParentTextSize(size);
182
						
183
					} else {
184
						buf.append("Error! Couldn't find preceding TextAtom for style\n");
185
					}
186
					
187
					buf.append(children[j].toString() + nl );
188
				} else {				
189
					buf.append(children[j].toString() + nl );
190
				}
191
			}
192
		} else {
193
			buf.append( er.toString() );
194
		}			
195
		return buf.toString();
196
  }
197
  
198
  public String printEscherContainerRecord( EscherContainerRecord ecr ) {
199
  		String indent = "";
200
  		
201
        String nl = System.getProperty( "line.separator" );
202
203
        StringBuffer children = new StringBuffer();
204
        if ( ecr.getChildRecords().size() > 0 )
205
        {
206
            children.append( "  children: " + nl );
207
            
208
            int count = 0;
209
            for ( Iterator iterator = ecr.getChildRecords().iterator(); iterator.hasNext(); )
210
            {
211
            	String newIndent = "   ";
212
            	
213
                EscherRecord record = (EscherRecord) iterator.next();
214
                children.append(newIndent + "Child " + count + ":" + nl);
215
                
216
               	children.append( printEscherRecord(record) );
217
218
                count++;
219
            }
220
        }
221
222
        return 
223
        	indent + ecr.getClass().getName() + " (" + ecr.getRecordName() + "):" + nl +
224
            indent + "  isContainer: " + ecr.isContainerRecord() + nl +
225
            indent + "  options: 0x" + HexDump.toHex( ecr.getOptions() ) + nl +
226
            indent + "  recordId: 0x" + HexDump.toHex( ecr.getRecordId() ) + nl +
227
            indent + "  numchildren: " + ecr.getChildRecords().size() + nl +
228
            indent + children.toString();
229
  }
230
231
105
  public void walkTree(int depth, int pos, Record[] records) throws IOException {
232
  public void walkTree(int depth, int pos, Record[] records) throws IOException {
106
	int indent = depth;
233
	int indent = depth;
107
	String ind = "";
234
	String ind = "";
Lines 109-118 Link Here
109
236
110
	for(int i=0; i<records.length; i++) {
237
	for(int i=0; i<records.length; i++) {
111
		Record r = records[i];
238
		Record r = records[i];
239
		if (r == null) {
240
			System.out.println(ind + "At position " + pos + " (" + makeHex(pos,6) + "):");
241
			System.out.println(ind + "Warning! Null record found.");
242
			continue;
243
		}
112
244
113
		// Figure out how big it is
245
		// Figure out how big it is
114
		int len = getDiskLen(r);
246
		int len = getDiskLen(r);
115
247
		
116
		// Grab the type as hex
248
		// Grab the type as hex
117
		String hexType = makeHex((int)r.getRecordType(),4);
249
		String hexType = makeHex((int)r.getRecordType(),4);
118
		String rHexType = reverseHex(hexType);
250
		String rHexType = reverseHex(hexType);
Lines 132-137 Link Here
132
		System.out.println(ind + " Record is of type " + cname);
264
		System.out.println(ind + " Record is of type " + cname);
133
		System.out.println(ind + " Type is " + r.getRecordType() + " (" + hexType + " -> " + rHexType + " )");
265
		System.out.println(ind + " Type is " + r.getRecordType() + " (" + hexType + " -> " + rHexType + " )");
134
		System.out.println(ind + " Len is " + (len-8) + " (" + makeHex((len-8),8) + "), on disk len is " + len );
266
		System.out.println(ind + " Len is " + (len-8) + " (" + makeHex((len-8),8) + "), on disk len is " + len );
267
268
		// print additional information for drawings and atoms
269
		if (optEscher && cname.equals("PPDrawing")) {
270
			DefaultEscherRecordFactory factory = new DefaultEscherRecordFactory();
271
272
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
273
			r.writeOut(baos);
274
			byte[] b = baos.toByteArray();
275
276
			EscherRecord er = factory.createRecord(b, 0);
277
			er.fillFields(b, 0, factory);
278
			
279
			System.out.println( printEscherRecord( er ) );
280
						
281
		} else if(optVerbose && r.getChildRecords() == null) {
282
			String recData = getPrintableRecordContents(r);
283
			System.out.println(ind + recData );
284
		}
285
135
		System.out.println();
286
		System.out.println();
136
287
137
		// If it has children, show them
288
		// If it has children, show them
(-)src/scratchpad/src/org/apache/poi/hslf/record/TextBytesAtom.java (+12 lines)
Lines 19-24 Link Here
19
19
20
package org.apache.poi.hslf.record;
20
package org.apache.poi.hslf.record;
21
21
22
import org.apache.poi.util.HexDump;
22
import org.apache.poi.util.LittleEndian;
23
import org.apache.poi.util.LittleEndian;
23
import org.apache.poi.util.StringUtil;
24
import org.apache.poi.util.StringUtil;
24
import java.io.IOException;
25
import java.io.IOException;
Lines 101-104 Link Here
101
		// Write out our text
102
		// Write out our text
102
		out.write(_text);
103
		out.write(_text);
103
	}
104
	}
105
106
	/**
107
	 * dump debug info; use getText() to return a string 
108
	 * representation of the atom
109
	 */
110
	public String toString() {
111
        StringBuffer out = new StringBuffer();
112
        out.append( "TextBytesAtom:\n");
113
		out.append( HexDump.dump(_text, 0, 0) );
114
		return out.toString();
115
	}
104
}
116
}
(-)src/scratchpad/src/org/apache/poi/hslf/record/StyleTextPropAtom.java (-18 / +56 lines)
Lines 32-37 Link Here
32
import org.apache.poi.hslf.model.textproperties.TextPropCollection;
32
import org.apache.poi.hslf.model.textproperties.TextPropCollection;
33
import org.apache.poi.util.LittleEndian;
33
import org.apache.poi.util.LittleEndian;
34
import org.apache.poi.util.POILogger;
34
import org.apache.poi.util.POILogger;
35
import org.apache.poi.util.HexDump;
35
36
36
/**
37
/**
37
 * A StyleTextPropAtom (type 4001). Holds basic character properties 
38
 * A StyleTextPropAtom (type 4001). Holds basic character properties 
Lines 417-442 Link Here
417
     */
418
     */
418
    public String toString(){
419
    public String toString(){
419
        StringBuffer out = new StringBuffer();
420
        StringBuffer out = new StringBuffer();
420
        out.append("Paragraph properties\n");
421
        
421
        for (Iterator it1 = getParagraphStyles().iterator(); it1.hasNext();) {
422
	    out.append("StyleTextPropAtom:\n");
422
            TextPropCollection pr = (TextPropCollection)it1.next();
423
        if (!initialised) {
423
            out.append("  chars covered: " + pr.getCharactersCovered() + "\n");
424
	        out.append("Uninitialised, dumping Raw Style Data\n");
424
            for (Iterator it2 = pr.getTextPropList().iterator(); it2.hasNext(); ) {
425
        } else {
425
                TextProp p = (TextProp)it2.next();
426
        
426
                out.append("    " + p.getName() + " = " + p.getValue() + "\n");
427
	        out.append("Paragraph properties\n");
427
            }
428
	        
429
	        for (Iterator it1 = getParagraphStyles().iterator(); it1.hasNext();) {
430
	            TextPropCollection pr = (TextPropCollection)it1.next();
431
	            out.append("  chars covered: " + pr.getCharactersCovered());
432
	            out.append("  special mask flags: 0x" + HexDump.toHex(pr.getSpecialMask()) + "\n");
433
	            for (Iterator it2 = pr.getTextPropList().iterator(); it2.hasNext(); ) {
434
	                TextProp p = (TextProp)it2.next();
435
	                out.append("    " + p.getName() + " = " + p.getValue() );
436
	                out.append(" (0x" + HexDump.toHex(p.getValue()) + ")\n");
437
	            }
438
	            
439
	            out.append("  para bytes that would be written: \n");
440
	            
441
	            try {
442
					ByteArrayOutputStream baos = new ByteArrayOutputStream();
443
					pr.writeOut(baos);
444
					byte[] b = baos.toByteArray();
445
					out.append(HexDump.dump(b, 0, 0));
446
	            } catch (Exception e ) {
447
	            	e.printStackTrace();
448
	            }
449
	        }
450
	
451
	        out.append("Character properties\n");
452
	        for (Iterator it1 = getCharacterStyles().iterator(); it1.hasNext();) {
453
	            TextPropCollection pr = (TextPropCollection)it1.next();
454
	            out.append("  chars covered: " + pr.getCharactersCovered() );
455
	            out.append("  special mask flags: 0x" + HexDump.toHex(pr.getSpecialMask()) + "\n");
456
	            for (Iterator it2 = pr.getTextPropList().iterator(); it2.hasNext(); ) {
457
	                TextProp p = (TextProp)it2.next();
458
	                out.append("    " + p.getName() + " = " + p.getValue() );
459
	                out.append(" (0x" + HexDump.toHex(p.getValue()) + ")\n");
460
	            }
461
	            
462
	            out.append("  char bytes that would be written: \n");
463
	            
464
	            try {
465
					ByteArrayOutputStream baos = new ByteArrayOutputStream();
466
					pr.writeOut(baos);
467
					byte[] b = baos.toByteArray();
468
					out.append(HexDump.dump(b, 0, 0));
469
	            } catch (Exception e ) {
470
	            	e.printStackTrace();
471
	            }
472
	        }
428
        }
473
        }
474
        	
475
        out.append("  original byte stream \n");
476
		out.append( HexDump.dump(rawContents, 0, 0) );
429
477
430
        out.append("Character properties\n");
431
        for (Iterator it1 = getCharacterStyles().iterator(); it1.hasNext();) {
432
            TextPropCollection pr = (TextPropCollection)it1.next();
433
            out.append("  chars covered: " + pr.getCharactersCovered() + "\n");
434
            for (Iterator it2 = pr.getTextPropList().iterator(); it2.hasNext(); ) {
435
                TextProp p = (TextProp)it2.next();
436
                out.append("    " + p.getName() + " = " + p.getValue() + "\n");
437
            }
438
        }
439
440
        return out.toString();
478
        return out.toString();
441
    }
479
    }
442
}
480
}
(-)src/scratchpad/src/org/apache/poi/hslf/record/TextCharsAtom.java (+12 lines)
Lines 19-24 Link Here
19
19
20
package org.apache.poi.hslf.record;
20
package org.apache.poi.hslf.record;
21
21
22
import org.apache.poi.util.HexDump;
22
import org.apache.poi.util.LittleEndian;
23
import org.apache.poi.util.LittleEndian;
23
import org.apache.poi.util.StringUtil;
24
import org.apache.poi.util.StringUtil;
24
import java.io.IOException;
25
import java.io.IOException;
Lines 97-100 Link Here
97
		// Write out our text
98
		// Write out our text
98
		out.write(_text);
99
		out.write(_text);
99
	}
100
	}
101
	
102
	/**
103
	 * dump debug info; use getText() to return a string 
104
	 * representation of the atom
105
	 */
106
	public String toString() {
107
        StringBuffer out = new StringBuffer();
108
        out.append( "TextCharsAtom:\n");
109
		out.append( HexDump.dump(_text, 0, 0) );
110
		return out.toString();
111
	}
100
}
112
}

Return to bug 45844