]> source.dussan.org Git - poi.git/commitdiff
Correct NPOIFS mini stream first write bug, and add more NPOIFS stream write tests
authorNick Burch <nick@apache.org>
Thu, 24 Apr 2014 21:08:34 +0000 (21:08 +0000)
committerNick Burch <nick@apache.org>
Thu, 24 Apr 2014 21:08:34 +0000 (21:08 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1589881 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/poifs/filesystem/NPOIFSMiniStore.java
src/testcases/org/apache/poi/poifs/filesystem/TestNPOIFSFileSystem.java

index 33d0b25418540ad9cc747db8ff6688a27538edf6..4339fdcd1f3a9a3093d58fe1fa21dce279f11a7a 100644 (file)
@@ -27,9 +27,9 @@ import java.util.List;
 import org.apache.poi.poifs.common.POIFSConstants;
 import org.apache.poi.poifs.property.RootProperty;
 import org.apache.poi.poifs.storage.BATBlock;
+import org.apache.poi.poifs.storage.BATBlock.BATBlockAndIndex;
 import org.apache.poi.poifs.storage.BlockAllocationTableWriter;
 import org.apache.poi.poifs.storage.HeaderBlock;
-import org.apache.poi.poifs.storage.BATBlock.BATBlockAndIndex;
 
 /**
  * This class handles the MiniStream (small block store)
@@ -86,6 +86,11 @@ public class NPOIFSMiniStore extends BlockStore
      * Load the block, extending the underlying stream if needed
      */
     protected ByteBuffer createBlockIfNeeded(final int offset) throws IOException {
+       // Ensure we have our first block at this point
+       if (_mini_stream.getStartBlock() == POIFSConstants.END_OF_CHAIN) {
+           getFreeBlock();
+       }
+        
        // Try to get it without extending the stream
        try {
           return getBlockAt(offset);
@@ -186,6 +191,7 @@ public class NPOIFSMiniStore extends BlockStore
        if(_header.getSBATCount() == 0) {
           _header.setSBATStart(batForSBAT);
           _header.setSBATBlockCount(1);
+          _mini_stream = new NPOIFSStream(_filesystem, batForSBAT);
        } else {
           // Find the end of the SBAT stream, and add the sbat in there
           ChainLoopDetector loopDetector = _filesystem.getChainLoopDetector();
index b23feb29d1b83af3438122d361be54f260783367..a5617ef2793ed8c0e5fc77adfba7c46ef787ad42 100644 (file)
@@ -681,10 +681,140 @@ public final class TestNPOIFSFileSystem {
       assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(3));
       assertEquals(POIFSConstants.END_OF_CHAIN, fs.getRoot().getProperty().getStartBlock());
 
-      // Now add a normal stream and a mini stream
-      // TODO
       
-      // TODO The rest of the test
+      // Put everything within a new directory
+      DirectoryEntry testDir = fs.createDirectory("Test Directory");
+      
+      // Add a new Normal Stream (Normal Streams minimum 4096 bytes)
+      byte[] main4096 = new byte[4096];
+      main4096[0] = -10;
+      main4096[4095] = -11;
+      testDir.createDocument("Normal4096", new ByteArrayInputStream(main4096));
+
+      assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(0));
+      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(1));
+      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(2));
+      if (fs.getBigBlockSize() == POIFSConstants.SMALLER_BIG_BLOCK_SIZE) {
+          assertEquals(4, fs.getNextBlock(3));
+          assertEquals(5, fs.getNextBlock(4));
+          assertEquals(6, fs.getNextBlock(5));
+          assertEquals(7, fs.getNextBlock(6));
+          assertEquals(8, fs.getNextBlock(7));
+          assertEquals(9, fs.getNextBlock(8));
+          assertEquals(10, fs.getNextBlock(9));
+          assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(10));
+          assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(11));
+      } else {
+          assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(3));
+          assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(4));
+      }
+      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getRoot().getProperty().getStartBlock());
+
+      
+      // Add a bigger Normal Stream
+      byte[] main5124 = new byte[5124];
+      main5124[0] = -22;
+      main5124[5123] = -33;
+      testDir.createDocument("Normal5124", new ByteArrayInputStream(main5124));
+
+      assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(0));
+      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(1));
+      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(2));
+      if (fs.getBigBlockSize() == POIFSConstants.SMALLER_BIG_BLOCK_SIZE) {
+          assertEquals(4, fs.getNextBlock(3));
+          assertEquals(5, fs.getNextBlock(4));
+          assertEquals(6, fs.getNextBlock(5));
+          assertEquals(7, fs.getNextBlock(6));
+          assertEquals(8, fs.getNextBlock(7));
+          assertEquals(9, fs.getNextBlock(8));
+          assertEquals(10, fs.getNextBlock(9));
+          assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(10));
+
+          assertEquals(12, fs.getNextBlock(11));
+          assertEquals(13, fs.getNextBlock(12));
+          assertEquals(14, fs.getNextBlock(13));
+          assertEquals(15, fs.getNextBlock(14));
+          assertEquals(16, fs.getNextBlock(15));
+          assertEquals(17, fs.getNextBlock(16));
+          assertEquals(18, fs.getNextBlock(17));
+          assertEquals(19, fs.getNextBlock(18));
+          assertEquals(20, fs.getNextBlock(19));
+          assertEquals(21, fs.getNextBlock(20));
+          assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(21));
+          assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(22));
+      } else {
+          assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(3));
+          assertEquals(5,                           fs.getNextBlock(4));
+          assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(5));
+          assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(6));
+      }
+      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getRoot().getProperty().getStartBlock());
+      
+      
+      // Now Add a mini stream
+      byte[] mini = new byte[] { 0, 1, 2, 3, 4 };
+      testDir.createDocument("Mini", new ByteArrayInputStream(mini));
+      
+      // Mini stream will get one block for fat + one block for data
+      assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(0));
+      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(1));
+      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(2));
+      if (fs.getBigBlockSize() == POIFSConstants.SMALLER_BIG_BLOCK_SIZE) {
+          assertEquals(4, fs.getNextBlock(3));
+          assertEquals(5, fs.getNextBlock(4));
+          assertEquals(6, fs.getNextBlock(5));
+          assertEquals(7, fs.getNextBlock(6));
+          assertEquals(8, fs.getNextBlock(7));
+          assertEquals(9, fs.getNextBlock(8));
+          assertEquals(10, fs.getNextBlock(9));
+          assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(10));
+
+          assertEquals(12, fs.getNextBlock(11));
+          assertEquals(13, fs.getNextBlock(12));
+          assertEquals(14, fs.getNextBlock(13));
+          assertEquals(15, fs.getNextBlock(14));
+          assertEquals(16, fs.getNextBlock(15));
+          assertEquals(17, fs.getNextBlock(16));
+          assertEquals(18, fs.getNextBlock(17));
+          assertEquals(19, fs.getNextBlock(18));
+          assertEquals(20, fs.getNextBlock(19));
+          assertEquals(21, fs.getNextBlock(20));
+          assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(21));
+          assertEquals(23,                          fs.getNextBlock(22));
+          assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(23));
+          assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(24));
+      } else {
+          assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(3));
+          assertEquals(5,                           fs.getNextBlock(4));
+          assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(5));
+          assertEquals(7,                           fs.getNextBlock(6));
+          assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(7));
+          assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(8));
+      }
+      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getRoot().getProperty().getStartBlock());
+      
+      
+      // Write and read back
+      // TODO
+   }
+   
+   @Test
+   public void addBeforeWrite() throws Exception {
+       NPOIFSFileSystem fs = new NPOIFSFileSystem();
+       
+       // Initially has BAT + Properties but nothing else
+       assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(0));
+       assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(1));
+       assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(2));
+
+       // Add to the mini stream
+       // TODO
+       
+       // Add to the main stream
+       // TODO
+       
+       // Write, read, check
+       // TODO
    }
 
    /**