]> source.dussan.org Git - poi.git/commitdiff
Fix a couple of NPOIFS bugs relating to empty files, empty documents and non-padded...
authorNick Burch <nick@apache.org>
Fri, 25 Mar 2011 18:02:46 +0000 (18:02 +0000)
committerNick Burch <nick@apache.org>
Fri, 25 Mar 2011 18:02:46 +0000 (18:02 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1085493 13f79535-47bb-0310-9956-ffa450edef68

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

index 3a2c28602336e2e0328ee23cdc68a22bfef4f05b..484914e54c3b22addc961eede07d548ea72d7ba2 100644 (file)
@@ -24,6 +24,7 @@ import java.io.InputStream;
 import java.nio.ByteBuffer;
 import java.util.Collections;
 import java.util.Iterator;
+import java.util.List;
 
 import org.apache.poi.poifs.common.POIFSConstants;
 import org.apache.poi.poifs.dev.POIFSViewable;
@@ -106,7 +107,12 @@ public final class NPOIFSDocument implements POIFSViewable {
    }
    
    Iterator<ByteBuffer> getBlockIterator() {
-      return _stream.getBlockIterator();
+      if(getSize() > 0) {
+         return _stream.getBlockIterator();
+      } else {
+         List<ByteBuffer> empty = Collections.emptyList();
+         return empty.iterator();
+      }
    }
 
    /**
index 58d77be69a01ebfc864b0cd75d8ecf4eaf625d0f..b15df9bd4cc7b9c851676058572c1d81d1f5f807 100644 (file)
@@ -103,6 +103,9 @@ public class NPOIFSFileSystem extends BlockStore
         _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()]);
     }
 
     /**
index 458100950d07d7c5fea4abf010ac273141dd8a9e..5d8d1fa8825eedcbdbdaf70e95417dbb65a50901 100644 (file)
@@ -102,7 +102,7 @@ public class NPOIFSStream implements Iterable<ByteBuffer>
    public void updateContents(byte[] contents) throws IOException {
       // How many blocks are we going to need?
       int blockSize = blockStore.getBlockStoreBlockSize();
-      int blocks = (int)Math.ceil(contents.length / blockSize);
+      int blocks = (int)Math.ceil( ((double)contents.length) / blockSize );
       
       // Make sure we don't encounter a loop whilst overwriting
       //  the existing blocks
@@ -141,7 +141,9 @@ public class NPOIFSStream implements Iterable<ByteBuffer>
          
          // Write it
          ByteBuffer buffer = blockStore.createBlockIfNeeded(thisBlock);
-         buffer.put(contents, i*blockSize, blockSize);
+         int startAt = i*blockSize;
+         int endAt = Math.min(contents.length - startAt, blockSize);
+         buffer.put(contents, startAt, endAt); 
          
          // Update pointers
          prevBlock = thisBlock;
index c8b38d99b8f24ff36d13c44bbf308bb31b07ed4b..5b17242a0893b5acdaef99d6fbceb60071634189 100644 (file)
@@ -24,6 +24,7 @@ import junit.framework.TestCase;
 
 import org.apache.poi.POIDataSamples;
 import org.apache.poi.poifs.common.POIFSConstants;
+import org.apache.poi.poifs.storage.BATBlock;
 
 /**
  * Tests {@link NPOIFSStream}
@@ -638,4 +639,69 @@ public final class TestNPOIFSStream extends TestCase {
          fail("Loop should have been detected but wasn't!");
       } catch(IllegalStateException e) {}
    }
+   
+   /**
+    * Tests adding a new stream, writing and reading it.
+    */
+   public void testReadWriteNewStream() throws Exception {
+      NPOIFSFileSystem fs = new NPOIFSFileSystem();
+      NPOIFSStream stream = new NPOIFSStream(fs);
+      
+      // Check our filesystem has a single block
+      //  to hold the BAT
+      assertEquals(1, fs.getFreeBlock());
+      BATBlock bat = fs.getBATBlockAndIndex(0).getBlock();
+      assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, bat.getValueAt(0));
+      assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(1));
+      
+      // Check the stream as-is
+      assertEquals(POIFSConstants.END_OF_CHAIN, stream.getStartBlock());
+      try {
+         stream.getBlockIterator();
+         fail("Shouldn't be able to get an iterator before writing");
+      } catch(IllegalStateException e) {}
+      
+      // Write in two blocks
+      byte[] data = new byte[512+20];
+      for(int i=0; i<512; i++) {
+         data[i] = (byte)(i%256);
+      }
+      for(int i=512; i<data.length; i++) {
+         data[i] = (byte)(i%256 + 100);
+      }
+      stream.updateContents(data);
+      
+      // Check now
+      assertEquals(3, 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));
+      
+      
+      Iterator<ByteBuffer> it = stream.getBlockIterator();
+      assertEquals(true, it.hasNext());
+      ByteBuffer b = it.next();
+      
+      byte[] read = new byte[512];
+      b.get(read);
+      for(int i=0; i<read.length; i++) {
+         assertEquals("Wrong value at " + i, data[i], read[i]);
+      }
+      
+      assertEquals(true, it.hasNext());
+      b = it.next();
+      
+      read = new byte[512];
+      b.get(read);
+      for(int i=0; i<20; i++) {
+         assertEquals(data[i+512], read[i]);
+      }
+      for(int i=20; i<read.length; i++) {
+         assertEquals(0, read[i]);
+      }
+      
+      assertEquals(false, it.hasNext());
+   }
 }