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
This commit is contained in:
Nick Burch 2011-05-12 22:10:51 +00:00
parent 62b5690d8f
commit 26ea0d987d
3 changed files with 64 additions and 20 deletions

View File

@ -93,20 +93,38 @@ public class NPOIFSFileSystem extends BlockStore
private POIFSBigBlockSize bigBlockSize = private POIFSBigBlockSize bigBlockSize =
POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS; POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS;
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>();
_bat_blocks = new ArrayList<BATBlock>();
_root = null;
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 * Constructor, intended for writing
*/ */
public NPOIFSFileSystem() public NPOIFSFileSystem()
{ {
_header = new HeaderBlock(bigBlockSize); this(true);
_property_table = new NPropertyTable(_header);
_mini_store = new NPOIFSMiniStore(this, _property_table.getRoot(), new ArrayList<BATBlock>(), _header); // Mark us as having a single empty BAT at offset 0
_xbat_blocks = new ArrayList<BATBlock>(); _header.setBATCount(1);
_bat_blocks = new ArrayList<BATBlock>(); _header.setBATArray(new int[] { 0 });
_root = null; _bat_blocks.add(BATBlock.createEmptyBATBlock(bigBlockSize, false));
setNextBlock(0, POIFSConstants.FAT_SECTOR_BLOCK);
// Data needs to initially hold just the header block // Now associate the properties with the empty block
_data = new ByteArrayBackedDataSource(new byte[bigBlockSize.getBigBlockSize()]); _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) private NPOIFSFileSystem(FileChannel channel, boolean closeChannelOnError)
throws IOException throws IOException
{ {
this(); this(false);
try { try {
// Get the header // Get the header
@ -230,7 +248,7 @@ public class NPOIFSFileSystem extends BlockStore
public NPOIFSFileSystem(InputStream stream) public NPOIFSFileSystem(InputStream stream)
throws IOException throws IOException
{ {
this(); this(false);
ReadableByteChannel channel = null; ReadableByteChannel channel = null;
boolean success = false; boolean success = false;
@ -674,7 +692,7 @@ public class NPOIFSFileSystem extends BlockStore
{ {
// HeaderBlock // HeaderBlock
HeaderBlockWriter hbw = new HeaderBlockWriter(_header); HeaderBlockWriter hbw = new HeaderBlockWriter(_header);
hbw.writeBlock( getBlockAt(0) ); hbw.writeBlock( getBlockAt(-1) );
// BATs // BATs
for(BATBlock bat : _bat_blocks) { for(BATBlock bat : _bat_blocks) {

View File

@ -17,6 +17,8 @@
package org.apache.poi.poifs.filesystem; package org.apache.poi.poifs.filesystem;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.Iterator; import java.util.Iterator;
@ -534,8 +536,31 @@ public final class TestNPOIFSFileSystem extends TestCase {
* Then, add some streams, write and read * Then, add some streams, write and read
*/ */
public void testCreateWriteRead() throws Exception { 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
// TODO The rest of the test
} }
// TODO Directory/Document write tests // TODO Directory/Document write tests

View File

@ -828,12 +828,12 @@ public final class TestNPOIFSStream extends TestCase {
NPOIFSFileSystem fs = new NPOIFSFileSystem(); NPOIFSFileSystem fs = new NPOIFSFileSystem();
NPOIFSStream stream = new NPOIFSStream(fs); NPOIFSStream stream = new NPOIFSStream(fs);
// Check our filesystem has a single block // Check our filesystem has a BAT and the Properties
// to hold the BAT assertEquals(2, fs.getFreeBlock());
assertEquals(1, fs.getFreeBlock());
BATBlock bat = fs.getBATBlockAndIndex(0).getBlock(); BATBlock bat = fs.getBATBlockAndIndex(0).getBlock();
assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, bat.getValueAt(0)); 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 // Check the stream as-is
assertEquals(POIFSConstants.END_OF_CHAIN, stream.getStartBlock()); assertEquals(POIFSConstants.END_OF_CHAIN, stream.getStartBlock());
@ -853,12 +853,13 @@ public final class TestNPOIFSStream extends TestCase {
stream.updateContents(data); stream.updateContents(data);
// Check now // Check now
assertEquals(3, fs.getFreeBlock()); assertEquals(4, fs.getFreeBlock());
bat = fs.getBATBlockAndIndex(0).getBlock(); bat = fs.getBATBlockAndIndex(0).getBlock();
assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, bat.getValueAt(0)); assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, bat.getValueAt(0));
assertEquals(2, bat.getValueAt(1)); assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(1));
assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(2)); assertEquals(3, bat.getValueAt(2));
assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(3)); assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(3));
assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(4));
Iterator<ByteBuffer> it = stream.getBlockIterator(); Iterator<ByteBuffer> it = stream.getBlockIterator();