From 14fbfb1321db6218e003695e60b4d6b1b84a61f1 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 | 33 ++++- .../poifs/filesystem/TestNPOIFSMiniStore.java | 3 +- .../poifs/filesystem/TestNPOIFSStream.java | 134 +++++++++++++++++- 3 files changed, 158 insertions(+), 12 deletions(-) diff --git a/src/java/org/apache/poi/poifs/filesystem/NPOIFSStream.java b/src/java/org/apache/poi/poifs/filesystem/NPOIFSStream.java index 859bde146..84e0e4c0c 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,12 +149,8 @@ public class NPOIFSStream implements Iterable int lastBlock = prevBlock; // If we're overwriting, free any remaining blocks - while(nextBlock != POIFSConstants.END_OF_CHAIN) { - int thisBlock = nextBlock; - loopDetector.claim(thisBlock); - nextBlock = blockStore.getNextBlock(thisBlock); - blockStore.setNextBlock(thisBlock, POIFSConstants.UNUSED_BLOCK); - } + NPOIFSStream toFree = new NPOIFSStream(blockStore, nextBlock); + toFree.free(loopDetector); // Mark the end of the stream blockStore.setNextBlock(lastBlock, POIFSConstants.END_OF_CHAIN); @@ -155,6 +158,24 @@ public class NPOIFSStream implements Iterable // 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); + } + this.startBlock = POIFSConstants.END_OF_CHAIN; + } + /** * 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 985ad015e..8f495903b 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 b9223e4e9..8705e7ac3 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