]> source.dussan.org Git - poi.git/commitdiff
More NPOIFSStream tests, and explicit free support+test
authorNick Burch <nick@apache.org>
Tue, 28 Dec 2010 04:29:18 +0000 (04:29 +0000)
committerNick Burch <nick@apache.org>
Tue, 28 Dec 2010 04:29:18 +0000 (04:29 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1053249 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/poifs/filesystem/NPOIFSStream.java
src/testcases/org/apache/poi/poifs/filesystem/TestNPOIFSMiniStore.java
src/testcases/org/apache/poi/poifs/filesystem/TestNPOIFSStream.java

index 859bde146967b93deb6eed0a10f195e74be3c632..84e0e4c0ce9208a64aacda0b19c3331de1e0c1ef 100644 (file)
@@ -127,6 +127,13 @@ public class NPOIFSStream implements Iterable<ByteBuffer>
             if(prevBlock != POIFSConstants.END_OF_CHAIN) {
                blockStore.setNextBlock(prevBlock, thisBlock);
             }
+            blockStore.setNextBlock(thisBlock, POIFSConstants.END_OF_CHAIN);
+            
+            // If we've just written the first block on a 
+            //  new stream, save the start block offset
+            if(this.startBlock == POIFSConstants.END_OF_CHAIN) {
+               this.startBlock = thisBlock;
+            }
          } else {
             loopDetector.claim(thisBlock);
             nextBlock = blockStore.getNextBlock(thisBlock);
@@ -142,19 +149,33 @@ public class NPOIFSStream implements Iterable<ByteBuffer>
       int lastBlock = prevBlock;
       
       // If we're overwriting, free any remaining blocks
+      NPOIFSStream toFree = new NPOIFSStream(blockStore, nextBlock);
+      toFree.free(loopDetector);
+      
+      // Mark the end of the stream
+      blockStore.setNextBlock(lastBlock, POIFSConstants.END_OF_CHAIN);
+   }
+   
+   // TODO Streaming write support too
+   
+   /**
+    * Frees all blocks in the stream
+    */
+   public void free() throws IOException {
+      ChainLoopDetector loopDetector = blockStore.getChainLoopDetector();
+      free(loopDetector);
+   }
+   private void free(ChainLoopDetector loopDetector) {
+      int nextBlock = startBlock;
       while(nextBlock != POIFSConstants.END_OF_CHAIN) {
          int thisBlock = nextBlock;
          loopDetector.claim(thisBlock);
          nextBlock = blockStore.getNextBlock(thisBlock);
          blockStore.setNextBlock(thisBlock, POIFSConstants.UNUSED_BLOCK);
       }
-      
-      // Mark the end of the stream
-      blockStore.setNextBlock(lastBlock, POIFSConstants.END_OF_CHAIN);
+      this.startBlock = POIFSConstants.END_OF_CHAIN;
    }
    
-   // TODO Streaming write support too
-   
    /**
     * Class that handles a streaming read of one stream
     */
index 985ad015e4c819bf3482686abc261de88eacc6f0..8f495903b7cb4daaea63bd17311114cdc9ecb0cd 100644 (file)
@@ -245,6 +245,7 @@ public final class TestNPOIFSMiniStore extends TestCase {
     *  big blocks that make up the ministream as needed
     */
    public void testCreateBlockIfNeeded() throws Exception {
-      // TODO
+      // TODO Add underlying implementation
+      // TODO Add unit test
    }
 }
index b9223e4e9431eb4cbd799567ddd4903dbc1c1812..8705e7ac37c5ca4f1a5eb3fafb7f66ab1a4a98f5 100644 (file)
@@ -27,8 +27,6 @@ import org.apache.poi.poifs.common.POIFSConstants;
 
 /**
  * Tests {@link NPOIFSStream}
- * 
- * TODO Write unit tests
  */
 public final class TestNPOIFSStream extends TestCase {
    private static final POIDataSamples _inst = POIDataSamples.getPOIFSInstance();
@@ -254,8 +252,53 @@ public final class TestNPOIFSStream extends TestCase {
     */
    public void testReadMiniStreams() throws Exception {
       NPOIFSFileSystem fs = new NPOIFSFileSystem(_inst.openResourceAsStream("BlockSize512.zvi"));
+      NPOIFSMiniStore ministore = fs.getMiniStore();
       
-      // TODO
+      // 178 -> 179 -> 180 -> end
+      NPOIFSStream stream = new NPOIFSStream(ministore, 178);
+      Iterator<ByteBuffer> i = stream.getBlockIterator();
+      assertEquals(true, i.hasNext());
+      assertEquals(true, i.hasNext());
+      assertEquals(true, i.hasNext());
+      ByteBuffer b178 = i.next();
+      assertEquals(true, i.hasNext());
+      assertEquals(true, i.hasNext());
+      ByteBuffer b179 = i.next();
+      assertEquals(true, i.hasNext());
+      ByteBuffer b180 = i.next();
+      assertEquals(false, i.hasNext());
+      assertEquals(false, i.hasNext());
+      assertEquals(false, i.hasNext());
+      
+      // Check the contents of the 1st block
+      assertEquals((byte)0xfe, b178.get());
+      assertEquals((byte)0xff, b178.get());
+      assertEquals((byte)0x00, b178.get());
+      assertEquals((byte)0x00, b178.get());
+      assertEquals((byte)0x05, b178.get());
+      assertEquals((byte)0x01, b178.get());
+      assertEquals((byte)0x02, b178.get());
+      assertEquals((byte)0x00, b178.get());
+      
+      // And the 2nd
+      assertEquals((byte)0x6c, b179.get());
+      assertEquals((byte)0x00, b179.get());
+      assertEquals((byte)0x00, b179.get());
+      assertEquals((byte)0x00, b179.get());
+      assertEquals((byte)0x28, b179.get());
+      assertEquals((byte)0x00, b179.get());
+      assertEquals((byte)0x00, b179.get());
+      assertEquals((byte)0x00, b179.get());
+      
+      // And the 3rd
+      assertEquals((byte)0x30, b180.get());
+      assertEquals((byte)0x00, b180.get());
+      assertEquals((byte)0x00, b180.get());
+      assertEquals((byte)0x00, b180.get());
+      assertEquals((byte)0x00, b180.get());
+      assertEquals((byte)0x00, b180.get());
+      assertEquals((byte)0x00, b180.get());
+      assertEquals((byte)0x80, b180.get());
    }
 
    /**
@@ -375,9 +418,90 @@ public final class TestNPOIFSStream extends TestCase {
     * Writes to a new stream in the file
     */
    public void testWriteNewStream() throws Exception {
-      NPOIFSFileSystem fs = new NPOIFSFileSystem(_inst.getFile("BlockSize512.zvi"));
+      NPOIFSFileSystem fs = new NPOIFSFileSystem(_inst.openResourceAsStream("BlockSize512.zvi"));
       
-      // TODO
+      // 100 is our first free one
+      assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(99));
+      assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(100));
+      assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(101));
+      assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(102));
+      assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(103));
+      assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(104));
+      
+      
+      // Add a single block one
+      byte[] data = new byte[512];
+      for(int i=0; i<data.length; i++) {
+         data[i] = (byte)(i%256);
+      }
+      
+      NPOIFSStream stream = new NPOIFSStream(fs);
+      stream.updateContents(data);
+      
+      // Check it was allocated properly
+      assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(99));
+      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(100));
+      assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(101));
+      assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(102));
+      assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(103));
+      assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(104));
+      
+      // And check the contents
+      Iterator<ByteBuffer> it = stream.getBlockIterator();
+      int count = 0;
+      while(it.hasNext()) {
+         ByteBuffer b = it.next();
+         data = new byte[512];
+         b.get(data);
+         for(int i=0; i<data.length; i++) {
+            byte exp = (byte)(i%256);
+            assertEquals(exp, data[i]);
+         }
+         count++;
+      }
+      assertEquals(1, count);
+      
+      
+      // And a multi block one
+      data = new byte[512*3];
+      for(int i=0; i<data.length; i++) {
+         data[i] = (byte)(i%256);
+      }
+      
+      stream = new NPOIFSStream(fs);
+      stream.updateContents(data);
+      
+      // Check it was allocated properly
+      assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(99));
+      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(100));
+      assertEquals(102,                         fs.getNextBlock(101));
+      assertEquals(103,                         fs.getNextBlock(102));
+      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(103));
+      assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(104));
+      
+      // And check the contents
+      it = stream.getBlockIterator();
+      count = 0;
+      while(it.hasNext()) {
+         ByteBuffer b = it.next();
+         data = new byte[512];
+         b.get(data);
+         for(int i=0; i<data.length; i++) {
+            byte exp = (byte)(i%256);
+            assertEquals(exp, data[i]);
+         }
+         count++;
+      }
+      assertEquals(3, count);
+      
+      // Free it
+      stream.free();
+      assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(99));
+      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(100));
+      assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(101));
+      assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(102));
+      assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(103));
+      assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(104));
    }
    
    /**