In-place write for HSLF #57919

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1753741 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Nick Burch 2016-07-21 23:25:02 +00:00
parent 13a7be6cd2
commit 5a1ff54cf3
3 changed files with 46 additions and 15 deletions

View File

@ -279,6 +279,6 @@ public class CurrentUserAtom
new ByteArrayInputStream(baos.toByteArray()); new ByteArrayInputStream(baos.toByteArray());
// Write out // Write out
fs.createDocument(bais,"Current User"); fs.createOrUpdateDocument(bais,"Current User");
} }
} }

View File

@ -537,16 +537,37 @@ public final class HSLFSlideShowImpl extends POIDocument implements Closeable {
// Update and write out the Current User atom // Update and write out the Current User atom
int oldLastUserEditAtomPos = (int)currentUser.getCurrentEditOffset(); int oldLastUserEditAtomPos = (int)currentUser.getCurrentEditOffset();
Integer newLastUserEditAtomPos = oldToNewPositions.get(oldLastUserEditAtomPos); Integer newLastUserEditAtomPos = oldToNewPositions.get(oldLastUserEditAtomPos);
if(newLastUserEditAtomPos == null || usr.getLastOnDiskOffset() != newLastUserEditAtomPos) { if (newLastUserEditAtomPos == null || usr.getLastOnDiskOffset() != newLastUserEditAtomPos) {
throw new HSLFException("Couldn't find the new location of the last UserEditAtom that used to be at " + oldLastUserEditAtomPos); throw new HSLFException("Couldn't find the new location of the last UserEditAtom that used to be at " + oldLastUserEditAtomPos);
} }
currentUser.setCurrentEditOffset(usr.getLastOnDiskOffset()); currentUser.setCurrentEditOffset(usr.getLastOnDiskOffset());
} }
@Override /**
public void write() throws IOException { * Writes out the slideshow to the currently open file.
throw new IllegalStateException("In-Place write coming soon! See Bug #57919"); *
} * <p>This will fail (with an {@link IllegalStateException} if the
* slideshow was opened read-only, opened from an {@link InputStream}
* instead of a File, or if this is not the root document. For those cases,
* you must use {@link #write(OutputStream)} or {@link #write(File)} to
* write to a brand new document.
*
* @since POI 3.15 beta 3
*
* @throws IOException thrown on errors writing to the file
* @throws IllegalStateException if this isn't from a writable File
*/
@Override
public void write() throws IOException {
validateInPlaceWritePossible();
// Write the PowerPoint streams to the current FileSystem
// No need to do anything to other streams, already there!
write(directory.getFileSystem(), false);
// Sync with the File on disk
directory.getFileSystem().writeFilesystem();
}
/** /**
* Writes out the slideshow file the is represented by an instance * Writes out the slideshow file the is represented by an instance
@ -625,7 +646,7 @@ public final class HSLFSlideShowImpl extends POIDocument implements Closeable {
outFS.close(); outFS.close();
} }
} }
private void write(POIFSFileSystem outFS, boolean preserveNodes) throws IOException { private void write(NPOIFSFileSystem outFS, boolean copyAllOtherNodes) throws IOException {
// read properties and pictures, with old encryption settings where appropriate // read properties and pictures, with old encryption settings where appropriate
if (_pictures == null) { if (_pictures == null) {
readPictures(); readPictures();
@ -656,7 +677,7 @@ public final class HSLFSlideShowImpl extends POIDocument implements Closeable {
// Write the PPT stream into the POIFS layer // Write the PPT stream into the POIFS layer
ByteArrayInputStream bais = new ByteArrayInputStream(_docstream); ByteArrayInputStream bais = new ByteArrayInputStream(_docstream);
outFS.createDocument(bais,"PowerPoint Document"); outFS.createOrUpdateDocument(bais,"PowerPoint Document");
writtenEntries.add("PowerPoint Document"); writtenEntries.add("PowerPoint Document");
currentUser.setEncrypted(encryptedSS.getDocumentEncryptionAtom() != null); currentUser.setEncrypted(encryptedSS.getDocumentEncryptionAtom() != null);
@ -671,15 +692,15 @@ public final class HSLFSlideShowImpl extends POIDocument implements Closeable {
p.write(pict); p.write(pict);
encryptedSS.encryptPicture(pict.getBuf(), offset); encryptedSS.encryptPicture(pict.getBuf(), offset);
} }
outFS.createDocument( outFS.createOrUpdateDocument(
new ByteArrayInputStream(pict.getBuf(), 0, pict.size()), "Pictures" new ByteArrayInputStream(pict.getBuf(), 0, pict.size()), "Pictures"
); );
writtenEntries.add("Pictures"); writtenEntries.add("Pictures");
pict.close(); pict.close();
} }
// If requested, write out any other streams we spot // If requested, copy over any other streams we spot, eg Macros
if (preserveNodes) { if (copyAllOtherNodes) {
EntryUtils.copyNodes(directory.getFileSystem(), outFS, writtenEntries); EntryUtils.copyNodes(directory.getFileSystem(), outFS, writtenEntries);
} }
} }
@ -706,7 +727,7 @@ public final class HSLFSlideShowImpl extends POIDocument implements Closeable {
* @throws IOException if an error when writing to the * @throws IOException if an error when writing to the
* {@link POIFSFileSystem} occurs * {@link POIFSFileSystem} occurs
*/ */
protected void writeProperties(POIFSFileSystem outFS, List<String> writtenEntries) throws IOException { protected void writeProperties(NPOIFSFileSystem outFS, List<String> writtenEntries) throws IOException {
super.writeProperties(outFS, writtenEntries); super.writeProperties(outFS, writtenEntries);
DocumentEncryptionAtom dea = getDocumentEncryptionAtom(); DocumentEncryptionAtom dea = getDocumentEncryptionAtom();
if (dea != null) { if (dea != null) {

View File

@ -79,7 +79,9 @@ public final class TestReWrite {
hss.write(baos); hss.write(baos);
final File file = TempFile.createTempFile("TestHSLF", ".ppt"); final File file = TempFile.createTempFile("TestHSLF", ".ppt");
final File file2 = TempFile.createTempFile("TestHSLF", ".ppt");
hss.write(file); hss.write(file);
hss.write(file2);
// Build an input stream of it, and read back as a POIFS from the stream // Build an input stream of it, and read back as a POIFS from the stream
@ -89,7 +91,15 @@ public final class TestReWrite {
// And the same on the temp file // And the same on the temp file
POIFSFileSystem npfF = new POIFSFileSystem(file); POIFSFileSystem npfF = new POIFSFileSystem(file);
for (POIFSFileSystem npf : new POIFSFileSystem[] { npfS, npfF }) { // And another where we do an in-place write
POIFSFileSystem npfRF = new POIFSFileSystem(file2, false);
HSLFSlideShowImpl hssRF = new HSLFSlideShowImpl(npfRF);
hssRF.write();
hssRF.close();
npfRF = new POIFSFileSystem(file2);
// Check all of them in turn
for (POIFSFileSystem npf : new POIFSFileSystem[] { npfS, npfF, npfRF }) {
// Check that the "PowerPoint Document" sections have the same size // Check that the "PowerPoint Document" sections have the same size
DocumentEntry oProps = (DocumentEntry)pfs.getRoot().getEntry("PowerPoint Document"); DocumentEntry oProps = (DocumentEntry)pfs.getRoot().getEntry("PowerPoint Document");
DocumentEntry nProps = (DocumentEntry)npf.getRoot().getEntry("PowerPoint Document"); DocumentEntry nProps = (DocumentEntry)npf.getRoot().getEntry("PowerPoint Document");