]> source.dussan.org Git - poi.git/commitdiff
More NPOIFS mini stream improvements, and more tests for it all
authorNick Burch <nick@apache.org>
Fri, 25 Apr 2014 18:39:31 +0000 (18:39 +0000)
committerNick Burch <nick@apache.org>
Fri, 25 Apr 2014 18:39:31 +0000 (18:39 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1590098 13f79535-47bb-0310-9956-ffa450edef68

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

index 5c753927e2042383f110f5c71262db3bf9631a8e..308ae15c74bd4ecb3cef974920de25d3b1790510 100644 (file)
@@ -86,44 +86,50 @@ public class NPOIFSMiniStore extends BlockStore
      * Load the block, extending the underlying stream if needed
      */
     protected ByteBuffer createBlockIfNeeded(final int offset) throws IOException {
-       // If we are the first block to be allocated, initialise the stream
+       boolean firstInStore = false;
        if (_mini_stream.getStartBlock() == POIFSConstants.END_OF_CHAIN) {
-           int firstBigBlock = _filesystem.getFreeBlock();
-           _filesystem.createBlockIfNeeded(firstBigBlock);
-           _filesystem.setNextBlock(firstBigBlock, POIFSConstants.END_OF_CHAIN);
-           _filesystem._get_property_table().getRoot().setStartBlock(firstBigBlock);
-           _mini_stream = new NPOIFSStream(_filesystem, firstBigBlock);
+           firstInStore = true;
        }
-        
+       
        // Try to get it without extending the stream
-       try {
-          return getBlockAt(offset);
-       } catch(IndexOutOfBoundsException e) {
-          // Need to extend the stream
-          // TODO Replace this with proper append support
-          // For now, do the extending by hand...
-          
-          // Ask for another block
-          int newBigBlock = _filesystem.getFreeBlock();
-          _filesystem.createBlockIfNeeded(newBigBlock);
-          
-          // Tack it onto the end of our chain
-          ChainLoopDetector loopDetector = _filesystem.getChainLoopDetector();
-          int block = _mini_stream.getStartBlock();
-          while(true) {
-             loopDetector.claim(block);
-             int next = _filesystem.getNextBlock(block);
-             if(next == POIFSConstants.END_OF_CHAIN) {
-                break;
-             }
-             block = next;
-          }
-          _filesystem.setNextBlock(block, newBigBlock);
-          _filesystem.setNextBlock(newBigBlock, POIFSConstants.END_OF_CHAIN);
+       if (! firstInStore) {
+           try {
+              return getBlockAt(offset);
+           } catch(IndexOutOfBoundsException e) {}
+       }
+       
+       // Need to extend the stream
+       // TODO Replace this with proper append support
+       // For now, do the extending by hand...
 
-          // Now try again to get it
-          return createBlockIfNeeded(offset);
+       // Ask for another block
+       int newBigBlock = _filesystem.getFreeBlock();
+       _filesystem.createBlockIfNeeded(newBigBlock);
+       
+       // If we are the first block to be allocated, initialise the stream
+       if (firstInStore) {
+           _filesystem._get_property_table().getRoot().setStartBlock(newBigBlock);
+           _mini_stream = new NPOIFSStream(_filesystem, newBigBlock);
+       } else {
+           // Tack it onto the end of our chain
+           ChainLoopDetector loopDetector = _filesystem.getChainLoopDetector();
+           int block = _mini_stream.getStartBlock();
+           while(true) {
+              loopDetector.claim(block);
+              int next = _filesystem.getNextBlock(block);
+              if(next == POIFSConstants.END_OF_CHAIN) {
+                 break;
+              }
+              block = next;
+           }
+           _filesystem.setNextBlock(block, newBigBlock);
        }
+       
+       // This is now the new end
+       _filesystem.setNextBlock(newBigBlock, POIFSConstants.END_OF_CHAIN);
+
+       // Now try again, to get the real small block
+       return createBlockIfNeeded(offset);
     }
     
     /**
index 6d51e55911cdf4a944bb65aa0ee0e2bfba6cd71d..0e531ea9359e4aa71f1853aae25f1d0ed3d6137f 100644 (file)
@@ -414,6 +414,7 @@ public final class TestNPOIFSFileSystem {
 
       // We have one BAT at block 99
       assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(99));
+      assertBATCount(fs, 1, 0);
       
       // We've spare ones from 100 to 128
       for(int i=100; i<128; i++) {
@@ -652,6 +653,8 @@ public final class TestNPOIFSFileSystem {
            
            // Check it's all there
            // TODO Add check
+
+           // TODO Something about directories too
            
            // All done
            fs.close();
@@ -663,8 +666,12 @@ public final class TestNPOIFSFileSystem {
     * Then, add some streams, write and read
     */
    @Test
+   @SuppressWarnings("resource")
    public void createWriteRead() throws Exception {
       NPOIFSFileSystem fs = new NPOIFSFileSystem();
+      NDocumentInputStream inp;
+      DocumentEntry miniDoc;
+      DocumentEntry normDoc;
       
       // Initially has a BAT but not SBAT
       assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(0));
@@ -822,8 +829,30 @@ if(1==0) { // TODO FIX
 
       
       // Check some data
-      // TODO
+      assertEquals(1, fs.getRoot().getEntryCount());
+      testDir = (DirectoryEntry)fs.getRoot().getEntry("Test Directory");
+      assertEquals(3, testDir.getEntryCount());
+
+      miniDoc = (DocumentEntry)testDir.getEntry("Mini");
+      inp = new NDocumentInputStream(miniDoc);
+      byte[] miniRead = new byte[miniDoc.getSize()];
+      assertEquals(miniDoc.getSize(), inp.read(miniRead));
+      assertThat(mini, equalTo(miniRead));
+      inp.close();
       
+      normDoc = (DocumentEntry)testDir.getEntry("Normal4096");
+      inp = new NDocumentInputStream(normDoc);
+      byte[] normRead = new byte[normDoc.getSize()];
+      assertEquals(normDoc.getSize(), inp.read(normRead));
+      assertThat(main4096, equalTo(normRead));
+      inp.close();
+
+      normDoc = (DocumentEntry)testDir.getEntry("Normal5124");
+      inp = new NDocumentInputStream(normDoc);
+      normRead = new byte[normDoc.getSize()];
+      assertEquals(normDoc.getSize(), inp.read(normRead));
+      assertThat(main5124, equalTo(normRead));
+      inp.close();
       
       // All done
       fs.close();
@@ -963,9 +992,48 @@ if(1==0) { // TODO FIX
        
        
        // Add one more stream to each, then save and re-load
+       byte[] mini2 = new byte[] { -42, 0, -1, -2, -3, -4, -42 };
+       testDir.createDocument("Mini2", new ByteArrayInputStream(mini2));
+       
+       // Add to the main stream
+       byte[] main4106 = new byte[4106];
+       main4106[0] = 41;
+       main4106[4105] = 42;
+       testDir.createDocument("Normal4106", new ByteArrayInputStream(main4106));
+       
+       
+       // Recheck the data in all 4 streams
+       fs = writeOutAndReadBack(fs);
+       
+       fsRoot = fs.getRoot();
+       assertEquals(1, fsRoot.getEntryCount());
+       
+       parentDir = (DirectoryEntry)fsRoot.getEntry("Parent Directory");
+       assertEquals(1, parentDir.getEntryCount());
        
-       // Recheck
-       // TODO
+       testDir = (DirectoryEntry)parentDir.getEntry("Test Directory");
+       assertEquals(4, testDir.getEntryCount());
+
+       miniDoc = (DocumentEntry)testDir.getEntry("Mini");
+       inp = new NDocumentInputStream(miniDoc);
+       miniRead = new byte[miniDoc.getSize()];
+       assertEquals(miniDoc.getSize(), inp.read(miniRead));
+       assertThat(mini, equalTo(miniRead));
+       inp.close();
+
+       miniDoc = (DocumentEntry)testDir.getEntry("Mini2");
+       inp = new NDocumentInputStream(miniDoc);
+       miniRead = new byte[miniDoc.getSize()];
+       assertEquals(miniDoc.getSize(), inp.read(miniRead));
+       assertThat(mini2, equalTo(miniRead));
+       inp.close();
+
+       normDoc = (DocumentEntry)testDir.getEntry("Normal4106");
+       inp = new NDocumentInputStream(normDoc);
+       normRead = new byte[normDoc.getSize()];
+       assertEquals(normDoc.getSize(), inp.read(normRead));
+       assertThat(main4106, equalTo(normRead));
+       inp.close();   
    }
 
    /**
@@ -991,6 +1059,4 @@ if(1==0) { // TODO FIX
        
        assertThat(wbDataExp, equalTo(wbDataAct));
    }
-   
-   // TODO Directory/Document create/write/read/delete/change tests
 }