📄 hslfslideshow.java
字号:
/** * Find the "Current User" stream, and load it */ private void readCurrentUserStream() { try { currentUser = new CurrentUserAtom(filesystem); } catch(IOException ie) { logger.log(POILogger.ERROR, "Error finding Current User Atom:\n" + ie); currentUser = new CurrentUserAtom(); } } /** * Find any other streams from the filesystem, and load them */ private void readOtherStreams() { // Currently, there aren't any } /** * Find and read in pictures contained in this presentation */ private void readPictures() throws IOException { byte[] pictstream; try { DocumentEntry entry = (DocumentEntry)filesystem.getRoot().getEntry("Pictures"); pictstream = new byte[entry.getSize()]; DocumentInputStream is = filesystem.createDocumentInputStream("Pictures"); is.read(pictstream); } catch (FileNotFoundException e){ // Silently catch exceptions if the presentation doesn't // contain pictures - will use a null set instead return; } List p = new ArrayList(); int pos = 0; // An empty picture record (length 0) will take up 8 bytes while (pos <= (pictstream.length-8)) { int offset = pos; // Image signature int signature = LittleEndian.getUShort(pictstream, pos); pos += LittleEndian.SHORT_SIZE; // Image type + 0xF018 int type = LittleEndian.getUShort(pictstream, pos); pos += LittleEndian.SHORT_SIZE; // Image size (excluding the 8 byte header) int imgsize = LittleEndian.getInt(pictstream, pos); pos += LittleEndian.INT_SIZE; // The image size must be 0 or greater // (0 is allowed, but odd, since we do wind on by the header each // time, so we won't get stuck) if(imgsize < 0) { throw new CorruptPowerPointFileException("The file contains a picture, at position " + p.size() + ", which has a negatively sized data length, so we can't trust any of the picture data"); } // If they type (including the bonus 0xF018) is 0, skip it if(type == 0) { logger.log(POILogger.ERROR, "Problem reading picture: Invalid image type 0, on picture with length " + imgsize + ".\nYou document will probably become corrupted if you save it!"); logger.log(POILogger.ERROR, "" + pos); } else { // Copy the data, ready to pass to PictureData byte[] imgdata = new byte[imgsize]; if(imgsize > 0) { System.arraycopy(pictstream, pos, imgdata, 0, imgdata.length); } // Build the PictureData object from the data try { PictureData pict = PictureData.create(type - 0xF018); pict.setRawData(imgdata); pict.setOffset(offset); p.add(pict); } catch(IllegalArgumentException e) { logger.log(POILogger.ERROR, "Problem reading picture: " + e + "\nYou document will probably become corrupted if you save it!"); } } pos += imgsize; } _pictures = (PictureData[])p.toArray(new PictureData[p.size()]); } /** * Writes out the slideshow file the is represented by an instance of * this class * @param out The OutputStream to write to. * @throws IOException If there is an unexpected IOException from the passed * in OutputStream */ public void write(OutputStream out) throws IOException { // Get a new Filesystem to write into POIFSFileSystem outFS = new POIFSFileSystem(); // Write out the Property Streams writeProperties(outFS); // 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 oldToNewPositions = new Hashtable(); // 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(int i=0; i<_records.length; i++) { if(_records[i] instanceof PositionDependentRecord) { PositionDependentRecord pdr = (PositionDependentRecord)_records[i]; int oldPos = pdr.getLastOnDiskOffset(); int newPos = baos.size(); pdr.setLastOnDiskOffset(newPos); oldToNewPositions.put(new Integer(oldPos),new Integer(newPos)); //System.out.println(oldPos + " -> " + newPos); } // Dummy write out, so the position winds on properly _records[i].writeOut(baos); } // No go back through, actually writing ourselves out baos.reset(); for(int i=0; i<_records.length; i++) { // 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 if(_records[i] instanceof PositionDependentRecord) { // 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)_records[i]; pdr.updateOtherRecordReferences(oldToNewPositions); } // Whatever happens, write out that record tree _records[i].writeOut(baos); } // Update our cached copy of the bytes that make up the PPT stream _docstream = baos.toByteArray(); // Write the PPT stream into the POIFS layer ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); outFS.createDocument(bais,"PowerPoint Document"); // Update and write out the Current User atom int oldLastUserEditAtomPos = (int)currentUser.getCurrentEditOffset(); Integer newLastUserEditAtomPos = (Integer)oldToNewPositions.get(new Integer(oldLastUserEditAtomPos)); if(newLastUserEditAtomPos == null) { throw new HSLFException("Couldn't find the new location of the UserEditAtom that used to be at " + oldLastUserEditAtomPos); } currentUser.setCurrentEditOffset(newLastUserEditAtomPos.intValue()); currentUser.writeToFS(outFS); // Write any pictures, into another stream if (_pictures != null) { ByteArrayOutputStream pict = new ByteArrayOutputStream(); for (int i = 0; i < _pictures.length; i++ ) { _pictures[i].write(pict); } outFS.createDocument( new ByteArrayInputStream(pict.toByteArray()), "Pictures" ); } // Send the POIFSFileSystem object out to the underlying stream outFS.writeFilesystem(out); } /* ******************* adding methods follow ********************* */ /** * Adds a new root level record, at the end, but before the last * PersistPtrIncrementalBlock. */ public synchronized int appendRootLevelRecord(Record newRecord) { int addedAt = -1; Record[] r = new Record[_records.length+1]; boolean added = false; for(int i=(_records.length-1); i>=0; i--) { if(added) { // Just copy over r[i] = _records[i]; } else { r[(i+1)] = _records[i]; if(_records[i] instanceof PersistPtrHolder) { r[i] = newRecord; added = true; addedAt = i; } } } _records = r; return addedAt; } /** * Add a new picture to this presentation. */ public void addPicture(PictureData img) { // Copy over the existing pictures, into an array one bigger PictureData[] lst; if(_pictures == null) { lst = new PictureData[1]; } else { lst = new PictureData[(_pictures.length+1)]; System.arraycopy(_pictures,0,lst,0,_pictures.length); } // Add in the new image lst[lst.length - 1] = img; _pictures = lst; } /* ******************* fetching methods follow ********************* */ /** * Returns an array of all the records found in the slideshow */ public Record[] getRecords() { return _records; } /** * Returns an array of the bytes of the file. Only correct after a * call to open or write - at all other times might be wrong! */ public byte[] getUnderlyingBytes() { return _docstream; } /** * Fetch the Current User Atom of the document */ public CurrentUserAtom getCurrentUserAtom() { return currentUser; } /** * Return array of pictures contained in this presentation * * @return array with the read pictures or <code>null</code> if the * presentation doesn't contain pictures. */ public PictureData[] getPictures() { return _pictures; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -