]> source.dussan.org Git - poi.git/commitdiff
Fix NPOIFS creation of an empty filesystem, with create/write/read test
authorNick Burch <nick@apache.org>
Thu, 12 May 2011 22:10:51 +0000 (22:10 +0000)
committerNick Burch <nick@apache.org>
Thu, 12 May 2011 22:10:51 +0000 (22:10 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1102482 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/poifs/filesystem/NPOIFSFileSystem.java
src/testcases/org/apache/poi/poifs/filesystem/TestNPOIFSFileSystem.java
src/testcases/org/apache/poi/poifs/filesystem/TestNPOIFSStream.java

index 8b2f9e9ea201feed05e1733d309f29cdd10c0ed8..fbfd04d77a8828f2d13ebbeb8b66cfe71b6ff796 100644 (file)
@@ -93,20 +93,38 @@ public class NPOIFSFileSystem extends BlockStore
     private POIFSBigBlockSize bigBlockSize = 
        POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS;
 
-    /**
-     * Constructor, intended for writing
-     */
-    public NPOIFSFileSystem()
+    private NPOIFSFileSystem(boolean newFS)
     {
         _header         = new HeaderBlock(bigBlockSize);
         _property_table = new NPropertyTable(_header);
         _mini_store     = new NPOIFSMiniStore(this, _property_table.getRoot(), new ArrayList<BATBlock>(), _header);
-        _xbat_blocks     = new ArrayList<BATBlock>();
+        _xbat_blocks    = new ArrayList<BATBlock>();
         _bat_blocks     = new ArrayList<BATBlock>();
         _root           = null;
         
-        // Data needs to initially hold just the header block 
-        _data           = new ByteArrayBackedDataSource(new byte[bigBlockSize.getBigBlockSize()]);
+        if(newFS) {
+           // Data needs to initially hold just the header block,
+           //  a single bat block, and an empty properties section
+           _data        = new ByteArrayBackedDataSource(new byte[bigBlockSize.getBigBlockSize()*3]);
+        }
+    }
+    
+    /**
+     * Constructor, intended for writing
+     */
+    public NPOIFSFileSystem()
+    {
+       this(true);
+       
+        // Mark us as having a single empty BAT at offset 0
+        _header.setBATCount(1);
+        _header.setBATArray(new int[] { 0 });
+        _bat_blocks.add(BATBlock.createEmptyBATBlock(bigBlockSize, false));
+        setNextBlock(0, POIFSConstants.FAT_SECTOR_BLOCK);
+        
+        // Now associate the properties with the empty block
+        _property_table.setStartBlock(1);
+        setNextBlock(1, POIFSConstants.END_OF_CHAIN);
     }
 
     /**
@@ -169,7 +187,7 @@ public class NPOIFSFileSystem extends BlockStore
     private NPOIFSFileSystem(FileChannel channel, boolean closeChannelOnError)
          throws IOException
     {
-       this();
+       this(false);
 
        try {
           // Get the header
@@ -230,7 +248,7 @@ public class NPOIFSFileSystem extends BlockStore
     public NPOIFSFileSystem(InputStream stream)
         throws IOException
     {
-        this();
+        this(false);
         
         ReadableByteChannel channel = null;
         boolean success = false;
@@ -674,7 +692,7 @@ public class NPOIFSFileSystem extends BlockStore
     {
        // HeaderBlock
        HeaderBlockWriter hbw = new HeaderBlockWriter(_header);
-       hbw.writeBlock( getBlockAt(0) );
+       hbw.writeBlock( getBlockAt(-1) );
        
        // BATs
        for(BATBlock bat : _bat_blocks) {
index 87b7d57c701c2b4ec991320302abe85b1243bddc..e8f8a1f189ad010a303ea1debcd928943001b1cb 100644 (file)
@@ -17,6 +17,8 @@
 
 package org.apache.poi.poifs.filesystem;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
 import java.nio.ByteBuffer;
 import java.util.Iterator;
 
@@ -534,8 +536,31 @@ public final class TestNPOIFSFileSystem extends TestCase {
     * Then, add some streams, write and read
     */
    public void testCreateWriteRead() throws Exception {
+      NPOIFSFileSystem fs = new NPOIFSFileSystem();
+      
+      // Initially has a BAT but not SBAT
+      assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(0));
+      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(1));
+      assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(2));
+      
+      // Check that the SBAT is empty
+      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getRoot().getProperty().getStartBlock());
+
+      // Write and read it
+      ByteArrayOutputStream baos = new ByteArrayOutputStream();
+      fs.writeFilesystem(baos);
+      fs = new NPOIFSFileSystem(new ByteArrayInputStream(baos.toByteArray()));
+      
+      // Check it's still like that
+      assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(0));
+      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(1));
+      assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(2));
+      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getRoot().getProperty().getStartBlock());
+
+      // Now add a normal stream and a mini stream
       // TODO
-      // TODO
+      
+      // TODO The rest of the test
    }
    
    // TODO Directory/Document write tests
index 256037100c2324e3205f061ba4d74f1737cb7110..40c1cc516da266a8d4aa44b8d7c99e1874638298 100644 (file)
@@ -828,12 +828,12 @@ public final class TestNPOIFSStream extends TestCase {
       NPOIFSFileSystem fs = new NPOIFSFileSystem();
       NPOIFSStream stream = new NPOIFSStream(fs);
       
-      // Check our filesystem has a single block
-      //  to hold the BAT
-      assertEquals(1, fs.getFreeBlock());
+      // Check our filesystem has a BAT and the Properties
+      assertEquals(2, fs.getFreeBlock());
       BATBlock bat = fs.getBATBlockAndIndex(0).getBlock();
       assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, bat.getValueAt(0));
-      assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(1));
+      assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(1));
+      assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(2));
       
       // Check the stream as-is
       assertEquals(POIFSConstants.END_OF_CHAIN, stream.getStartBlock());
@@ -853,12 +853,13 @@ public final class TestNPOIFSStream extends TestCase {
       stream.updateContents(data);
       
       // Check now
-      assertEquals(3, fs.getFreeBlock());
+      assertEquals(4, fs.getFreeBlock());
       bat = fs.getBATBlockAndIndex(0).getBlock();
       assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, bat.getValueAt(0));
-      assertEquals(2,                           bat.getValueAt(1));
-      assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(2));
-      assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(3));
+      assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(1));
+      assertEquals(3,                           bat.getValueAt(2));
+      assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(3));
+      assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(4));
       
       
       Iterator<ByteBuffer> it = stream.getBlockIterator();