ASF Bugzilla – Attachment 30944 Details for
Bug 48593
[PATCH] Multiple Saves Causes Slide Corruption
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
[PATCH] Bug 48593 - Multi Rewrites
hslf-bug48593-multi-writes.diff (text/plain), 9.98 KB, created by
Andreas Beeker
on 2013-10-18 23:49:29 UTC
(
hide
)
Description:
[PATCH] Bug 48593 - Multi Rewrites
Filename:
MIME Type:
Creator:
Andreas Beeker
Created:
2013-10-18 23:49:29 UTC
Size:
9.98 KB
patch
obsolete
>Index: src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java >=================================================================== >--- src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java (revision 1532876) >+++ src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java (working copy) >@@ -723,53 +723,10 @@ > > // Add the core records for this new Slide to the record tree > org.apache.poi.hslf.record.Slide slideRecord = slide.getSlideRecord(); >- int slideRecordPos = _hslfSlideShow.appendRootLevelRecord(slideRecord); >- _records = _hslfSlideShow.getRecords(); >- >- // Add the new Slide into the PersistPtr stuff >- int offset = 0; >- int slideOffset = 0; >- PersistPtrHolder ptr = null; >- UserEditAtom usr = null; >- for (int i = 0; i < _records.length; i++) { >- Record record = _records[i]; >- ByteArrayOutputStream out = new ByteArrayOutputStream(); >- try { >- record.writeOut(out); >- } catch (IOException e) { >- throw new HSLFException(e); >- } >- >- // Grab interesting records as they come past >- if (_records[i].getRecordType() == RecordTypes.PersistPtrIncrementalBlock.typeID) { >- ptr = (PersistPtrHolder) _records[i]; >- } >- if (_records[i].getRecordType() == RecordTypes.UserEditAtom.typeID) { >- usr = (UserEditAtom) _records[i]; >- } >- >- if (i == slideRecordPos) { >- slideOffset = offset; >- } >- offset += out.size(); >- } >- >- // persist ID is UserEditAtom.maxPersistWritten + 1 >- int psrId = usr.getMaxPersistWritten() + 1; >+ int psrId = addPersistentObject(slideRecord); > sp.setRefID(psrId); > slideRecord.setSheetId(psrId); >- >- // Last view is now of the slide >- usr.setLastViewType((short) UserEditAtom.LAST_VIEW_SLIDE_VIEW); >- usr.setMaxPersistWritten(psrId); // increment the number of persit >- // objects >- >- // Add the new slide into the last PersistPtr >- // (Also need to tell it where it is) >- slideRecord.setLastOnDiskOffset(slideOffset); >- ptr.addSlideLookup(sp.getRefID(), slideOffset); >- logger.log(POILogger.INFO, "New slide ended up at " + slideOffset); >- >+ > slide.setMasterSheet(_masters[0]); > // All done and added > return slide; >@@ -978,16 +935,6 @@ > * @return 0-based index of the movie > */ > public int addMovie(String path, int type) { >- ExObjList lst = (ExObjList) _documentRecord.findFirstOfType(RecordTypes.ExObjList.typeID); >- if (lst == null) { >- lst = new ExObjList(); >- _documentRecord.addChildAfter(lst, _documentRecord.getDocumentAtom()); >- } >- >- ExObjListAtom objAtom = lst.getExObjListAtom(); >- // increment the object ID seed >- int objectId = (int) objAtom.getObjectIDSeed() + 1; >- objAtom.setObjectIDSeed(objectId); > ExMCIMovie mci; > switch (type) { > case MovieShape.MOVIE_MPEG: >@@ -1000,11 +947,13 @@ > throw new IllegalArgumentException("Unsupported Movie: " + type); > } > >- lst.appendChildRecord(mci); > ExVideoContainer exVideo = mci.getExVideo(); >- exVideo.getExMediaAtom().setObjectId(objectId); > exVideo.getExMediaAtom().setMask(0xE80000); > exVideo.getPathAtom().setText(path); >+ >+ int objectId = addToObjListAtom(mci); >+ exVideo.getExMediaAtom().setObjectId(objectId); >+ > return objectId; > } > >@@ -1019,27 +968,18 @@ > * @return 0-based index of the control > */ > public int addControl(String name, String progId) { >- ExObjList lst = (ExObjList) _documentRecord.findFirstOfType(RecordTypes.ExObjList.typeID); >- if (lst == null) { >- lst = new ExObjList(); >- _documentRecord.addChildAfter(lst, _documentRecord.getDocumentAtom()); >- } >- ExObjListAtom objAtom = lst.getExObjListAtom(); >- // increment the object ID seed >- int objectId = (int) objAtom.getObjectIDSeed() + 1; >- objAtom.setObjectIDSeed(objectId); > ExControl ctrl = new ExControl(); >+ ctrl.setProgId(progId); >+ ctrl.setMenuName(name); >+ ctrl.setClipboardName(name); >+ > ExOleObjAtom oleObj = ctrl.getExOleObjAtom(); >- oleObj.setObjID(objectId); > oleObj.setDrawAspect(ExOleObjAtom.DRAW_ASPECT_VISIBLE); > oleObj.setType(ExOleObjAtom.TYPE_CONTROL); > oleObj.setSubType(ExOleObjAtom.SUBTYPE_DEFAULT); >- >- ctrl.setProgId(progId); >- ctrl.setMenuName(name); >- ctrl.setClipboardName(name); >- lst.addChildAfter(ctrl, objAtom); >- >+ >+ int objectId = addToObjListAtom(ctrl); >+ oleObj.setObjID(objectId); > return objectId; > } > >@@ -1049,19 +989,8 @@ > * @return 0-based index of the hyperlink > */ > public int addHyperlink(Hyperlink link) { >- ExObjList lst = (ExObjList) _documentRecord.findFirstOfType(RecordTypes.ExObjList.typeID); >- if (lst == null) { >- lst = new ExObjList(); >- _documentRecord.addChildAfter(lst, _documentRecord.getDocumentAtom()); >- } >- ExObjListAtom objAtom = lst.getExObjListAtom(); >- // increment the object ID seed >- int objectId = (int) objAtom.getObjectIDSeed() + 1; >- objAtom.setObjectIDSeed(objectId); >- > ExHyperlink ctrl = new ExHyperlink(); > ExHyperlinkAtom obj = ctrl.getExHyperlinkAtom(); >- obj.setNumber(objectId); > if(link.getType() == Hyperlink.LINK_SLIDENUMBER) { > ctrl.setLinkURL(link.getAddress(), 0x30); > } else { >@@ -1068,9 +997,110 @@ > ctrl.setLinkURL(link.getAddress()); > } > ctrl.setLinkTitle(link.getTitle()); >- lst.addChildAfter(ctrl, objAtom); >+ >+ int objectId = addToObjListAtom(ctrl); > link.setId(objectId); >+ obj.setNumber(objectId); > > return objectId; > } >+ >+ protected int addToObjListAtom(RecordContainer exObj) { >+ ExObjList lst = (ExObjList) _documentRecord.findFirstOfType(RecordTypes.ExObjList.typeID); >+ if (lst == null) { >+ lst = new ExObjList(); >+ _documentRecord.addChildAfter(lst, _documentRecord.getDocumentAtom()); >+ } >+ ExObjListAtom objAtom = lst.getExObjListAtom(); >+ // increment the object ID seed >+ int objectId = (int) objAtom.getObjectIDSeed() + 1; >+ objAtom.setObjectIDSeed(objectId); >+ >+ lst.addChildAfter(exObj, objAtom); >+ >+ return objectId; >+ } >+ >+ protected int addPersistentObject(PositionDependentRecord slideRecord) { >+ slideRecord.setLastOnDiskOffset(-1); >+ _hslfSlideShow.appendRootLevelRecord((Record)slideRecord); >+ _records = _hslfSlideShow.getRecords(); >+ >+ // For position dependent records, hold where they were and now are >+ // As we go along, update, and hand over, to any Position Dependent >+ // records we happen across >+ Hashtable<Integer,Integer> oldToNewPositions = new Hashtable<Integer,Integer>(); >+ >+ // Add the new Slide into the PersistPtr stuff >+ int slideOffset = 0; >+ >+ // First pass - figure out where all the position dependent >+ // records are going to end up, in the new scheme >+ // (Annoyingly, some powerpoing files have PersistPtrHolders >+ // that reference slides after the PersistPtrHolder) >+ ByteArrayOutputStream baos = new ByteArrayOutputStream(); >+ for (Record record : _records) { >+ if(record instanceof PositionDependentRecord) { >+ PositionDependentRecord pdr = (PositionDependentRecord)record; >+ int oldPos = pdr.getLastOnDiskOffset(); >+ int newPos = baos.size(); >+ pdr.setLastOnDiskOffset(newPos); >+ if (record == slideRecord) { >+ // set the slideOffset later, to not interfere with exisiting positions >+ slideOffset = newPos; >+ } else { >+ oldToNewPositions.put(Integer.valueOf(oldPos),Integer.valueOf(newPos)); >+ } >+ >+ } >+ >+ // Dummy write out, so the position winds on properly >+ try { >+ record.writeOut(baos); >+ } catch (IOException e) { >+ throw new HSLFException(e); >+ } >+ } >+ >+ PersistPtrHolder ptr = null; >+ UserEditAtom usr = null; >+ // For now, we're only handling PositionDependentRecord's that >+ // happen at the top level. >+ // In future, we'll need the handle them everywhere, but that's >+ // a bit trickier >+ for (Record record : _records) { >+ if (!(record instanceof PositionDependentRecord)) continue; >+ >+ // We've already figured out their new location, and >+ // told them that >+ // Tell them of the positions of the other records though >+ PositionDependentRecord pdr = (PositionDependentRecord)record; >+ pdr.updateOtherRecordReferences(oldToNewPositions); >+ >+ // Grab interesting records as they come past >+ int recordType = (int)record.getRecordType(); >+ if (recordType == RecordTypes.PersistPtrIncrementalBlock.typeID) { >+ ptr = (PersistPtrHolder)record; >+ } else if (recordType == RecordTypes.UserEditAtom.typeID) { >+ usr = (UserEditAtom)record; >+ } >+ } >+ >+ // persist ID is UserEditAtom.maxPersistWritten + 1 >+ int psrId = usr.getMaxPersistWritten() + 1; >+ >+ // Last view is now of the slide >+ usr.setLastViewType((short) UserEditAtom.LAST_VIEW_SLIDE_VIEW); >+ // increment the number of persistent objects >+ usr.setMaxPersistWritten(psrId); >+ _hslfSlideShow.getCurrentUserAtom().setCurrentEditOffset(usr.getLastOnDiskOffset()); >+ >+ // Add the new slide into the last PersistPtr >+ // (Also need to tell it where it is) >+ slideRecord.setLastOnDiskOffset(slideOffset); >+ ptr.addSlideLookup(psrId, slideOffset); >+ logger.log(POILogger.INFO, "New slide/object ended up at " + slideOffset); >+ >+ return psrId; >+ } > } >Index: src/scratchpad/testcases/org/apache/poi/hslf/TestReWrite.java >=================================================================== >--- src/scratchpad/testcases/org/apache/poi/hslf/TestReWrite.java (revision 1532876) >+++ src/scratchpad/testcases/org/apache/poi/hslf/TestReWrite.java (working copy) >@@ -160,4 +160,16 @@ > assertEquals(_oData[i], _nData[i]); > } > } >+ >+ public void test48593() throws Exception { >+ SlideShow slideShow = new SlideShow(); >+ slideShow.createSlide(); >+ slideShow = HSLFTestDataSamples.writeOutAndReadBack(slideShow); >+ slideShow.createSlide(); >+ slideShow = HSLFTestDataSamples.writeOutAndReadBack(slideShow); >+ slideShow.createSlide(); >+ slideShow = HSLFTestDataSamples.writeOutAndReadBack(slideShow); >+ slideShow.createSlide(); >+ slideShow = HSLFTestDataSamples.writeOutAndReadBack(slideShow); >+ } > }
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 48593
:
24881
|
29961
|
30944
|
30948
|
31161