From d40aa464fa478f70355ef6129dbf03d7fdcf72ec Mon Sep 17 00:00:00 2001 From: Nick Burch Date: Thu, 9 Jun 2005 15:09:16 +0000 Subject: [PATCH] Improved handling of byte position sensitive records git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@353709 13f79535-47bb-0310-9956-ffa450edef68 --- .../src/org/apache/poi/hslf/model/Sheet.java | 13 +- .../org/apache/poi/hslf/model/TextRun.java | 2 +- ...myPositionSensitiveRecordWithChildren.java | 75 +++++++++ .../src/org/apache/poi/hslf/record/Notes.java | 2 +- .../poi/hslf/record/PersistPtrHolder.java | 156 ++++++++++++++++-- .../hslf/record/PositionDependentRecord.java | 52 ++++++ .../record/PositionDependentRecordAtom.java | 13 +- .../PositionDependentRecordContainer.java | 53 ++++++ .../org/apache/poi/hslf/record/Record.java | 61 +++++-- .../src/org/apache/poi/hslf/record/Slide.java | 2 +- .../apache/poi/hslf/record/UserEditAtom.java | 26 ++- 11 files changed, 417 insertions(+), 38 deletions(-) create mode 100644 src/scratchpad/src/org/apache/poi/hslf/record/DummyPositionSensitiveRecordWithChildren.java create mode 100644 src/scratchpad/src/org/apache/poi/hslf/record/PositionDependentRecord.java create mode 100644 src/scratchpad/src/org/apache/poi/hslf/record/PositionDependentRecordContainer.java diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/Sheet.java b/src/scratchpad/src/org/apache/poi/hslf/model/Sheet.java index 5a7aa8ac7..015d90328 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/Sheet.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/Sheet.java @@ -77,14 +77,21 @@ public abstract class Sheet } else if(records[i+1] instanceof TextBytesAtom) { TextBytesAtom tba = (TextBytesAtom)records[i+1]; trun = new TextRun(tha,tba); + } else if(records[i+1].getRecordType() == 4001l) { + // StyleTextPropAtom - Safe to ignore } else if(records[i+1].getRecordType() == 4010l) { - // Safe to ignore + // TextSpecInfoAtom - Safe to ignore } else { System.err.println("Found a TextHeaderAtom not followed by a TextBytesAtom or TextCharsAtom: Followed by " + records[i+1].getRecordType()); continue; } - found.add(trun); - i++; + + if(trun != null) { + found.add(trun); + i++; + } else { + // Not a valid one, so skip on to next and look again + } } } } diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/TextRun.java b/src/scratchpad/src/org/apache/poi/hslf/model/TextRun.java index fd010f849..dc87c79ee 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/TextRun.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/TextRun.java @@ -99,7 +99,7 @@ public class TextRun public void setText(String s) { // If size changed, warn if(s.length() != getText().length()) { - System.err.println("Warning: Your powerpoint file is probably no longer readable by powerpoint, as the text run has changed size!"); + System.err.println("Warning: Your powerpoint file may no longer readable by powerpoint, as the text run has changed size!"); } if(_isUnicode) { diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/DummyPositionSensitiveRecordWithChildren.java b/src/scratchpad/src/org/apache/poi/hslf/record/DummyPositionSensitiveRecordWithChildren.java new file mode 100644 index 000000000..3f2674bf8 --- /dev/null +++ b/src/scratchpad/src/org/apache/poi/hslf/record/DummyPositionSensitiveRecordWithChildren.java @@ -0,0 +1,75 @@ + +/* ==================================================================== + Copyright 2002-2004 Apache Software Foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + + +package org.apache.poi.hslf.record; + +import org.apache.poi.util.LittleEndian; +import java.io.IOException; +import java.io.OutputStream; +import java.io.ByteArrayOutputStream; + +/** + * If we come across a record we know has children of (potential) + * interest, but where the record itself is boring, but where other + * records may care about where this one lives, we create one + * of these. It allows us to get at the children, and track where on + * disk this is, but not much else. + * Anything done using this should quite quickly be transitioned to its + * own proper record class! + * + * @author Nick Burch + */ + +public class DummyPositionSensitiveRecordWithChildren extends PositionDependentRecordContainer +{ + private Record[] _children; + private byte[] _header; + private long _type; + + /** + * Create a new holder for a boring record with children, but with + * position dependent characteristics + */ + protected DummyPositionSensitiveRecordWithChildren(byte[] source, int start, int len) { + // Just grab the header, not the whole contents + _header = new byte[8]; + System.arraycopy(source,start,_header,0,8); + _type = LittleEndian.getUShort(_header,2); + + // Find our children + _children = Record.findChildRecords(source,start+8,len-8); + } + + /** + * Return the value we were given at creation + */ + public long getRecordType() { return _type; } + + /** + * Return any children + */ + public Record[] getChildRecords() { return _children; } + + /** + * Write the contents of the record back, so it can be written + * to disk + */ + public void writeOut(OutputStream out) throws IOException { + writeOut(_header[0],_header[1],_type,_children,out); + } +} diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/Notes.java b/src/scratchpad/src/org/apache/poi/hslf/record/Notes.java index 86e692b36..3e7c9e7e2 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/record/Notes.java +++ b/src/scratchpad/src/org/apache/poi/hslf/record/Notes.java @@ -30,7 +30,7 @@ import java.io.ByteArrayOutputStream; * @author Nick Burch */ -public class Notes extends RecordContainer +public class Notes extends PositionDependentRecordContainer { private Record[] _children; private byte[] _header; diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/PersistPtrHolder.java b/src/scratchpad/src/org/apache/poi/hslf/record/PersistPtrHolder.java index 56390adb5..cb5b5dee2 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/record/PersistPtrHolder.java +++ b/src/scratchpad/src/org/apache/poi/hslf/record/PersistPtrHolder.java @@ -21,47 +21,183 @@ package org.apache.poi.hslf.record; import org.apache.poi.util.LittleEndian; import java.io.IOException; import java.io.OutputStream; +import java.util.Enumeration; +import java.util.Hashtable; /** * General holder for PersistPtrFullBlock and PersistPtrIncrementalBlock * records. We need to handle them specially, since we have to go around * updating UserEditAtoms if they shuffle about on disk + * These hold references to where slides "live". If the position of a slide + * moves, then we have update all of these. If we come up with a new version + * of a slide, then we have to add one of these to the end of the chain + * (via CurrentUserAtom and UserEditAtom) pointing to the new slide location * * @author Nick Burch */ public class PersistPtrHolder extends PositionDependentRecordAtom { - private byte[] _contents; + private byte[] _header; + private byte[] _ptrData; // Will need to update this once we allow updates to _slideLocations private long _type; + /** + * Holds the lookup for slides to their position on disk. + * You always need to check the most recent PersistPtrHolder + * that knows about a given slide to find the right location + */ + private Hashtable _slideLocations; + /** + * Holds the lookup from slide id to where their offset is + * held inside _ptrData. Used when writing out, and updating + * the positions of the slides + */ + private Hashtable _slideOffsetDataLocation; + + /** + * Get the list of slides that this PersistPtrHolder knows about. + * (They will be the keys in the hashtable for looking up the positions + * of these slides) + */ + public int[] getKnownSlideIDs() { + int[] ids = new int[_slideLocations.size()]; + Enumeration e = _slideLocations.keys(); + for(int i=0; i> 20); + int offset_no = (int)(info - (offset_count << 20)); +//System.out.println("Info is " + info + ", count is " + offset_count + ", number is " + offset_no); + + // Wind on by the 4 byte info header + pos += 4; + + // Grab the offsets for each of the sheets + for(int i=0; i