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

(-)src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java (-85 / +115 lines)
Lines 723-775 Link Here
723
723
724
		// Add the core records for this new Slide to the record tree
724
		// Add the core records for this new Slide to the record tree
725
		org.apache.poi.hslf.record.Slide slideRecord = slide.getSlideRecord();
725
		org.apache.poi.hslf.record.Slide slideRecord = slide.getSlideRecord();
726
		int slideRecordPos = _hslfSlideShow.appendRootLevelRecord(slideRecord);
726
		int psrId = addPersistentObject(slideRecord);
727
		_records = _hslfSlideShow.getRecords();
728
729
		// Add the new Slide into the PersistPtr stuff
730
		int offset = 0;
731
		int slideOffset = 0;
732
		PersistPtrHolder ptr = null;
733
		UserEditAtom usr = null;
734
		for (int i = 0; i < _records.length; i++) {
735
			Record record = _records[i];
736
			ByteArrayOutputStream out = new ByteArrayOutputStream();
737
			try {
738
				record.writeOut(out);
739
			} catch (IOException e) {
740
				throw new HSLFException(e);
741
			}
742
743
			// Grab interesting records as they come past
744
			if (_records[i].getRecordType() == RecordTypes.PersistPtrIncrementalBlock.typeID) {
745
				ptr = (PersistPtrHolder) _records[i];
746
			}
747
			if (_records[i].getRecordType() == RecordTypes.UserEditAtom.typeID) {
748
				usr = (UserEditAtom) _records[i];
749
			}
750
751
			if (i == slideRecordPos) {
752
				slideOffset = offset;
753
			}
754
			offset += out.size();
755
		}
756
757
		// persist ID is UserEditAtom.maxPersistWritten + 1
758
		int psrId = usr.getMaxPersistWritten() + 1;
759
		sp.setRefID(psrId);
727
		sp.setRefID(psrId);
760
		slideRecord.setSheetId(psrId);
728
		slideRecord.setSheetId(psrId);
761
729
		
762
		// Last view is now of the slide
763
		usr.setLastViewType((short) UserEditAtom.LAST_VIEW_SLIDE_VIEW);
764
		usr.setMaxPersistWritten(psrId); // increment the number of persit
765
										 // objects
766
767
		// Add the new slide into the last PersistPtr
768
		// (Also need to tell it where it is)
769
		slideRecord.setLastOnDiskOffset(slideOffset);
770
		ptr.addSlideLookup(sp.getRefID(), slideOffset);
771
		logger.log(POILogger.INFO, "New slide ended up at " + slideOffset);
772
773
		slide.setMasterSheet(_masters[0]);
730
		slide.setMasterSheet(_masters[0]);
774
		// All done and added
731
		// All done and added
775
		return slide;
732
		return slide;
Lines 978-993 Link Here
978
	 * @return 0-based index of the movie
935
	 * @return 0-based index of the movie
979
	 */
936
	 */
980
	public int addMovie(String path, int type) {
937
	public int addMovie(String path, int type) {
981
		ExObjList lst = (ExObjList) _documentRecord.findFirstOfType(RecordTypes.ExObjList.typeID);
982
		if (lst == null) {
983
			lst = new ExObjList();
984
			_documentRecord.addChildAfter(lst, _documentRecord.getDocumentAtom());
985
		}
986
987
		ExObjListAtom objAtom = lst.getExObjListAtom();
988
		// increment the object ID seed
989
		int objectId = (int) objAtom.getObjectIDSeed() + 1;
990
		objAtom.setObjectIDSeed(objectId);
991
		ExMCIMovie mci;
938
		ExMCIMovie mci;
992
		switch (type) {
939
		switch (type) {
993
			case MovieShape.MOVIE_MPEG:
940
			case MovieShape.MOVIE_MPEG:
Lines 1000-1010 Link Here
1000
				throw new IllegalArgumentException("Unsupported Movie: " + type);
947
				throw new IllegalArgumentException("Unsupported Movie: " + type);
1001
		}
948
		}
1002
949
1003
		lst.appendChildRecord(mci);
1004
		ExVideoContainer exVideo = mci.getExVideo();
950
		ExVideoContainer exVideo = mci.getExVideo();
1005
		exVideo.getExMediaAtom().setObjectId(objectId);
1006
		exVideo.getExMediaAtom().setMask(0xE80000);
951
		exVideo.getExMediaAtom().setMask(0xE80000);
1007
		exVideo.getPathAtom().setText(path);
952
		exVideo.getPathAtom().setText(path);
953
954
		int objectId = addToObjListAtom(mci);
955
		exVideo.getExMediaAtom().setObjectId(objectId);
956
		
1008
		return objectId;
957
		return objectId;
1009
	}
958
	}
1010
959
Lines 1019-1045 Link Here
1019
	 * @return 0-based index of the control
968
	 * @return 0-based index of the control
1020
	 */
969
	 */
1021
	public int addControl(String name, String progId) {
970
	public int addControl(String name, String progId) {
1022
		ExObjList lst = (ExObjList) _documentRecord.findFirstOfType(RecordTypes.ExObjList.typeID);
1023
		if (lst == null) {
1024
			lst = new ExObjList();
1025
			_documentRecord.addChildAfter(lst, _documentRecord.getDocumentAtom());
1026
		}
1027
		ExObjListAtom objAtom = lst.getExObjListAtom();
1028
		// increment the object ID seed
1029
		int objectId = (int) objAtom.getObjectIDSeed() + 1;
1030
		objAtom.setObjectIDSeed(objectId);
1031
		ExControl ctrl = new ExControl();
971
		ExControl ctrl = new ExControl();
972
		ctrl.setProgId(progId);
973
		ctrl.setMenuName(name);
974
		ctrl.setClipboardName(name);
975
		
1032
		ExOleObjAtom oleObj = ctrl.getExOleObjAtom();
976
		ExOleObjAtom oleObj = ctrl.getExOleObjAtom();
1033
		oleObj.setObjID(objectId);
1034
		oleObj.setDrawAspect(ExOleObjAtom.DRAW_ASPECT_VISIBLE);
977
		oleObj.setDrawAspect(ExOleObjAtom.DRAW_ASPECT_VISIBLE);
1035
		oleObj.setType(ExOleObjAtom.TYPE_CONTROL);
978
		oleObj.setType(ExOleObjAtom.TYPE_CONTROL);
1036
		oleObj.setSubType(ExOleObjAtom.SUBTYPE_DEFAULT);
979
		oleObj.setSubType(ExOleObjAtom.SUBTYPE_DEFAULT);
1037
980
		
1038
		ctrl.setProgId(progId);
981
		int objectId = addToObjListAtom(ctrl);
1039
		ctrl.setMenuName(name);
982
		oleObj.setObjID(objectId);
1040
		ctrl.setClipboardName(name);
1041
		lst.addChildAfter(ctrl, objAtom);
1042
1043
		return objectId;
983
		return objectId;
1044
	}
984
	}
1045
985
Lines 1049-1067 Link Here
1049
	 * @return 0-based index of the hyperlink
989
	 * @return 0-based index of the hyperlink
1050
	 */
990
	 */
1051
	public int addHyperlink(Hyperlink link) {
991
	public int addHyperlink(Hyperlink link) {
1052
		ExObjList lst = (ExObjList) _documentRecord.findFirstOfType(RecordTypes.ExObjList.typeID);
1053
		if (lst == null) {
1054
			lst = new ExObjList();
1055
			_documentRecord.addChildAfter(lst, _documentRecord.getDocumentAtom());
1056
		}
1057
		ExObjListAtom objAtom = lst.getExObjListAtom();
1058
		// increment the object ID seed
1059
		int objectId = (int) objAtom.getObjectIDSeed() + 1;
1060
		objAtom.setObjectIDSeed(objectId);
1061
1062
		ExHyperlink ctrl = new ExHyperlink();
992
		ExHyperlink ctrl = new ExHyperlink();
1063
		ExHyperlinkAtom obj = ctrl.getExHyperlinkAtom();
993
		ExHyperlinkAtom obj = ctrl.getExHyperlinkAtom();
1064
		obj.setNumber(objectId);
1065
        if(link.getType() == Hyperlink.LINK_SLIDENUMBER) {
994
        if(link.getType() == Hyperlink.LINK_SLIDENUMBER) {
1066
            ctrl.setLinkURL(link.getAddress(), 0x30);
995
            ctrl.setLinkURL(link.getAddress(), 0x30);
1067
        } else {
996
        } else {
Lines 1068-1076 Link Here
1068
            ctrl.setLinkURL(link.getAddress());
997
            ctrl.setLinkURL(link.getAddress());
1069
        }
998
        }
1070
		ctrl.setLinkTitle(link.getTitle());
999
		ctrl.setLinkTitle(link.getTitle());
1071
		lst.addChildAfter(ctrl, objAtom);
1000
1001
		int objectId = addToObjListAtom(ctrl);
1072
		link.setId(objectId);
1002
		link.setId(objectId);
1003
		obj.setNumber(objectId);
1073
1004
1074
		return objectId;
1005
		return objectId;
1075
	}
1006
	}
1007
1008
	protected int addToObjListAtom(RecordContainer exObj) {
1009
		ExObjList lst = (ExObjList) _documentRecord.findFirstOfType(RecordTypes.ExObjList.typeID);
1010
		if (lst == null) {
1011
			lst = new ExObjList();
1012
			_documentRecord.addChildAfter(lst, _documentRecord.getDocumentAtom());
1013
		}
1014
		ExObjListAtom objAtom = lst.getExObjListAtom();
1015
		// increment the object ID seed
1016
		int objectId = (int) objAtom.getObjectIDSeed() + 1;
1017
		objAtom.setObjectIDSeed(objectId);
1018
1019
		lst.addChildAfter(exObj, objAtom);
1020
		
1021
		return objectId;
1022
	}
1023
1024
    protected int addPersistentObject(PositionDependentRecord slideRecord) {
1025
    	slideRecord.setLastOnDiskOffset(-1);
1026
		_hslfSlideShow.appendRootLevelRecord((Record)slideRecord);
1027
		_records = _hslfSlideShow.getRecords();
1028
1029
        // For position dependent records, hold where they were and now are
1030
        // As we go along, update, and hand over, to any Position Dependent
1031
        //  records we happen across
1032
        Hashtable<Integer,Integer> oldToNewPositions = new Hashtable<Integer,Integer>();
1033
1034
		// Add the new Slide into the PersistPtr stuff
1035
		int slideOffset = 0;
1036
1037
        // First pass - figure out where all the position dependent
1038
        //   records are going to end up, in the new scheme
1039
        // (Annoyingly, some powerpoing files have PersistPtrHolders
1040
        //  that reference slides after the PersistPtrHolder)
1041
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
1042
		for (Record record : _records) {
1043
			if(record instanceof PositionDependentRecord) {
1044
                PositionDependentRecord pdr = (PositionDependentRecord)record;
1045
                int oldPos = pdr.getLastOnDiskOffset();
1046
                int newPos = baos.size();
1047
                pdr.setLastOnDiskOffset(newPos);
1048
                if (record == slideRecord) {
1049
                	// set the slideOffset later, to not interfere with exisiting positions
1050
                	slideOffset = newPos;
1051
                } else {
1052
                	oldToNewPositions.put(Integer.valueOf(oldPos),Integer.valueOf(newPos));
1053
                }
1054
			
1055
			}
1056
			
1057
            // Dummy write out, so the position winds on properly
1058
			try {
1059
				record.writeOut(baos);
1060
			} catch (IOException e) {
1061
				throw new HSLFException(e);
1062
			}
1063
		}
1064
1065
		PersistPtrHolder ptr = null;
1066
		UserEditAtom usr = null;
1067
        // For now, we're only handling PositionDependentRecord's that
1068
        // happen at the top level.
1069
        // In future, we'll need the handle them everywhere, but that's
1070
        // a bit trickier
1071
		for (Record record : _records) {
1072
			if (!(record instanceof PositionDependentRecord)) continue;
1073
1074
			// We've already figured out their new location, and
1075
            // told them that
1076
            // Tell them of the positions of the other records though
1077
            PositionDependentRecord pdr = (PositionDependentRecord)record;
1078
            pdr.updateOtherRecordReferences(oldToNewPositions);
1079
1080
            // Grab interesting records as they come past
1081
			int recordType = (int)record.getRecordType();
1082
            if (recordType == RecordTypes.PersistPtrIncrementalBlock.typeID) {
1083
                ptr = (PersistPtrHolder)record;
1084
            } else if (recordType == RecordTypes.UserEditAtom.typeID) {
1085
                usr = (UserEditAtom)record;
1086
            }
1087
		}
1088
		
1089
		// persist ID is UserEditAtom.maxPersistWritten + 1
1090
		int psrId = usr.getMaxPersistWritten() + 1;
1091
1092
		// Last view is now of the slide
1093
		usr.setLastViewType((short) UserEditAtom.LAST_VIEW_SLIDE_VIEW);
1094
		// increment the number of persistent objects
1095
		usr.setMaxPersistWritten(psrId);
1096
		_hslfSlideShow.getCurrentUserAtom().setCurrentEditOffset(usr.getLastOnDiskOffset());
1097
1098
		// Add the new slide into the last PersistPtr
1099
		// (Also need to tell it where it is)
1100
		slideRecord.setLastOnDiskOffset(slideOffset);
1101
		ptr.addSlideLookup(psrId, slideOffset);
1102
		logger.log(POILogger.INFO, "New slide/object ended up at " + slideOffset);
1103
1104
		return psrId;
1105
    }
1076
}
1106
}
(-)src/scratchpad/testcases/org/apache/poi/hslf/TestReWrite.java (+12 lines)
Lines 160-163 Link Here
160
			assertEquals(_oData[i], _nData[i]);
160
			assertEquals(_oData[i], _nData[i]);
161
		}
161
		}
162
	}
162
	}
163
    
164
    public void test48593() throws Exception {
165
		SlideShow slideShow = new SlideShow();
166
		slideShow.createSlide();
167
		slideShow = HSLFTestDataSamples.writeOutAndReadBack(slideShow);
168
		slideShow.createSlide();
169
		slideShow = HSLFTestDataSamples.writeOutAndReadBack(slideShow);
170
		slideShow.createSlide();
171
		slideShow = HSLFTestDataSamples.writeOutAndReadBack(slideShow);
172
		slideShow.createSlide();
173
		slideShow = HSLFTestDataSamples.writeOutAndReadBack(slideShow);
174
    }
163
}
175
}
(-)src/scratchpad/testcases/org/apache/poi/hslf/HSLFTestDataSamples.java (+74 lines)
Line 0 Link Here
1
/* ====================================================================
2
   Licensed to the Apache Software Foundation (ASF) under one or more
3
   contributor license agreements.  See the NOTICE file distributed with
4
   this work for additional information regarding copyright ownership.
5
   The ASF licenses this file to You under the Apache License, Version 2.0
6
   (the "License"); you may not use this file except in compliance with
7
   the License.  You may obtain a copy of the License at
8
9
       http://www.apache.org/licenses/LICENSE-2.0
10
11
   Unless required by applicable law or agreed to in writing, software
12
   distributed under the License is distributed on an "AS IS" BASIS,
13
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
   See the License for the specific language governing permissions and
15
   limitations under the License.
16
==================================================================== */
17
18
package org.apache.poi.hslf;
19
20
import java.io.ByteArrayInputStream;
21
import java.io.ByteArrayOutputStream;
22
import java.io.File;
23
import java.io.IOException;
24
import java.io.InputStream;
25
26
import org.apache.poi.POIDataSamples;
27
import org.apache.poi.hslf.usermodel.SlideShow;
28
29
public class HSLFTestDataSamples {
30
31
	private static final POIDataSamples _inst = POIDataSamples.getSlideShowInstance();
32
33
	public static InputStream openSampleFileStream(String sampleFileName) {
34
		return _inst.openResourceAsStream(sampleFileName);
35
	}
36
	public static File getSampleFile(String sampleFileName) {
37
	   return _inst.getFile(sampleFileName);
38
	}
39
	public static byte[] getTestDataFileContent(String fileName) {
40
		return _inst.readFile(fileName);
41
	}
42
43
	/**
44
	 * Writes a slideshow to a <tt>ByteArrayOutputStream</tt> and reads it back
45
	 * from a <tt>ByteArrayInputStream</tt>.<p/>
46
	 * Useful for verifying that the serialisation round trip
47
	 */
48
	public static HSLFSlideShow writeOutAndReadBack(HSLFSlideShow original) {
49
		try {
50
			ByteArrayOutputStream baos = new ByteArrayOutputStream(4096);
51
			original.write(baos);
52
			ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
53
			return new HSLFSlideShow(bais);
54
		} catch (IOException e) {
55
			throw new RuntimeException(e);
56
		}
57
	}
58
59
	/**
60
	 * Writes a slideshow to a <tt>ByteArrayOutputStream</tt> and reads it back
61
	 * from a <tt>ByteArrayInputStream</tt>.<p/>
62
	 * Useful for verifying that the serialisation round trip
63
	 */
64
	public static SlideShow writeOutAndReadBack(SlideShow original) {
65
		try {
66
			ByteArrayOutputStream baos = new ByteArrayOutputStream(4096);
67
			original.write(baos);
68
			ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
69
			return new SlideShow(bais);
70
		} catch (IOException e) {
71
			throw new RuntimeException(e);
72
		}
73
	}
74
}

Return to bug 48593