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,10 +93,7 @@ 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);
@ -105,8 +102,29 @@ public class NPOIFSFileSystem extends BlockStore
_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) {

View 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

View 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();