]> source.dussan.org Git - poi.git/commitdiff
NDocumentOutputStream write logic
authorNick Burch <nick@apache.org>
Fri, 25 Apr 2014 23:34:09 +0000 (23:34 +0000)
committerNick Burch <nick@apache.org>
Fri, 25 Apr 2014 23:34:09 +0000 (23:34 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1590191 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/hpsf/MutablePropertySet.java
src/java/org/apache/poi/hpsf/SpecialPropertySet.java
src/java/org/apache/poi/poifs/filesystem/NDocumentOutputStream.java
src/java/org/apache/poi/poifs/filesystem/NPOIFSDocument.java
src/testcases/org/apache/poi/hpsf/basic/TestWrite.java

index 2604cbe32437ef854bb64691203c936d2ea3799b..304141113e96e8f6b5d7597d71d8207fd639f56e 100644 (file)
@@ -246,6 +246,9 @@ public class MutablePropertySet extends PropertySet
             final MutableSection s = (MutableSection) i.next();
             offset += s.write(out);
         }
+        
+        /* Indicate that we're done */
+        out.close();
     }
 
 
index 993765f6a5d1a6c036f3044e664ec7b3b18b5dda..4bcd8ca71ffcd9fd2890968fd00a3a7d35d68b35 100644 (file)
@@ -261,8 +261,6 @@ public abstract class SpecialPropertySet extends MutablePropertySet
         delegate.write(dir, name);
     }
 
-
-
     /**
      * @see org.apache.poi.hpsf.MutablePropertySet#write(java.io.OutputStream)
      */
@@ -271,8 +269,6 @@ public abstract class SpecialPropertySet extends MutablePropertySet
         delegate.write(out);
     }
 
-
-
     /**
      * @see org.apache.poi.hpsf.PropertySet#equals(java.lang.Object)
      */
@@ -281,8 +277,6 @@ public abstract class SpecialPropertySet extends MutablePropertySet
         return delegate.equals(o);
     }
 
-
-
     /**
      * @see org.apache.poi.hpsf.PropertySet#getProperties()
      */
@@ -291,8 +285,6 @@ public abstract class SpecialPropertySet extends MutablePropertySet
         return delegate.getProperties();
     }
 
-
-
     /**
      * @see org.apache.poi.hpsf.PropertySet#getProperty(int)
      */
index 0215009475850f11fa6965590a0237c4aebbc040..6d4d13d5d1d00aacbaf829e1f4b66f33b9a21ae6 100644 (file)
 package org.apache.poi.poifs.filesystem;
 
 import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
 
+import org.apache.poi.poifs.common.POIFSConstants;
+import org.apache.poi.poifs.property.DocumentProperty;
+
 /**
  * This class provides methods to write a DocumentEntry managed by a
  * {@link NPOIFSFileSystem} instance.
@@ -34,6 +38,16 @@ public final class NDocumentOutputStream extends OutputStream {
 
        /** the actual Document */
        private NPOIFSDocument _document;
+       /** and its Property */
+       private DocumentProperty _property;
+       
+       /** our buffer, when null we're into normal blocks */
+       private ByteArrayOutputStream _buffer = 
+               new ByteArrayOutputStream(POIFSConstants.BIG_BLOCK_MINIMUM_DOCUMENT_SIZE);
+       
+       /** our main block stream, when we're into normal blocks */
+       private NPOIFSStream _stream;
+       private OutputStream _stream_output;
        
        /**
         * Create an OutputStream from the specified DocumentEntry.
@@ -48,6 +62,8 @@ public final class NDocumentOutputStream extends OutputStream {
                _document_size = 0;
                _closed = false;
                
+               _property = (DocumentProperty)((DocumentNode)document).getProperty();
+               
                _document = new NPOIFSDocument((DocumentNode)document);
                _document.free();
        }
@@ -67,22 +83,81 @@ public final class NDocumentOutputStream extends OutputStream {
 
         // Have an empty one created for now
         DocumentEntry doc = parent.createDocument(name, new ByteArrayInputStream(new byte[0]));
+        _property = (DocumentProperty)((DocumentNode)doc).getProperty();
         _document = new NPOIFSDocument((DocumentNode)doc);
        }
+       
+    private void dieIfClosed() throws IOException {
+        if (_closed) {
+            throw new IOException("cannot perform requested operation on a closed stream");
+        }
+    }
+    
+    private void checkBufferSize() throws IOException {
+        // Have we gone over the mini stream limit yet?
+        if (_buffer.size() > POIFSConstants.BIG_BLOCK_MINIMUM_DOCUMENT_SIZE) {
+            // Will need to be in the main stream
+            byte[] data = _buffer.toByteArray();
+            _buffer = null;
+            write(data, 0, data.length);
+        } else {
+            // So far, mini stream will work, keep going
+        }
+    }
 
     public void write(int b) throws IOException {
-        // TODO
+        dieIfClosed();
+        
+        if (_buffer != null) {
+            _buffer.write(b);
+            checkBufferSize();
+        } else {
+            write(new byte[] { (byte)b });
+        }
     }
 
     public void write(byte[] b) throws IOException {
-        // TODO
+        dieIfClosed();
+        
+        if (_buffer != null) {
+            _buffer.write(b);
+            checkBufferSize();
+        } else {
+            write(b, 0, b.length);
+        }
     }
 
     public void write(byte[] b, int off, int len) throws IOException {
-        // TODO
+        dieIfClosed();
+        
+        if (_buffer != null) {
+            _buffer.write(b, off, len);
+            checkBufferSize();
+        } else {
+            if (_stream == null) {
+                _stream = new NPOIFSStream(_document.getFileSystem());
+                _stream_output = _stream.getOutputStream();
+            }
+            _stream_output.write(b, off, len);
+            _document_size += len;
+        }
     }
 
     public void close() throws IOException {
-        // TODO
+        // Do we have a pending buffer for the mini stream?
+        if (_buffer != null) {
+            // It's not much data, so ask NPOIFSDocument to do it for us
+            _document.replaceContents(new ByteArrayInputStream(_buffer.toByteArray()));
+        }
+        else {
+            // We've been writing to the stream as we've gone along
+            // Update the details on the property now
+            _stream_output.close();
+            _property.updateSize(_document_size);
+            _property.setStartBlock(_stream.getStartBlock());
+        }
+        
+        // No more!
+        _closed = true;
     }
 }
index affaa161254413f6490f6760e097ba24d2244ffc..99613c5ea11a4c11304d598dd821c1b2d05c9c74 100644 (file)
@@ -154,6 +154,11 @@ public final class NPOIFSDocument implements POIFSViewable {
        _property.setStartBlock(POIFSConstants.END_OF_CHAIN);
    }
    
+   NPOIFSFileSystem getFileSystem()
+   {
+       return _filesystem;
+   }
+   
    int getDocumentBlockSize() {
       return _block_size;
    }
index 8e228f68717b4f837ee2a3708e428917c2fcf0b3..e4cf9b5ebd7d86bae61629907b67a5f7ac978ece 100644 (file)
@@ -799,9 +799,8 @@ public class TestWrite extends TestCase
     /**
      * Tests that when using NPOIFS, we can do an in-place write
      *  without needing to stream in + out the whole kitchen sink
-     * TODO Finish implementing the logic for this
      */
-    public void DISBALEDtestInPlaceNPOIFSWrite() throws Exception {
+    public void DISABLEDtestInPlaceNPOIFSWrite() throws Exception {
         NPOIFSFileSystem fs = null;
         DirectoryEntry root = null;
         DocumentNode sinfDoc = null;