From: Nick Burch Date: Thu, 12 May 2011 22:10:51 +0000 (+0000) Subject: Fix NPOIFS creation of an empty filesystem, with create/write/read test X-Git-Tag: REL_3_8_BETA3~33 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=8038e149d6ac875de2bafb989e1c8ea6538d536a;p=poi.git Fix NPOIFS creation of an empty filesystem, with create/write/read test git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1102482 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/src/java/org/apache/poi/poifs/filesystem/NPOIFSFileSystem.java b/src/java/org/apache/poi/poifs/filesystem/NPOIFSFileSystem.java index 8b2f9e9ea2..fbfd04d77a 100644 --- a/src/java/org/apache/poi/poifs/filesystem/NPOIFSFileSystem.java +++ b/src/java/org/apache/poi/poifs/filesystem/NPOIFSFileSystem.java @@ -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(), _header); - _xbat_blocks = new ArrayList(); + _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()]); + 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) { diff --git a/src/testcases/org/apache/poi/poifs/filesystem/TestNPOIFSFileSystem.java b/src/testcases/org/apache/poi/poifs/filesystem/TestNPOIFSFileSystem.java index 87b7d57c70..e8f8a1f189 100644 --- a/src/testcases/org/apache/poi/poifs/filesystem/TestNPOIFSFileSystem.java +++ b/src/testcases/org/apache/poi/poifs/filesystem/TestNPOIFSFileSystem.java @@ -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 diff --git a/src/testcases/org/apache/poi/poifs/filesystem/TestNPOIFSStream.java b/src/testcases/org/apache/poi/poifs/filesystem/TestNPOIFSStream.java index 256037100c..40c1cc516d 100644 --- a/src/testcases/org/apache/poi/poifs/filesystem/TestNPOIFSStream.java +++ b/src/testcases/org/apache/poi/poifs/filesystem/TestNPOIFSStream.java @@ -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 it = stream.getBlockIterator();