diff --git a/src/java/org/apache/poi/poifs/filesystem/NPOIFSDocument.java b/src/java/org/apache/poi/poifs/filesystem/NPOIFSDocument.java index 3a2c28602..484914e54 100644 --- a/src/java/org/apache/poi/poifs/filesystem/NPOIFSDocument.java +++ b/src/java/org/apache/poi/poifs/filesystem/NPOIFSDocument.java @@ -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 getBlockIterator() { - return _stream.getBlockIterator(); + if(getSize() > 0) { + return _stream.getBlockIterator(); + } else { + List empty = Collections.emptyList(); + return empty.iterator(); + } } /** diff --git a/src/java/org/apache/poi/poifs/filesystem/NPOIFSFileSystem.java b/src/java/org/apache/poi/poifs/filesystem/NPOIFSFileSystem.java index 58d77be69..b15df9bd4 100644 --- a/src/java/org/apache/poi/poifs/filesystem/NPOIFSFileSystem.java +++ b/src/java/org/apache/poi/poifs/filesystem/NPOIFSFileSystem.java @@ -103,6 +103,9 @@ public class NPOIFSFileSystem extends BlockStore _xbat_blocks = new ArrayList(); _bat_blocks = new ArrayList(); _root = null; + + // Data needs to initially hold just the header block + _data = new ByteArrayBackedDataSource(new byte[bigBlockSize.getBigBlockSize()]); } /** diff --git a/src/java/org/apache/poi/poifs/filesystem/NPOIFSStream.java b/src/java/org/apache/poi/poifs/filesystem/NPOIFSStream.java index 458100950..5d8d1fa88 100644 --- a/src/java/org/apache/poi/poifs/filesystem/NPOIFSStream.java +++ b/src/java/org/apache/poi/poifs/filesystem/NPOIFSStream.java @@ -102,7 +102,7 @@ public class NPOIFSStream implements Iterable 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 // 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; diff --git a/src/testcases/org/apache/poi/poifs/filesystem/TestNPOIFSStream.java b/src/testcases/org/apache/poi/poifs/filesystem/TestNPOIFSStream.java index c8b38d99b..5b17242a0 100644 --- a/src/testcases/org/apache/poi/poifs/filesystem/TestNPOIFSStream.java +++ b/src/testcases/org/apache/poi/poifs/filesystem/TestNPOIFSStream.java @@ -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 it = stream.getBlockIterator(); + assertEquals(true, it.hasNext()); + ByteBuffer b = it.next(); + + byte[] read = new byte[512]; + b.get(read); + for(int i=0; i