From 08e0e85635116c05f88d9c560e1aedc1a76c9eb3 Mon Sep 17 00:00:00 2001 From: Nick Burch Date: Tue, 28 Dec 2010 04:29:18 +0000 Subject: [PATCH] More NPOIFSStream tests, and explicit free support+test git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1053249 13f79535-47bb-0310-9956-ffa450edef68 --- .../poi/poifs/filesystem/NPOIFSStream.java | 31 +++- .../poifs/filesystem/TestNPOIFSMiniStore.java | 3 +- .../poifs/filesystem/TestNPOIFSStream.java | 134 +++++++++++++++++- 3 files changed, 157 insertions(+), 11 deletions(-) diff --git a/src/java/org/apache/poi/poifs/filesystem/NPOIFSStream.java b/src/java/org/apache/poi/poifs/filesystem/NPOIFSStream.java index 859bde1469..84e0e4c0ce 100644 --- a/src/java/org/apache/poi/poifs/filesystem/NPOIFSStream.java +++ b/src/java/org/apache/poi/poifs/filesystem/NPOIFSStream.java @@ -127,6 +127,13 @@ public class NPOIFSStream implements Iterable if(prevBlock != POIFSConstants.END_OF_CHAIN) { blockStore.setNextBlock(prevBlock, thisBlock); } + blockStore.setNextBlock(thisBlock, POIFSConstants.END_OF_CHAIN); + + // If we've just written the first block on a + // new stream, save the start block offset + if(this.startBlock == POIFSConstants.END_OF_CHAIN) { + this.startBlock = thisBlock; + } } else { loopDetector.claim(thisBlock); nextBlock = blockStore.getNextBlock(thisBlock); @@ -142,19 +149,33 @@ public class NPOIFSStream implements Iterable int lastBlock = prevBlock; // If we're overwriting, free any remaining blocks + NPOIFSStream toFree = new NPOIFSStream(blockStore, nextBlock); + toFree.free(loopDetector); + + // Mark the end of the stream + blockStore.setNextBlock(lastBlock, POIFSConstants.END_OF_CHAIN); + } + + // TODO Streaming write support too + + /** + * Frees all blocks in the stream + */ + public void free() throws IOException { + ChainLoopDetector loopDetector = blockStore.getChainLoopDetector(); + free(loopDetector); + } + private void free(ChainLoopDetector loopDetector) { + int nextBlock = startBlock; while(nextBlock != POIFSConstants.END_OF_CHAIN) { int thisBlock = nextBlock; loopDetector.claim(thisBlock); nextBlock = blockStore.getNextBlock(thisBlock); blockStore.setNextBlock(thisBlock, POIFSConstants.UNUSED_BLOCK); } - - // Mark the end of the stream - blockStore.setNextBlock(lastBlock, POIFSConstants.END_OF_CHAIN); + this.startBlock = POIFSConstants.END_OF_CHAIN; } - // TODO Streaming write support too - /** * Class that handles a streaming read of one stream */ diff --git a/src/testcases/org/apache/poi/poifs/filesystem/TestNPOIFSMiniStore.java b/src/testcases/org/apache/poi/poifs/filesystem/TestNPOIFSMiniStore.java index 985ad015e4..8f495903b7 100644 --- a/src/testcases/org/apache/poi/poifs/filesystem/TestNPOIFSMiniStore.java +++ b/src/testcases/org/apache/poi/poifs/filesystem/TestNPOIFSMiniStore.java @@ -245,6 +245,7 @@ public final class TestNPOIFSMiniStore extends TestCase { * big blocks that make up the ministream as needed */ public void testCreateBlockIfNeeded() throws Exception { - // TODO + // TODO Add underlying implementation + // TODO Add unit test } } diff --git a/src/testcases/org/apache/poi/poifs/filesystem/TestNPOIFSStream.java b/src/testcases/org/apache/poi/poifs/filesystem/TestNPOIFSStream.java index b9223e4e94..8705e7ac37 100644 --- a/src/testcases/org/apache/poi/poifs/filesystem/TestNPOIFSStream.java +++ b/src/testcases/org/apache/poi/poifs/filesystem/TestNPOIFSStream.java @@ -27,8 +27,6 @@ import org.apache.poi.poifs.common.POIFSConstants; /** * Tests {@link NPOIFSStream} - * - * TODO Write unit tests */ public final class TestNPOIFSStream extends TestCase { private static final POIDataSamples _inst = POIDataSamples.getPOIFSInstance(); @@ -254,8 +252,53 @@ public final class TestNPOIFSStream extends TestCase { */ public void testReadMiniStreams() throws Exception { NPOIFSFileSystem fs = new NPOIFSFileSystem(_inst.openResourceAsStream("BlockSize512.zvi")); + NPOIFSMiniStore ministore = fs.getMiniStore(); - // TODO + // 178 -> 179 -> 180 -> end + NPOIFSStream stream = new NPOIFSStream(ministore, 178); + Iterator i = stream.getBlockIterator(); + assertEquals(true, i.hasNext()); + assertEquals(true, i.hasNext()); + assertEquals(true, i.hasNext()); + ByteBuffer b178 = i.next(); + assertEquals(true, i.hasNext()); + assertEquals(true, i.hasNext()); + ByteBuffer b179 = i.next(); + assertEquals(true, i.hasNext()); + ByteBuffer b180 = i.next(); + assertEquals(false, i.hasNext()); + assertEquals(false, i.hasNext()); + assertEquals(false, i.hasNext()); + + // Check the contents of the 1st block + assertEquals((byte)0xfe, b178.get()); + assertEquals((byte)0xff, b178.get()); + assertEquals((byte)0x00, b178.get()); + assertEquals((byte)0x00, b178.get()); + assertEquals((byte)0x05, b178.get()); + assertEquals((byte)0x01, b178.get()); + assertEquals((byte)0x02, b178.get()); + assertEquals((byte)0x00, b178.get()); + + // And the 2nd + assertEquals((byte)0x6c, b179.get()); + assertEquals((byte)0x00, b179.get()); + assertEquals((byte)0x00, b179.get()); + assertEquals((byte)0x00, b179.get()); + assertEquals((byte)0x28, b179.get()); + assertEquals((byte)0x00, b179.get()); + assertEquals((byte)0x00, b179.get()); + assertEquals((byte)0x00, b179.get()); + + // And the 3rd + assertEquals((byte)0x30, b180.get()); + assertEquals((byte)0x00, b180.get()); + assertEquals((byte)0x00, b180.get()); + assertEquals((byte)0x00, b180.get()); + assertEquals((byte)0x00, b180.get()); + assertEquals((byte)0x00, b180.get()); + assertEquals((byte)0x00, b180.get()); + assertEquals((byte)0x80, b180.get()); } /** @@ -375,9 +418,90 @@ public final class TestNPOIFSStream extends TestCase { * Writes to a new stream in the file */ public void testWriteNewStream() throws Exception { - NPOIFSFileSystem fs = new NPOIFSFileSystem(_inst.getFile("BlockSize512.zvi")); + NPOIFSFileSystem fs = new NPOIFSFileSystem(_inst.openResourceAsStream("BlockSize512.zvi")); - // TODO + // 100 is our first free one + assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(99)); + assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(100)); + assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(101)); + assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(102)); + assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(103)); + assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(104)); + + + // Add a single block one + byte[] data = new byte[512]; + for(int i=0; i it = stream.getBlockIterator(); + int count = 0; + while(it.hasNext()) { + ByteBuffer b = it.next(); + data = new byte[512]; + b.get(data); + for(int i=0; i