| /* ==================================================================== |
| Licensed to the Apache Software Foundation (ASF) under one or more |
| contributor license agreements. See the NOTICE file distributed with |
| this work for additional information regarding copyright ownership. |
| The ASF licenses this file to You under the Apache License, Version 2.0 |
| (the "License"); you may not use this file except in compliance with |
| the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| ==================================================================== */ |
| |
| package org.apache.poi.poifs.filesystem; |
| |
| import static org.apache.poi.poifs.filesystem.TestNPOIFSFileSystem.writeOutAndReadBack; |
| |
| import java.io.ByteArrayInputStream; |
| import java.nio.ByteBuffer; |
| import java.util.Iterator; |
| |
| import junit.framework.TestCase; |
| |
| import org.apache.poi.POIDataSamples; |
| import org.apache.poi.poifs.common.POIFSConstants; |
| import org.apache.poi.poifs.storage.BATBlock; |
| |
| /** |
| * Tests {@link NPOIFSStream} |
| */ |
| @SuppressWarnings("resource") |
| public final class TestNPOIFSStream extends TestCase { |
| private static final POIDataSamples _inst = POIDataSamples.getPOIFSInstance(); |
| |
| /** |
| * Read a single block stream |
| */ |
| public void testReadTinyStream() throws Exception { |
| NPOIFSFileSystem fs = new NPOIFSFileSystem(_inst.getFile("BlockSize512.zvi")); |
| |
| // 98 is actually the last block in a two block stream... |
| NPOIFSStream stream = new NPOIFSStream(fs, 98); |
| Iterator<ByteBuffer> i = stream.getBlockIterator(); |
| assertEquals(true, i.hasNext()); |
| assertEquals(true, i.hasNext()); |
| assertEquals(true, i.hasNext()); |
| ByteBuffer b = i.next(); |
| assertEquals(false, i.hasNext()); |
| assertEquals(false, i.hasNext()); |
| assertEquals(false, i.hasNext()); |
| |
| // Check the contents |
| assertEquals((byte)0x81, b.get()); |
| assertEquals((byte)0x00, b.get()); |
| assertEquals((byte)0x00, b.get()); |
| assertEquals((byte)0x00, b.get()); |
| assertEquals((byte)0x82, b.get()); |
| assertEquals((byte)0x00, b.get()); |
| assertEquals((byte)0x00, b.get()); |
| assertEquals((byte)0x00, b.get()); |
| |
| fs.close(); |
| } |
| |
| /** |
| * Read a stream with only two blocks in it |
| */ |
| public void testReadShortStream() throws Exception { |
| NPOIFSFileSystem fs = new NPOIFSFileSystem(_inst.getFile("BlockSize512.zvi")); |
| |
| // 97 -> 98 -> end |
| NPOIFSStream stream = new NPOIFSStream(fs, 97); |
| Iterator<ByteBuffer> i = stream.getBlockIterator(); |
| assertEquals(true, i.hasNext()); |
| assertEquals(true, i.hasNext()); |
| assertEquals(true, i.hasNext()); |
| ByteBuffer b97 = i.next(); |
| assertEquals(true, i.hasNext()); |
| assertEquals(true, i.hasNext()); |
| ByteBuffer b98 = i.next(); |
| assertEquals(false, i.hasNext()); |
| assertEquals(false, i.hasNext()); |
| assertEquals(false, i.hasNext()); |
| |
| // Check the contents of the 1st block |
| assertEquals((byte)0x01, b97.get()); |
| assertEquals((byte)0x00, b97.get()); |
| assertEquals((byte)0x00, b97.get()); |
| assertEquals((byte)0x00, b97.get()); |
| assertEquals((byte)0x02, b97.get()); |
| assertEquals((byte)0x00, b97.get()); |
| assertEquals((byte)0x00, b97.get()); |
| assertEquals((byte)0x00, b97.get()); |
| |
| // Check the contents of the 2nd block |
| assertEquals((byte)0x81, b98.get()); |
| assertEquals((byte)0x00, b98.get()); |
| assertEquals((byte)0x00, b98.get()); |
| assertEquals((byte)0x00, b98.get()); |
| assertEquals((byte)0x82, b98.get()); |
| assertEquals((byte)0x00, b98.get()); |
| assertEquals((byte)0x00, b98.get()); |
| assertEquals((byte)0x00, b98.get()); |
| |
| fs.close(); |
| } |
| |
| /** |
| * Read a stream with many blocks |
| */ |
| public void testReadLongerStream() throws Exception { |
| NPOIFSFileSystem fs = new NPOIFSFileSystem(_inst.getFile("BlockSize512.zvi")); |
| |
| ByteBuffer b0 = null; |
| ByteBuffer b1 = null; |
| ByteBuffer b22 = null; |
| |
| // The stream at 0 has 23 blocks in it |
| NPOIFSStream stream = new NPOIFSStream(fs, 0); |
| Iterator<ByteBuffer> i = stream.getBlockIterator(); |
| int count = 0; |
| while(i.hasNext()) { |
| ByteBuffer b = i.next(); |
| if(count == 0) { |
| b0 = b; |
| } |
| if(count == 1) { |
| b1 = b; |
| } |
| if(count == 22) { |
| b22 = b; |
| } |
| |
| count++; |
| } |
| assertEquals(23, count); |
| |
| // Check the contents |
| // 1st block is at 0 |
| assertEquals((byte)0x9e, b0.get()); |
| assertEquals((byte)0x75, b0.get()); |
| assertEquals((byte)0x97, b0.get()); |
| assertEquals((byte)0xf6, b0.get()); |
| |
| // 2nd block is at 1 |
| assertEquals((byte)0x86, b1.get()); |
| assertEquals((byte)0x09, b1.get()); |
| assertEquals((byte)0x22, b1.get()); |
| assertEquals((byte)0xfb, b1.get()); |
| |
| // last block is at 89 |
| assertEquals((byte)0xfe, b22.get()); |
| assertEquals((byte)0xff, b22.get()); |
| assertEquals((byte)0x00, b22.get()); |
| assertEquals((byte)0x00, b22.get()); |
| assertEquals((byte)0x05, b22.get()); |
| assertEquals((byte)0x01, b22.get()); |
| assertEquals((byte)0x02, b22.get()); |
| assertEquals((byte)0x00, b22.get()); |
| |
| fs.close(); |
| } |
| |
| /** |
| * Read a stream with several blocks in a 4096 byte block file |
| */ |
| public void testReadStream4096() throws Exception { |
| NPOIFSFileSystem fs = new NPOIFSFileSystem(_inst.getFile("BlockSize4096.zvi")); |
| |
| // 0 -> 1 -> 2 -> end |
| NPOIFSStream stream = new NPOIFSStream(fs, 0); |
| Iterator<ByteBuffer> i = stream.getBlockIterator(); |
| assertEquals(true, i.hasNext()); |
| assertEquals(true, i.hasNext()); |
| assertEquals(true, i.hasNext()); |
| ByteBuffer b0 = i.next(); |
| assertEquals(true, i.hasNext()); |
| assertEquals(true, i.hasNext()); |
| ByteBuffer b1 = i.next(); |
| assertEquals(true, i.hasNext()); |
| assertEquals(true, i.hasNext()); |
| ByteBuffer b2 = i.next(); |
| assertEquals(false, i.hasNext()); |
| assertEquals(false, i.hasNext()); |
| assertEquals(false, i.hasNext()); |
| |
| // Check the contents of the 1st block |
| assertEquals((byte)0x9E, b0.get()); |
| assertEquals((byte)0x75, b0.get()); |
| assertEquals((byte)0x97, b0.get()); |
| assertEquals((byte)0xF6, b0.get()); |
| assertEquals((byte)0xFF, b0.get()); |
| assertEquals((byte)0x21, b0.get()); |
| assertEquals((byte)0xD2, b0.get()); |
| assertEquals((byte)0x11, b0.get()); |
| |
| // Check the contents of the 2nd block |
| assertEquals((byte)0x00, b1.get()); |
| assertEquals((byte)0x00, b1.get()); |
| assertEquals((byte)0x03, b1.get()); |
| assertEquals((byte)0x00, b1.get()); |
| assertEquals((byte)0x00, b1.get()); |
| assertEquals((byte)0x00, b1.get()); |
| assertEquals((byte)0x00, b1.get()); |
| assertEquals((byte)0x00, b1.get()); |
| |
| // Check the contents of the 3rd block |
| assertEquals((byte)0x6D, b2.get()); |
| assertEquals((byte)0x00, b2.get()); |
| assertEquals((byte)0x00, b2.get()); |
| assertEquals((byte)0x00, b2.get()); |
| assertEquals((byte)0x03, b2.get()); |
| assertEquals((byte)0x00, b2.get()); |
| assertEquals((byte)0x46, b2.get()); |
| assertEquals((byte)0x00, b2.get()); |
| |
| fs.close(); |
| } |
| |
| /** |
| * Craft a nasty file with a loop, and ensure we don't get stuck |
| */ |
| public void testReadFailsOnLoop() throws Exception { |
| NPOIFSFileSystem fs = new NPOIFSFileSystem(_inst.getFile("BlockSize512.zvi")); |
| |
| // Hack the FAT so that it goes 0->1->2->0 |
| fs.setNextBlock(0, 1); |
| fs.setNextBlock(1, 2); |
| fs.setNextBlock(2, 0); |
| |
| // Now try to read |
| NPOIFSStream stream = new NPOIFSStream(fs, 0); |
| Iterator<ByteBuffer> i = stream.getBlockIterator(); |
| assertEquals(true, i.hasNext()); |
| |
| // 1st read works |
| i.next(); |
| assertEquals(true, i.hasNext()); |
| |
| // 2nd read works |
| i.next(); |
| assertEquals(true, i.hasNext()); |
| |
| // 3rd read works |
| i.next(); |
| assertEquals(true, i.hasNext()); |
| |
| // 4th read blows up as it loops back to 0 |
| try { |
| i.next(); |
| fail("Loop should have been detected but wasn't!"); |
| } catch(RuntimeException e) { |
| // Good, it was detected |
| } |
| assertEquals(true, i.hasNext()); |
| |
| fs.close(); |
| } |
| |
| /** |
| * Tests that we can load some streams that are |
| * stored in the mini stream. |
| */ |
| public void testReadMiniStreams() throws Exception { |
| NPOIFSFileSystem fs = new NPOIFSFileSystem(_inst.openResourceAsStream("BlockSize512.zvi")); |
| NPOIFSMiniStore ministore = fs.getMiniStore(); |
| |
| // 178 -> 179 -> 180 -> end |
| NPOIFSStream stream = new NPOIFSStream(ministore, 178); |
| Iterator<ByteBuffer> 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()); |
| |
| fs.close(); |
| } |
| |
| /** |
| * Writing the same amount of data as before |
| */ |
| public void testReplaceStream() throws Exception { |
| NPOIFSFileSystem fs = new NPOIFSFileSystem(_inst.openResourceAsStream("BlockSize512.zvi")); |
| |
| byte[] data = new byte[512]; |
| for(int i=0; i<data.length; i++) { |
| data[i] = (byte)(i%256); |
| } |
| |
| // 98 is actually the last block in a two block stream... |
| NPOIFSStream stream = new NPOIFSStream(fs, 98); |
| stream.updateContents(data); |
| |
| // Check the reading of blocks |
| Iterator<ByteBuffer> it = stream.getBlockIterator(); |
| assertEquals(true, it.hasNext()); |
| ByteBuffer b = it.next(); |
| assertEquals(false, it.hasNext()); |
| |
| // Now check the contents |
| data = new byte[512]; |
| b.get(data); |
| for(int i=0; i<data.length; i++) { |
| byte exp = (byte)(i%256); |
| assertEquals(exp, data[i]); |
| } |
| |
| fs.close(); |
| } |
| |
| /** |
| * Writes less data than before, some blocks will need |
| * to be freed |
| */ |
| public void testReplaceStreamWithLess() throws Exception { |
| NPOIFSFileSystem fs = new NPOIFSFileSystem(_inst.openResourceAsStream("BlockSize512.zvi")); |
| |
| byte[] data = new byte[512]; |
| for(int i=0; i<data.length; i++) { |
| data[i] = (byte)(i%256); |
| } |
| |
| // 97 -> 98 -> end |
| assertEquals(98, fs.getNextBlock(97)); |
| assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(98)); |
| |
| // Create a 2 block stream, will become a 1 block one |
| NPOIFSStream stream = new NPOIFSStream(fs, 97); |
| stream.updateContents(data); |
| |
| // 97 should now be the end, and 98 free |
| assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(97)); |
| assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(98)); |
| |
| // Check the reading of blocks |
| Iterator<ByteBuffer> it = stream.getBlockIterator(); |
| assertEquals(true, it.hasNext()); |
| ByteBuffer b = it.next(); |
| assertEquals(false, it.hasNext()); |
| |
| // Now check the contents |
| data = new byte[512]; |
| b.get(data); |
| for(int i=0; i<data.length; i++) { |
| byte exp = (byte)(i%256); |
| assertEquals(exp, data[i]); |
| } |
| |
| fs.close(); |
| } |
| |
| /** |
| * Writes more data than before, new blocks will be needed |
| */ |
| public void testReplaceStreamWithMore() throws Exception { |
| NPOIFSFileSystem fs = new NPOIFSFileSystem(_inst.openResourceAsStream("BlockSize512.zvi")); |
| |
| byte[] data = new byte[512*3]; |
| for(int i=0; i<data.length; i++) { |
| data[i] = (byte)(i%256); |
| } |
| |
| // 97 -> 98 -> end |
| assertEquals(98, fs.getNextBlock(97)); |
| assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(98)); |
| |
| // 100 is our first free one |
| assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(99)); |
| assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(100)); |
| |
| // Create a 2 block stream, will become a 3 block one |
| NPOIFSStream stream = new NPOIFSStream(fs, 97); |
| stream.updateContents(data); |
| |
| // 97 -> 98 -> 100 -> end |
| assertEquals(98, fs.getNextBlock(97)); |
| assertEquals(100, fs.getNextBlock(98)); |
| assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(100)); |
| |
| // Check the reading of blocks |
| Iterator<ByteBuffer> 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<data.length; i++) { |
| byte exp = (byte)(i%256); |
| assertEquals(exp, data[i]); |
| } |
| count++; |
| } |
| assertEquals(3, count); |
| |
| fs.close(); |
| } |
| |
| /** |
| * Writes to a new stream in the file |
| */ |
| public void testWriteNewStream() throws Exception { |
| NPOIFSFileSystem fs = new NPOIFSFileSystem(_inst.openResourceAsStream("BlockSize512.zvi")); |
| |
| // 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<data.length; i++) { |
| data[i] = (byte)(i%256); |
| } |
| |
| NPOIFSStream stream = new NPOIFSStream(fs); |
| stream.updateContents(data); |
| |
| // Check it was allocated properly |
| assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(99)); |
| assertEquals(POIFSConstants.END_OF_CHAIN, 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)); |
| |
| // And check the contents |
| Iterator<ByteBuffer> 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<data.length; i++) { |
| byte exp = (byte)(i%256); |
| assertEquals(exp, data[i]); |
| } |
| count++; |
| } |
| assertEquals(1, count); |
| |
| |
| // And a multi block one |
| data = new byte[512*3]; |
| for(int i=0; i<data.length; i++) { |
| data[i] = (byte)(i%256); |
| } |
| |
| stream = new NPOIFSStream(fs); |
| stream.updateContents(data); |
| |
| // Check it was allocated properly |
| assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(99)); |
| assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(100)); |
| assertEquals(102, fs.getNextBlock(101)); |
| assertEquals(103, fs.getNextBlock(102)); |
| assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(103)); |
| assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(104)); |
| |
| // And check the contents |
| it = stream.getBlockIterator(); |
| count = 0; |
| while(it.hasNext()) { |
| ByteBuffer b = it.next(); |
| data = new byte[512]; |
| b.get(data); |
| for(int i=0; i<data.length; i++) { |
| byte exp = (byte)(i%256); |
| assertEquals(exp, data[i]); |
| } |
| count++; |
| } |
| assertEquals(3, count); |
| |
| // Free it |
| stream.free(); |
| assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(99)); |
| assertEquals(POIFSConstants.END_OF_CHAIN, 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)); |
| |
| fs.close(); |
| } |
| |
| /** |
| * Writes to a new stream in the file, where we've not enough |
| * free blocks so new FAT segments will need to be allocated |
| * to support this |
| */ |
| public void testWriteNewStreamExtraFATs() throws Exception { |
| NPOIFSFileSystem fs = new NPOIFSFileSystem(_inst.openResourceAsStream("BlockSize512.zvi")); |
| |
| // Allocate almost all the blocks |
| assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(99)); |
| assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(100)); |
| assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(127)); |
| for(int i=100; i<127; i++) { |
| fs.setNextBlock(i, POIFSConstants.END_OF_CHAIN); |
| } |
| assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(127)); |
| assertEquals(true, fs.getBATBlockAndIndex(0).getBlock().hasFreeSectors()); |
| |
| |
| // Write a 3 block stream |
| byte[] data = new byte[512*3]; |
| for(int i=0; i<data.length; i++) { |
| data[i] = (byte)(i%256); |
| } |
| NPOIFSStream stream = new NPOIFSStream(fs); |
| stream.updateContents(data); |
| |
| // Check we got another BAT |
| assertEquals(false, fs.getBATBlockAndIndex(0).getBlock().hasFreeSectors()); |
| assertEquals(true, fs.getBATBlockAndIndex(128).getBlock().hasFreeSectors()); |
| |
| // the BAT will be in the first spot of the new block |
| assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(126)); |
| assertEquals(129, fs.getNextBlock(127)); |
| assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(128)); |
| assertEquals(130, fs.getNextBlock(129)); |
| assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(130)); |
| assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(131)); |
| |
| fs.close(); |
| } |
| |
| /** |
| * Replaces data in an existing stream, with a bit |
| * more data than before, in a 4096 byte block file |
| */ |
| public void testWriteStream4096() throws Exception { |
| NPOIFSFileSystem fs = new NPOIFSFileSystem(_inst.openResourceAsStream("BlockSize4096.zvi")); |
| |
| // 0 -> 1 -> 2 -> end |
| assertEquals(1, fs.getNextBlock(0)); |
| assertEquals(2, fs.getNextBlock(1)); |
| assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(2)); |
| assertEquals(4, fs.getNextBlock(3)); |
| |
| // First free one is at 15 |
| assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(14)); |
| assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(15)); |
| |
| |
| // Write a 5 block file |
| byte[] data = new byte[4096*5]; |
| for(int i=0; i<data.length; i++) { |
| data[i] = (byte)(i%256); |
| } |
| NPOIFSStream stream = new NPOIFSStream(fs, 0); |
| stream.updateContents(data); |
| |
| |
| // Check it |
| assertEquals(1, fs.getNextBlock(0)); |
| assertEquals(2, fs.getNextBlock(1)); |
| assertEquals(15, fs.getNextBlock(2)); // Jumps |
| assertEquals(4, fs.getNextBlock(3)); // Next stream |
| assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(14)); |
| assertEquals(16, fs.getNextBlock(15)); // Continues |
| assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(16)); // Ends |
| assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(17)); // Free |
| |
| // Check the contents too |
| Iterator<ByteBuffer> 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<data.length; i++) { |
| byte exp = (byte)(i%256); |
| assertEquals(exp, data[i]); |
| } |
| count++; |
| } |
| assertEquals(5, count); |
| |
| fs.close(); |
| } |
| |
| /** |
| * Tests that we can write into the mini stream |
| */ |
| public void testWriteMiniStreams() throws Exception { |
| NPOIFSFileSystem fs = new NPOIFSFileSystem(_inst.openResourceAsStream("BlockSize512.zvi")); |
| NPOIFSMiniStore ministore = fs.getMiniStore(); |
| NPOIFSStream stream = new NPOIFSStream(ministore, 178); |
| |
| // 178 -> 179 -> 180 -> end |
| assertEquals(179, ministore.getNextBlock(178)); |
| assertEquals(180, ministore.getNextBlock(179)); |
| assertEquals(POIFSConstants.END_OF_CHAIN, ministore.getNextBlock(180)); |
| |
| |
| // Try writing 3 full blocks worth |
| byte[] data = new byte[64*3]; |
| for(int i=0; i<data.length; i++) { |
| data[i] = (byte)i; |
| } |
| stream = new NPOIFSStream(ministore, 178); |
| stream.updateContents(data); |
| |
| // Check |
| assertEquals(179, ministore.getNextBlock(178)); |
| assertEquals(180, ministore.getNextBlock(179)); |
| assertEquals(POIFSConstants.END_OF_CHAIN, ministore.getNextBlock(180)); |
| |
| stream = new NPOIFSStream(ministore, 178); |
| Iterator<ByteBuffer> it = stream.getBlockIterator(); |
| ByteBuffer b178 = it.next(); |
| ByteBuffer b179 = it.next(); |
| ByteBuffer b180 = it.next(); |
| assertEquals(false, it.hasNext()); |
| |
| assertEquals((byte)0x00, b178.get()); |
| assertEquals((byte)0x01, b178.get()); |
| assertEquals((byte)0x40, b179.get()); |
| assertEquals((byte)0x41, b179.get()); |
| assertEquals((byte)0x80, b180.get()); |
| assertEquals((byte)0x81, b180.get()); |
| |
| |
| // Try writing just into 3 blocks worth |
| data = new byte[64*2 + 12]; |
| for(int i=0; i<data.length; i++) { |
| data[i] = (byte)(i+4); |
| } |
| stream = new NPOIFSStream(ministore, 178); |
| stream.updateContents(data); |
| |
| // Check |
| assertEquals(179, ministore.getNextBlock(178)); |
| assertEquals(180, ministore.getNextBlock(179)); |
| assertEquals(POIFSConstants.END_OF_CHAIN, ministore.getNextBlock(180)); |
| |
| stream = new NPOIFSStream(ministore, 178); |
| it = stream.getBlockIterator(); |
| b178 = it.next(); |
| b179 = it.next(); |
| b180 = it.next(); |
| assertEquals(false, it.hasNext()); |
| |
| assertEquals((byte)0x04, b178.get(0)); |
| assertEquals((byte)0x05, b178.get(1)); |
| assertEquals((byte)0x44, b179.get(0)); |
| assertEquals((byte)0x45, b179.get(1)); |
| assertEquals((byte)0x84, b180.get(0)); |
| assertEquals((byte)0x85, b180.get(1)); |
| |
| |
| // Try writing 1, should truncate |
| data = new byte[12]; |
| for(int i=0; i<data.length; i++) { |
| data[i] = (byte)(i+9); |
| } |
| stream = new NPOIFSStream(ministore, 178); |
| stream.updateContents(data); |
| |
| assertEquals(POIFSConstants.END_OF_CHAIN, ministore.getNextBlock(178)); |
| assertEquals(POIFSConstants.UNUSED_BLOCK, ministore.getNextBlock(179)); |
| assertEquals(POIFSConstants.UNUSED_BLOCK, ministore.getNextBlock(180)); |
| |
| stream = new NPOIFSStream(ministore, 178); |
| it = stream.getBlockIterator(); |
| b178 = it.next(); |
| assertEquals(false, it.hasNext()); |
| |
| assertEquals((byte)0x09, b178.get(0)); |
| assertEquals((byte)0x0a, b178.get(1)); |
| |
| |
| // Try writing 5, should extend |
| assertEquals(POIFSConstants.END_OF_CHAIN, ministore.getNextBlock(178)); |
| assertEquals(POIFSConstants.UNUSED_BLOCK, ministore.getNextBlock(179)); |
| assertEquals(POIFSConstants.UNUSED_BLOCK, ministore.getNextBlock(180)); |
| assertEquals(POIFSConstants.UNUSED_BLOCK, ministore.getNextBlock(181)); |
| assertEquals(POIFSConstants.UNUSED_BLOCK, ministore.getNextBlock(182)); |
| assertEquals(POIFSConstants.UNUSED_BLOCK, ministore.getNextBlock(183)); |
| |
| data = new byte[64*4 + 12]; |
| for(int i=0; i<data.length; i++) { |
| data[i] = (byte)(i+3); |
| } |
| stream = new NPOIFSStream(ministore, 178); |
| stream.updateContents(data); |
| |
| assertEquals(179, ministore.getNextBlock(178)); |
| assertEquals(180, ministore.getNextBlock(179)); |
| assertEquals(181, ministore.getNextBlock(180)); |
| assertEquals(182, ministore.getNextBlock(181)); |
| assertEquals(POIFSConstants.END_OF_CHAIN, ministore.getNextBlock(182)); |
| |
| stream = new NPOIFSStream(ministore, 178); |
| it = stream.getBlockIterator(); |
| b178 = it.next(); |
| b179 = it.next(); |
| b180 = it.next(); |
| ByteBuffer b181 = it.next(); |
| ByteBuffer b182 = it.next(); |
| assertEquals(false, it.hasNext()); |
| |
| assertEquals((byte)0x03, b178.get(0)); |
| assertEquals((byte)0x04, b178.get(1)); |
| assertEquals((byte)0x43, b179.get(0)); |
| assertEquals((byte)0x44, b179.get(1)); |
| assertEquals((byte)0x83, b180.get(0)); |
| assertEquals((byte)0x84, b180.get(1)); |
| assertEquals((byte)0xc3, b181.get(0)); |
| assertEquals((byte)0xc4, b181.get(1)); |
| assertEquals((byte)0x03, b182.get(0)); |
| assertEquals((byte)0x04, b182.get(1)); |
| |
| |
| // Write lots, so it needs another big block |
| ministore.getBlockAt(183); |
| try { |
| ministore.getBlockAt(184); |
| fail("Block 184 should be off the end of the list"); |
| } catch(IndexOutOfBoundsException e) {} |
| |
| data = new byte[64*6 + 12]; |
| for(int i=0; i<data.length; i++) { |
| data[i] = (byte)(i+1); |
| } |
| stream = new NPOIFSStream(ministore, 178); |
| stream.updateContents(data); |
| |
| // Should have added 2 more blocks to the chain |
| assertEquals(179, ministore.getNextBlock(178)); |
| assertEquals(180, ministore.getNextBlock(179)); |
| assertEquals(181, ministore.getNextBlock(180)); |
| assertEquals(182, ministore.getNextBlock(181)); |
| assertEquals(183, ministore.getNextBlock(182)); |
| assertEquals(184, ministore.getNextBlock(183)); |
| assertEquals(POIFSConstants.END_OF_CHAIN, ministore.getNextBlock(184)); |
| assertEquals(POIFSConstants.UNUSED_BLOCK, ministore.getNextBlock(185)); |
| |
| // Block 184 should exist |
| ministore.getBlockAt(183); |
| ministore.getBlockAt(184); |
| ministore.getBlockAt(185); |
| |
| // Check contents |
| stream = new NPOIFSStream(ministore, 178); |
| it = stream.getBlockIterator(); |
| b178 = it.next(); |
| b179 = it.next(); |
| b180 = it.next(); |
| b181 = it.next(); |
| b182 = it.next(); |
| ByteBuffer b183 = it.next(); |
| ByteBuffer b184 = it.next(); |
| assertEquals(false, it.hasNext()); |
| |
| assertEquals((byte)0x01, b178.get(0)); |
| assertEquals((byte)0x02, b178.get(1)); |
| assertEquals((byte)0x41, b179.get(0)); |
| assertEquals((byte)0x42, b179.get(1)); |
| assertEquals((byte)0x81, b180.get(0)); |
| assertEquals((byte)0x82, b180.get(1)); |
| assertEquals((byte)0xc1, b181.get(0)); |
| assertEquals((byte)0xc2, b181.get(1)); |
| assertEquals((byte)0x01, b182.get(0)); |
| assertEquals((byte)0x02, b182.get(1)); |
| assertEquals((byte)0x41, b183.get(0)); |
| assertEquals((byte)0x42, b183.get(1)); |
| assertEquals((byte)0x81, b184.get(0)); |
| assertEquals((byte)0x82, b184.get(1)); |
| |
| fs.close(); |
| } |
| |
| /** |
| * Craft a nasty file with a loop, and ensure we don't get stuck |
| */ |
| public void testWriteFailsOnLoop() throws Exception { |
| NPOIFSFileSystem fs = new NPOIFSFileSystem(_inst.getFile("BlockSize512.zvi")); |
| |
| // Hack the FAT so that it goes 0->1->2->0 |
| fs.setNextBlock(0, 1); |
| fs.setNextBlock(1, 2); |
| fs.setNextBlock(2, 0); |
| |
| // Try to write a large amount, should fail on the write |
| byte[] data = new byte[512*4]; |
| NPOIFSStream stream = new NPOIFSStream(fs, 0); |
| try { |
| stream.updateContents(data); |
| fail("Loop should have been detected but wasn't!"); |
| } catch(IllegalStateException e) {} |
| |
| // Now reset, and try on a small bit |
| // Should fail during the freeing set |
| fs.setNextBlock(0, 1); |
| fs.setNextBlock(1, 2); |
| fs.setNextBlock(2, 0); |
| |
| data = new byte[512]; |
| stream = new NPOIFSStream(fs, 0); |
| try { |
| stream.updateContents(data); |
| fail("Loop should have been detected but wasn't!"); |
| } catch(IllegalStateException e) {} |
| |
| fs.close(); |
| } |
| |
| /** |
| * Tests adding a new stream, writing and reading it. |
| */ |
| public void testReadWriteNewStream() throws Exception { |
| NPOIFSFileSystem fs = new NPOIFSFileSystem(); |
| NPOIFSStream stream = new NPOIFSStream(fs); |
| |
| // Check our filesystem has Properties then BAT |
| assertEquals(2, fs.getFreeBlock()); |
| BATBlock bat = fs.getBATBlockAndIndex(0).getBlock(); |
| assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(0)); |
| assertEquals(POIFSConstants.FAT_SECTOR_BLOCK,bat.getValueAt(1)); |
| assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(2)); |
| |
| // Check the stream as-is |
| assertEquals(POIFSConstants.END_OF_CHAIN, stream.getStartBlock()); |
| try { |
| stream.getBlockIterator(); |
| fail("Shouldn't be able to get an iterator before writing"); |
| } catch(IllegalStateException e) {} |
| |
| // Write in two blocks |
| byte[] data = new byte[512+20]; |
| for(int i=0; i<512; i++) { |
| data[i] = (byte)(i%256); |
| } |
| for(int i=512; i<data.length; i++) { |
| data[i] = (byte)(i%256 + 100); |
| } |
| stream.updateContents(data); |
| |
| // Check now |
| assertEquals(4, fs.getFreeBlock()); |
| bat = fs.getBATBlockAndIndex(0).getBlock(); |
| assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(0)); |
| assertEquals(POIFSConstants.FAT_SECTOR_BLOCK,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(); |
| assertEquals(true, it.hasNext()); |
| ByteBuffer b = it.next(); |
| |
| byte[] read = new byte[512]; |
| b.get(read); |
| for(int i=0; i<read.length; i++) { |
| assertEquals("Wrong value at " + i, data[i], read[i]); |
| } |
| |
| assertEquals(true, it.hasNext()); |
| b = it.next(); |
| |
| read = new byte[512]; |
| b.get(read); |
| for(int i=0; i<20; i++) { |
| assertEquals(data[i+512], read[i]); |
| } |
| for(int i=20; i<read.length; i++) { |
| assertEquals(0, read[i]); |
| } |
| |
| assertEquals(false, it.hasNext()); |
| |
| fs.close(); |
| } |
| |
| /** |
| * Writes a stream, then replaces it |
| */ |
| public void testWriteThenReplace() throws Exception { |
| NPOIFSFileSystem fs = new NPOIFSFileSystem(); |
| |
| // Starts empty, other that Properties and BAT |
| BATBlock bat = fs.getBATBlockAndIndex(0).getBlock(); |
| assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(0)); |
| assertEquals(POIFSConstants.FAT_SECTOR_BLOCK,bat.getValueAt(1)); |
| assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(2)); |
| |
| // Write something that uses a main stream |
| byte[] main4106 = new byte[4106]; |
| main4106[0] = -10; |
| main4106[4105] = -11; |
| DocumentEntry normal = fs.getRoot().createDocument( |
| "Normal", new ByteArrayInputStream(main4106)); |
| |
| // Should have used 9 blocks |
| assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(0)); |
| assertEquals(POIFSConstants.FAT_SECTOR_BLOCK,bat.getValueAt(1)); |
| assertEquals(3, bat.getValueAt(2)); |
| assertEquals(4, bat.getValueAt(3)); |
| assertEquals(5, bat.getValueAt(4)); |
| assertEquals(6, bat.getValueAt(5)); |
| assertEquals(7, bat.getValueAt(6)); |
| assertEquals(8, bat.getValueAt(7)); |
| assertEquals(9, bat.getValueAt(8)); |
| assertEquals(10, bat.getValueAt(9)); |
| assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(10)); |
| assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(11)); |
| |
| normal = (DocumentEntry)fs.getRoot().getEntry("Normal"); |
| assertEquals(4106, normal.getSize()); |
| assertEquals(4106, ((DocumentNode)normal).getProperty().getSize()); |
| |
| |
| // Replace with one still big enough for a main stream, but one block smaller |
| byte[] main4096 = new byte[4096]; |
| main4096[0] = -10; |
| main4096[4095] = -11; |
| |
| NDocumentOutputStream nout = new NDocumentOutputStream(normal); |
| nout.write(main4096); |
| nout.close(); |
| |
| // Will have dropped to 8 |
| assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(0)); |
| assertEquals(POIFSConstants.FAT_SECTOR_BLOCK,bat.getValueAt(1)); |
| assertEquals(3, bat.getValueAt(2)); |
| assertEquals(4, bat.getValueAt(3)); |
| assertEquals(5, bat.getValueAt(4)); |
| assertEquals(6, bat.getValueAt(5)); |
| assertEquals(7, bat.getValueAt(6)); |
| assertEquals(8, bat.getValueAt(7)); |
| assertEquals(9, bat.getValueAt(8)); |
| assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(9)); |
| assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(10)); |
| assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(11)); |
| |
| normal = (DocumentEntry)fs.getRoot().getEntry("Normal"); |
| assertEquals(4096, normal.getSize()); |
| assertEquals(4096, ((DocumentNode)normal).getProperty().getSize()); |
| |
| |
| // Write and check |
| fs = writeOutAndReadBack(fs); |
| bat = fs.getBATBlockAndIndex(0).getBlock(); |
| |
| // No change after write |
| assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(0)); // Properties |
| assertEquals(POIFSConstants.FAT_SECTOR_BLOCK,bat.getValueAt(1)); |
| assertEquals(3, bat.getValueAt(2)); |
| assertEquals(4, bat.getValueAt(3)); |
| assertEquals(5, bat.getValueAt(4)); |
| assertEquals(6, bat.getValueAt(5)); |
| assertEquals(7, bat.getValueAt(6)); |
| assertEquals(8, bat.getValueAt(7)); |
| assertEquals(9, bat.getValueAt(8)); |
| assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(9)); // End of Normal |
| assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(10)); |
| assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(11)); |
| |
| normal = (DocumentEntry)fs.getRoot().getEntry("Normal"); |
| assertEquals(4096, normal.getSize()); |
| assertEquals(4096, ((DocumentNode)normal).getProperty().getSize()); |
| |
| |
| // Make longer, take 1 block at the end |
| normal = (DocumentEntry)fs.getRoot().getEntry("Normal"); |
| nout = new NDocumentOutputStream(normal); |
| nout.write(main4106); |
| nout.close(); |
| |
| assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(0)); |
| assertEquals(POIFSConstants.FAT_SECTOR_BLOCK,bat.getValueAt(1)); |
| assertEquals(3, bat.getValueAt(2)); |
| assertEquals(4, bat.getValueAt(3)); |
| assertEquals(5, bat.getValueAt(4)); |
| assertEquals(6, bat.getValueAt(5)); |
| assertEquals(7, bat.getValueAt(6)); |
| assertEquals(8, bat.getValueAt(7)); |
| assertEquals(9, bat.getValueAt(8)); |
| assertEquals(10, bat.getValueAt(9)); |
| assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(10)); // Normal |
| assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(11)); |
| assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(12)); |
| |
| normal = (DocumentEntry)fs.getRoot().getEntry("Normal"); |
| assertEquals(4106, normal.getSize()); |
| assertEquals(4106, ((DocumentNode)normal).getProperty().getSize()); |
| |
| |
| // Make it small, will trigger the SBAT stream and free lots up |
| byte[] mini = new byte[] { 42, 0, 1, 2, 3, 4, 42 }; |
| normal = (DocumentEntry)fs.getRoot().getEntry("Normal"); |
| nout = new NDocumentOutputStream(normal); |
| nout.write(mini); |
| nout.close(); |
| |
| assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(0)); |
| assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, bat.getValueAt(1)); |
| assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(2)); // SBAT |
| assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(3)); // Mini Stream |
| assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(4)); |
| assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(5)); |
| assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(6)); |
| assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(7)); |
| assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(8)); |
| assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(9)); |
| assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(10)); |
| assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(11)); |
| assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(12)); |
| |
| normal = (DocumentEntry)fs.getRoot().getEntry("Normal"); |
| assertEquals(7, normal.getSize()); |
| assertEquals(7, ((DocumentNode)normal).getProperty().getSize()); |
| |
| |
| // Finally back to big again |
| nout = new NDocumentOutputStream(normal); |
| nout.write(main4096); |
| nout.close(); |
| |
| // Will keep the mini stream, now empty |
| assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(0)); |
| assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, bat.getValueAt(1)); |
| assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(2)); // SBAT |
| assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(3)); // Mini Stream |
| assertEquals(5, bat.getValueAt(4)); |
| assertEquals(6, bat.getValueAt(5)); |
| assertEquals(7, bat.getValueAt(6)); |
| assertEquals(8, bat.getValueAt(7)); |
| assertEquals(9, bat.getValueAt(8)); |
| assertEquals(10, bat.getValueAt(9)); |
| assertEquals(11, bat.getValueAt(10)); |
| assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(11)); |
| assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(12)); |
| assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(13)); |
| |
| normal = (DocumentEntry)fs.getRoot().getEntry("Normal"); |
| assertEquals(4096, normal.getSize()); |
| assertEquals(4096, ((DocumentNode)normal).getProperty().getSize()); |
| |
| |
| // Save, re-load, re-check |
| fs = writeOutAndReadBack(fs); |
| bat = fs.getBATBlockAndIndex(0).getBlock(); |
| |
| assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(0)); |
| assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, bat.getValueAt(1)); |
| assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(2)); // SBAT |
| assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(3)); // Mini Stream |
| assertEquals(5, bat.getValueAt(4)); |
| assertEquals(6, bat.getValueAt(5)); |
| assertEquals(7, bat.getValueAt(6)); |
| assertEquals(8, bat.getValueAt(7)); |
| assertEquals(9, bat.getValueAt(8)); |
| assertEquals(10, bat.getValueAt(9)); |
| assertEquals(11, bat.getValueAt(10)); |
| assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(11)); |
| assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(12)); |
| assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(13)); |
| |
| normal = (DocumentEntry)fs.getRoot().getEntry("Normal"); |
| assertEquals(4096, normal.getSize()); |
| assertEquals(4096, ((DocumentNode)normal).getProperty().getSize()); |
| |
| fs.close(); |
| } |
| } |