protected int addPersistentObject(PositionDependentRecord slideRecord) { slideRecord.setLastOnDiskOffset(HSLFSlideShowImpl.UNSET_OFFSET); _hslfSlideShow.appendRootLevelRecord((Record) slideRecord); // 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 Map<RecordTypes.Type, PositionDependentRecord> interestingRecords = new HashMap<RecordTypes.Type, PositionDependentRecord>(); try { _hslfSlideShow.updateAndWriteDependantRecords(null, interestingRecords); } catch (IOException e) { throw new HSLFException(e); } PersistPtrHolder ptr = (PersistPtrHolder) interestingRecords.get(RecordTypes.PersistPtrIncrementalBlock); UserEditAtom usr = (UserEditAtom) interestingRecords.get(RecordTypes.UserEditAtom); // 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); // Add the new slide into the last PersistPtr // (Also need to tell it where it is) int slideOffset = slideRecord.getLastOnDiskOffset(); slideRecord.setLastOnDiskOffset(slideOffset); ptr.addSlideLookup(psrId, slideOffset); logger.log(POILogger.INFO, "New slide/object ended up at " + slideOffset); return psrId; }
/** * Use the PersistPtrHolder entries to figure out what is the "most recent" version of all the * core records (Document, Notes, Slide etc), and save a record of them. Do this by walking from * the oldest PersistPtr to the newest, overwriting any references found along the way with newer * ones */ private void findMostRecentCoreRecords() { // To start with, find the most recent in the byte offset domain Map<Integer, Integer> mostRecentByBytes = new HashMap<Integer, Integer>(); for (Record record : _hslfSlideShow.getRecords()) { if (record instanceof PersistPtrHolder) { PersistPtrHolder pph = (PersistPtrHolder) record; // If we've already seen any of the "slide" IDs for this // PersistPtr, remove their old positions int[] ids = pph.getKnownSlideIDs(); for (int id : ids) { if (mostRecentByBytes.containsKey(id)) { mostRecentByBytes.remove(id); } } // Now, update the byte level locations with their latest values Map<Integer, Integer> thisSetOfLocations = pph.getSlideLocationsLookup(); for (int id : ids) { mostRecentByBytes.put(id, thisSetOfLocations.get(id)); } } } // We now know how many unique special records we have, so init // the array _mostRecentCoreRecords = new Record[mostRecentByBytes.size()]; // We'll also want to be able to turn the slide IDs into a position // in this array _sheetIdToCoreRecordsLookup = new HashMap<Integer, Integer>(); Integer[] allIDs = mostRecentByBytes.keySet().toArray(new Integer[mostRecentByBytes.size()]); Arrays.sort(allIDs); for (int i = 0; i < allIDs.length; i++) { _sheetIdToCoreRecordsLookup.put(allIDs[i], i); } Map<Integer, Integer> mostRecentByBytesRev = new HashMap<Integer, Integer>(mostRecentByBytes.size()); for (Map.Entry<Integer, Integer> me : mostRecentByBytes.entrySet()) { mostRecentByBytesRev.put(me.getValue(), me.getKey()); } // Now convert the byte offsets back into record offsets for (Record record : _hslfSlideShow.getRecords()) { if (!(record instanceof PositionDependentRecord)) continue; PositionDependentRecord pdr = (PositionDependentRecord) record; int recordAt = pdr.getLastOnDiskOffset(); Integer thisID = mostRecentByBytesRev.get(recordAt); if (thisID == null) continue; // Bingo. Now, where do we store it? int storeAt = _sheetIdToCoreRecordsLookup.get(thisID); // Tell it its Sheet ID, if it cares if (pdr instanceof PositionDependentRecordContainer) { PositionDependentRecordContainer pdrc = (PositionDependentRecordContainer) record; pdrc.setSheetId(thisID); } // Finally, save the record _mostRecentCoreRecords[storeAt] = record; } // Now look for the interesting records in there for (Record record : _mostRecentCoreRecords) { // Check there really is a record at this number if (record != null) { // Find the Document, and interesting things in it if (record.getRecordType() == RecordTypes.Document.typeID) { _documentRecord = (Document) record; _fonts = _documentRecord.getEnvironment().getFontCollection(); } } else { // No record at this number // Odd, but not normally a problem } } }