2010-12-19 03:06:48 -05:00
|
|
|
/* ====================================================================
|
|
|
|
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;
|
|
|
|
|
2014-04-21 10:37:33 -04:00
|
|
|
import static org.hamcrest.core.IsEqual.equalTo;
|
|
|
|
import static org.junit.Assert.assertEquals;
|
|
|
|
import static org.junit.Assert.assertThat;
|
|
|
|
import static org.junit.Assert.fail;
|
|
|
|
|
2011-05-12 18:10:51 -04:00
|
|
|
import java.io.ByteArrayInputStream;
|
|
|
|
import java.io.ByteArrayOutputStream;
|
2014-04-21 10:37:33 -04:00
|
|
|
import java.io.File;
|
|
|
|
import java.io.IOException;
|
2010-12-23 02:08:50 -05:00
|
|
|
import java.nio.ByteBuffer;
|
2010-12-26 20:51:10 -05:00
|
|
|
import java.util.Iterator;
|
2010-12-23 02:08:50 -05:00
|
|
|
|
2010-12-19 03:06:48 -05:00
|
|
|
import org.apache.poi.POIDataSamples;
|
2010-12-28 03:52:50 -05:00
|
|
|
import org.apache.poi.hpsf.PropertySet;
|
|
|
|
import org.apache.poi.hpsf.PropertySetFactory;
|
|
|
|
import org.apache.poi.hpsf.SummaryInformation;
|
2010-12-22 03:52:17 -05:00
|
|
|
import org.apache.poi.poifs.common.POIFSConstants;
|
2010-12-26 20:51:10 -05:00
|
|
|
import org.apache.poi.poifs.property.NPropertyTable;
|
|
|
|
import org.apache.poi.poifs.property.Property;
|
|
|
|
import org.apache.poi.poifs.property.RootProperty;
|
2011-05-19 07:54:29 -04:00
|
|
|
import org.apache.poi.poifs.storage.HeaderBlock;
|
2014-04-21 10:37:33 -04:00
|
|
|
import org.apache.poi.util.IOUtils;
|
|
|
|
import org.junit.Test;
|
2010-12-19 03:06:48 -05:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Tests for the new NIO POIFSFileSystem implementation
|
|
|
|
*/
|
2014-04-21 10:37:33 -04:00
|
|
|
public final class TestNPOIFSFileSystem {
|
2010-12-19 03:06:48 -05:00
|
|
|
private static final POIDataSamples _inst = POIDataSamples.getPOIFSInstance();
|
2014-04-24 16:23:43 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns test files with 512 byte and 4k block sizes, loaded
|
|
|
|
* both from InputStreams and Files
|
|
|
|
*/
|
|
|
|
protected NPOIFSFileSystem[] get512and4kFileAndInput() throws Exception {
|
|
|
|
NPOIFSFileSystem fsA = new NPOIFSFileSystem(_inst.getFile("BlockSize512.zvi"));
|
|
|
|
NPOIFSFileSystem fsB = new NPOIFSFileSystem(_inst.openResourceAsStream("BlockSize512.zvi"));
|
|
|
|
NPOIFSFileSystem fsC = new NPOIFSFileSystem(_inst.getFile("BlockSize4096.zvi"));
|
|
|
|
NPOIFSFileSystem fsD = new NPOIFSFileSystem(_inst.openResourceAsStream("BlockSize4096.zvi"));
|
|
|
|
return new NPOIFSFileSystem[] {fsA,fsB,fsC,fsD};
|
|
|
|
}
|
2010-12-19 03:06:48 -05:00
|
|
|
|
2014-04-24 13:25:10 -04:00
|
|
|
protected static void assertBATCount(NPOIFSFileSystem fs, int expectedBAT, int expectedXBAT) throws IOException {
|
|
|
|
int foundBAT = 0;
|
|
|
|
int foundXBAT = 0;
|
|
|
|
int sz = (int)(fs.size() / fs.getBigBlockSize());
|
|
|
|
for (int i=0; i<sz; i++) {
|
|
|
|
if(fs.getNextBlock(i) == POIFSConstants.FAT_SECTOR_BLOCK) {
|
|
|
|
foundBAT++;
|
|
|
|
}
|
|
|
|
if(fs.getNextBlock(i) == POIFSConstants.DIFAT_SECTOR_BLOCK) {
|
|
|
|
foundXBAT++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
assertEquals("Wrong number of BATs", expectedBAT, foundBAT);
|
|
|
|
assertEquals("Wrong number of XBATs with " + expectedBAT + " BATs", expectedXBAT, foundXBAT);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected static HeaderBlock writeOutAndReadHeader(NPOIFSFileSystem fs) throws IOException {
|
|
|
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
|
|
|
fs.writeFilesystem(baos);
|
|
|
|
|
|
|
|
HeaderBlock header = new HeaderBlock(new ByteArrayInputStream(baos.toByteArray()));
|
|
|
|
return header;
|
|
|
|
}
|
|
|
|
|
2014-04-24 18:22:06 -04:00
|
|
|
protected static NPOIFSFileSystem writeOutAndReadBack(NPOIFSFileSystem original) throws IOException {
|
|
|
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
|
|
|
original.writeFilesystem(baos);
|
|
|
|
original.close();
|
|
|
|
return new NPOIFSFileSystem(new ByteArrayInputStream(baos.toByteArray()));
|
|
|
|
}
|
|
|
|
|
2014-04-21 10:37:33 -04:00
|
|
|
@Test
|
|
|
|
public void basicOpen() throws Exception {
|
2010-12-19 03:06:48 -05:00
|
|
|
NPOIFSFileSystem fsA, fsB;
|
|
|
|
|
|
|
|
// With a simple 512 block file
|
|
|
|
fsA = new NPOIFSFileSystem(_inst.getFile("BlockSize512.zvi"));
|
|
|
|
fsB = new NPOIFSFileSystem(_inst.openResourceAsStream("BlockSize512.zvi"));
|
|
|
|
for(NPOIFSFileSystem fs : new NPOIFSFileSystem[] {fsA,fsB}) {
|
|
|
|
assertEquals(512, fs.getBigBlockSize());
|
|
|
|
}
|
|
|
|
|
|
|
|
// Now with a simple 4096 block file
|
|
|
|
fsA = new NPOIFSFileSystem(_inst.getFile("BlockSize4096.zvi"));
|
|
|
|
fsB = new NPOIFSFileSystem(_inst.openResourceAsStream("BlockSize4096.zvi"));
|
|
|
|
for(NPOIFSFileSystem fs : new NPOIFSFileSystem[] {fsA,fsB}) {
|
|
|
|
assertEquals(4096, fs.getBigBlockSize());
|
|
|
|
}
|
|
|
|
}
|
2010-12-19 03:53:36 -05:00
|
|
|
|
2014-04-21 10:37:33 -04:00
|
|
|
@Test
|
|
|
|
public void propertiesAndFatOnRead() throws Exception {
|
2010-12-19 03:53:36 -05:00
|
|
|
NPOIFSFileSystem fsA, fsB;
|
|
|
|
|
|
|
|
// With a simple 512 block file
|
|
|
|
fsA = new NPOIFSFileSystem(_inst.getFile("BlockSize512.zvi"));
|
|
|
|
fsB = new NPOIFSFileSystem(_inst.openResourceAsStream("BlockSize512.zvi"));
|
|
|
|
for(NPOIFSFileSystem fs : new NPOIFSFileSystem[] {fsA,fsB}) {
|
2010-12-23 04:21:49 -05:00
|
|
|
// Check the FAT was properly processed:
|
|
|
|
// Verify we only got one block
|
|
|
|
fs.getBATBlockAndIndex(0);
|
|
|
|
fs.getBATBlockAndIndex(1);
|
|
|
|
try {
|
|
|
|
fs.getBATBlockAndIndex(140);
|
|
|
|
fail("Should only be one BAT, but a 2nd was found");
|
|
|
|
} catch(IndexOutOfBoundsException e) {}
|
|
|
|
|
|
|
|
// Verify a few next offsets
|
|
|
|
// 97 -> 98 -> END
|
|
|
|
assertEquals(98, fs.getNextBlock(97));
|
|
|
|
assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(98));
|
2010-12-19 03:53:36 -05:00
|
|
|
|
2010-12-26 20:51:10 -05:00
|
|
|
|
2010-12-19 03:53:36 -05:00
|
|
|
// Check the properties
|
2010-12-26 20:51:10 -05:00
|
|
|
NPropertyTable props = fs._get_property_table();
|
|
|
|
assertEquals(90, props.getStartBlock());
|
|
|
|
assertEquals(7, props.countBlocks());
|
|
|
|
|
|
|
|
// Root property tells us about the Mini Stream
|
|
|
|
RootProperty root = props.getRoot();
|
|
|
|
assertEquals("Root Entry", root.getName());
|
|
|
|
assertEquals(11564, root.getSize());
|
|
|
|
assertEquals(0, root.getStartBlock());
|
|
|
|
|
|
|
|
// Check its children too
|
|
|
|
Property prop;
|
|
|
|
Iterator<Property> pi = root.getChildren();
|
|
|
|
prop = pi.next();
|
|
|
|
assertEquals("Thumbnail", prop.getName());
|
|
|
|
prop = pi.next();
|
|
|
|
assertEquals("\u0005DocumentSummaryInformation", prop.getName());
|
|
|
|
prop = pi.next();
|
|
|
|
assertEquals("\u0005SummaryInformation", prop.getName());
|
|
|
|
prop = pi.next();
|
|
|
|
assertEquals("Image", prop.getName());
|
|
|
|
prop = pi.next();
|
|
|
|
assertEquals("Tags", prop.getName());
|
|
|
|
assertEquals(false, pi.hasNext());
|
|
|
|
|
|
|
|
|
|
|
|
// Check the SBAT (Small Blocks FAT) was properly processed
|
2010-12-27 02:53:05 -05:00
|
|
|
NPOIFSMiniStore ministore = fs.getMiniStore();
|
|
|
|
|
|
|
|
// Verify we only got two SBAT blocks
|
|
|
|
ministore.getBATBlockAndIndex(0);
|
|
|
|
ministore.getBATBlockAndIndex(128);
|
|
|
|
try {
|
|
|
|
ministore.getBATBlockAndIndex(256);
|
|
|
|
fail("Should only be two SBATs, but a 3rd was found");
|
|
|
|
} catch(IndexOutOfBoundsException e) {}
|
|
|
|
|
|
|
|
// Verify a few offsets: 0->50 is a stream
|
|
|
|
for(int i=0; i<50; i++) {
|
|
|
|
assertEquals(i+1, ministore.getNextBlock(i));
|
|
|
|
}
|
|
|
|
assertEquals(POIFSConstants.END_OF_CHAIN, ministore.getNextBlock(50));
|
2010-12-19 03:53:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// Now with a simple 4096 block file
|
|
|
|
fsA = new NPOIFSFileSystem(_inst.getFile("BlockSize4096.zvi"));
|
|
|
|
fsB = new NPOIFSFileSystem(_inst.openResourceAsStream("BlockSize4096.zvi"));
|
|
|
|
for(NPOIFSFileSystem fs : new NPOIFSFileSystem[] {fsA,fsB}) {
|
|
|
|
// Check the FAT was properly processed
|
2010-12-23 04:21:49 -05:00
|
|
|
// Verify we only got one block
|
|
|
|
fs.getBATBlockAndIndex(0);
|
|
|
|
fs.getBATBlockAndIndex(1);
|
|
|
|
try {
|
|
|
|
fs.getBATBlockAndIndex(1040);
|
|
|
|
fail("Should only be one BAT, but a 2nd was found");
|
|
|
|
} catch(IndexOutOfBoundsException e) {}
|
|
|
|
|
|
|
|
// Verify a few next offsets
|
|
|
|
// 0 -> 1 -> 2 -> END
|
|
|
|
assertEquals(1, fs.getNextBlock(0));
|
|
|
|
assertEquals(2, fs.getNextBlock(1));
|
|
|
|
assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(2));
|
2010-12-26 20:51:10 -05:00
|
|
|
|
2010-12-19 03:53:36 -05:00
|
|
|
|
|
|
|
// Check the properties
|
2010-12-26 20:51:10 -05:00
|
|
|
NPropertyTable props = fs._get_property_table();
|
|
|
|
assertEquals(12, props.getStartBlock());
|
|
|
|
assertEquals(1, props.countBlocks());
|
|
|
|
|
|
|
|
// Root property tells us about the Mini Stream
|
|
|
|
RootProperty root = props.getRoot();
|
|
|
|
assertEquals("Root Entry", root.getName());
|
|
|
|
assertEquals(11564, root.getSize());
|
|
|
|
assertEquals(0, root.getStartBlock());
|
|
|
|
|
|
|
|
// Check its children too
|
|
|
|
Property prop;
|
|
|
|
Iterator<Property> pi = root.getChildren();
|
|
|
|
prop = pi.next();
|
|
|
|
assertEquals("Thumbnail", prop.getName());
|
|
|
|
prop = pi.next();
|
|
|
|
assertEquals("\u0005DocumentSummaryInformation", prop.getName());
|
|
|
|
prop = pi.next();
|
|
|
|
assertEquals("\u0005SummaryInformation", prop.getName());
|
|
|
|
prop = pi.next();
|
|
|
|
assertEquals("Image", prop.getName());
|
|
|
|
prop = pi.next();
|
|
|
|
assertEquals("Tags", prop.getName());
|
|
|
|
assertEquals(false, pi.hasNext());
|
|
|
|
|
|
|
|
|
|
|
|
// Check the SBAT (Small Blocks FAT) was properly processed
|
2010-12-27 02:53:05 -05:00
|
|
|
NPOIFSMiniStore ministore = fs.getMiniStore();
|
|
|
|
|
|
|
|
// Verify we only got one SBAT block
|
|
|
|
ministore.getBATBlockAndIndex(0);
|
|
|
|
ministore.getBATBlockAndIndex(128);
|
|
|
|
ministore.getBATBlockAndIndex(1023);
|
|
|
|
try {
|
|
|
|
ministore.getBATBlockAndIndex(1024);
|
|
|
|
fail("Should only be one SBAT, but a 2nd was found");
|
|
|
|
} catch(IndexOutOfBoundsException e) {}
|
|
|
|
|
|
|
|
// Verify a few offsets: 0->50 is a stream
|
|
|
|
for(int i=0; i<50; i++) {
|
|
|
|
assertEquals(i+1, ministore.getNextBlock(i));
|
|
|
|
}
|
|
|
|
assertEquals(POIFSConstants.END_OF_CHAIN, ministore.getNextBlock(50));
|
2010-12-19 03:53:36 -05:00
|
|
|
}
|
|
|
|
}
|
2010-12-22 03:52:17 -05:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Check that for a given block, we can correctly figure
|
|
|
|
* out what the next one is
|
|
|
|
*/
|
2014-04-21 10:37:33 -04:00
|
|
|
@Test
|
|
|
|
public void nextBlock() throws Exception {
|
2010-12-23 04:21:49 -05:00
|
|
|
NPOIFSFileSystem fsA = new NPOIFSFileSystem(_inst.getFile("BlockSize512.zvi"));
|
|
|
|
NPOIFSFileSystem fsB = new NPOIFSFileSystem(_inst.openResourceAsStream("BlockSize512.zvi"));
|
|
|
|
for(NPOIFSFileSystem fs : new NPOIFSFileSystem[] {fsA,fsB}) {
|
|
|
|
// 0 -> 21 are simple
|
|
|
|
for(int i=0; i<21; i++) {
|
|
|
|
assertEquals(i+1, fs.getNextBlock(i));
|
|
|
|
}
|
|
|
|
// 21 jumps to 89, then ends
|
|
|
|
assertEquals(89, fs.getNextBlock(21));
|
|
|
|
assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(89));
|
|
|
|
|
|
|
|
// 22 -> 88 simple sequential stream
|
|
|
|
for(int i=22; i<88; i++) {
|
|
|
|
assertEquals(i+1, fs.getNextBlock(i));
|
|
|
|
}
|
|
|
|
assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(88));
|
|
|
|
|
|
|
|
// 90 -> 96 is another stream
|
|
|
|
for(int i=90; i<96; i++) {
|
|
|
|
assertEquals(i+1, fs.getNextBlock(i));
|
|
|
|
}
|
|
|
|
assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(96));
|
|
|
|
|
|
|
|
// 97+98 is another
|
|
|
|
assertEquals(98, fs.getNextBlock(97));
|
|
|
|
assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(98));
|
|
|
|
|
|
|
|
// 99 is our FAT block
|
|
|
|
assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(99));
|
|
|
|
|
|
|
|
// 100 onwards is free
|
|
|
|
for(int i=100; i<fs.getBigBlockSizeDetails().getBATEntriesPerBlock(); i++) {
|
|
|
|
assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(i));
|
|
|
|
}
|
2010-12-22 03:52:17 -05:00
|
|
|
}
|
|
|
|
|
2010-12-26 20:51:10 -05:00
|
|
|
// Quick check on 4096 byte blocks too
|
|
|
|
fsA = new NPOIFSFileSystem(_inst.getFile("BlockSize4096.zvi"));
|
|
|
|
fsB = new NPOIFSFileSystem(_inst.openResourceAsStream("BlockSize4096.zvi"));
|
|
|
|
for(NPOIFSFileSystem fs : new NPOIFSFileSystem[] {fsA,fsB}) {
|
|
|
|
// 0 -> 1 -> 2 -> end
|
|
|
|
assertEquals(1, fs.getNextBlock(0));
|
|
|
|
assertEquals(2, fs.getNextBlock(1));
|
|
|
|
assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(2));
|
|
|
|
|
|
|
|
// 4 -> 11 then end
|
|
|
|
for(int i=4; i<11; i++) {
|
|
|
|
assertEquals(i+1, fs.getNextBlock(i));
|
|
|
|
}
|
|
|
|
assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(11));
|
|
|
|
}
|
2010-12-22 03:52:17 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check we get the right data back for each block
|
|
|
|
*/
|
2014-04-21 10:37:33 -04:00
|
|
|
@Test
|
|
|
|
public void getBlock() throws Exception {
|
2010-12-23 04:21:49 -05:00
|
|
|
NPOIFSFileSystem fsA = new NPOIFSFileSystem(_inst.getFile("BlockSize512.zvi"));
|
|
|
|
NPOIFSFileSystem fsB = new NPOIFSFileSystem(_inst.openResourceAsStream("BlockSize512.zvi"));
|
|
|
|
for(NPOIFSFileSystem fs : new NPOIFSFileSystem[] {fsA,fsB}) {
|
|
|
|
ByteBuffer b;
|
|
|
|
|
|
|
|
// The 0th block is the first data block
|
|
|
|
b = fs.getBlockAt(0);
|
|
|
|
assertEquals((byte)0x9e, b.get());
|
|
|
|
assertEquals((byte)0x75, b.get());
|
|
|
|
assertEquals((byte)0x97, b.get());
|
|
|
|
assertEquals((byte)0xf6, b.get());
|
|
|
|
|
|
|
|
// And the next block
|
|
|
|
b = fs.getBlockAt(1);
|
|
|
|
assertEquals((byte)0x86, b.get());
|
|
|
|
assertEquals((byte)0x09, b.get());
|
|
|
|
assertEquals((byte)0x22, b.get());
|
|
|
|
assertEquals((byte)0xfb, b.get());
|
|
|
|
|
|
|
|
// Check the final block too
|
|
|
|
b = fs.getBlockAt(99);
|
|
|
|
assertEquals((byte)0x01, b.get());
|
|
|
|
assertEquals((byte)0x00, b.get());
|
|
|
|
assertEquals((byte)0x00, b.get());
|
|
|
|
assertEquals((byte)0x00, b.get());
|
|
|
|
assertEquals((byte)0x02, b.get());
|
|
|
|
assertEquals((byte)0x00, b.get());
|
|
|
|
assertEquals((byte)0x00, b.get());
|
|
|
|
assertEquals((byte)0x00, b.get());
|
|
|
|
}
|
2010-12-23 02:08:50 -05:00
|
|
|
|
2010-12-26 20:51:10 -05:00
|
|
|
// Quick check on 4096 byte blocks too
|
|
|
|
fsA = new NPOIFSFileSystem(_inst.getFile("BlockSize4096.zvi"));
|
|
|
|
fsB = new NPOIFSFileSystem(_inst.openResourceAsStream("BlockSize4096.zvi"));
|
|
|
|
for(NPOIFSFileSystem fs : new NPOIFSFileSystem[] {fsA,fsB}) {
|
|
|
|
ByteBuffer b;
|
|
|
|
|
|
|
|
// The 0th block is the first data block
|
|
|
|
b = fs.getBlockAt(0);
|
|
|
|
assertEquals((byte)0x9e, b.get());
|
|
|
|
assertEquals((byte)0x75, b.get());
|
|
|
|
assertEquals((byte)0x97, b.get());
|
|
|
|
assertEquals((byte)0xf6, b.get());
|
|
|
|
|
|
|
|
// And the next block
|
|
|
|
b = fs.getBlockAt(1);
|
|
|
|
assertEquals((byte)0x00, b.get());
|
|
|
|
assertEquals((byte)0x00, b.get());
|
|
|
|
assertEquals((byte)0x03, b.get());
|
|
|
|
assertEquals((byte)0x00, b.get());
|
|
|
|
|
|
|
|
// The 14th block is the FAT
|
|
|
|
b = fs.getBlockAt(14);
|
|
|
|
assertEquals((byte)0x01, b.get());
|
|
|
|
assertEquals((byte)0x00, b.get());
|
|
|
|
assertEquals((byte)0x00, b.get());
|
|
|
|
assertEquals((byte)0x00, b.get());
|
|
|
|
assertEquals((byte)0x02, b.get());
|
|
|
|
assertEquals((byte)0x00, b.get());
|
|
|
|
assertEquals((byte)0x00, b.get());
|
|
|
|
assertEquals((byte)0x00, b.get());
|
|
|
|
}
|
2010-12-22 03:52:17 -05:00
|
|
|
}
|
2010-12-23 03:02:50 -05:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Ask for free blocks where there are some already
|
|
|
|
* to be had from the FAT
|
|
|
|
*/
|
2014-04-21 10:37:33 -04:00
|
|
|
@Test
|
|
|
|
public void getFreeBlockWithSpare() throws Exception {
|
2010-12-23 03:02:50 -05:00
|
|
|
NPOIFSFileSystem fs = new NPOIFSFileSystem(_inst.getFile("BlockSize512.zvi"));
|
|
|
|
|
|
|
|
// Our first BAT block has spares
|
|
|
|
assertEquals(true, fs.getBATBlockAndIndex(0).getBlock().hasFreeSectors());
|
|
|
|
|
|
|
|
// First free one is 100
|
|
|
|
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));
|
|
|
|
|
|
|
|
// Ask, will get 100
|
|
|
|
assertEquals(100, fs.getFreeBlock());
|
|
|
|
|
|
|
|
// Ask again, will still get 100 as not written to
|
|
|
|
assertEquals(100, fs.getFreeBlock());
|
|
|
|
|
|
|
|
// Allocate it, then ask again
|
|
|
|
fs.setNextBlock(100, POIFSConstants.END_OF_CHAIN);
|
|
|
|
assertEquals(101, fs.getFreeBlock());
|
2014-04-24 13:25:10 -04:00
|
|
|
|
|
|
|
// All done
|
|
|
|
fs.close();
|
2010-12-23 03:02:50 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Ask for free blocks where no free ones exist, and so the
|
|
|
|
* file needs to be extended and another BAT/XBAT added
|
|
|
|
*/
|
2014-04-21 10:37:33 -04:00
|
|
|
@Test
|
|
|
|
public void getFreeBlockWithNoneSpare() throws Exception {
|
2010-12-23 03:02:50 -05:00
|
|
|
NPOIFSFileSystem fs = new NPOIFSFileSystem(_inst.openResourceAsStream("BlockSize512.zvi"));
|
2011-01-01 01:49:53 -05:00
|
|
|
int free;
|
2010-12-27 23:43:19 -05:00
|
|
|
|
|
|
|
// We have one BAT at block 99
|
|
|
|
assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(99));
|
2010-12-23 03:02:50 -05:00
|
|
|
|
|
|
|
// We've spare ones from 100 to 128
|
|
|
|
for(int i=100; i<128; i++) {
|
|
|
|
assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(i));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check our BAT knows it's free
|
|
|
|
assertEquals(true, fs.getBATBlockAndIndex(0).getBlock().hasFreeSectors());
|
|
|
|
|
|
|
|
// Allocate all the spare ones
|
|
|
|
for(int i=100; i<128; i++) {
|
|
|
|
fs.setNextBlock(i, POIFSConstants.END_OF_CHAIN);
|
|
|
|
}
|
|
|
|
|
|
|
|
// BAT is now full, but there's only the one
|
|
|
|
assertEquals(false, fs.getBATBlockAndIndex(0).getBlock().hasFreeSectors());
|
|
|
|
try {
|
|
|
|
assertEquals(false, fs.getBATBlockAndIndex(128).getBlock().hasFreeSectors());
|
|
|
|
fail("Should only be one BAT");
|
|
|
|
} catch(IndexOutOfBoundsException e) {}
|
2014-04-24 13:25:10 -04:00
|
|
|
assertBATCount(fs, 1, 0);
|
|
|
|
|
2010-12-23 03:02:50 -05:00
|
|
|
|
|
|
|
// Now ask for a free one, will need to extend the file
|
|
|
|
assertEquals(129, fs.getFreeBlock());
|
|
|
|
|
|
|
|
assertEquals(false, fs.getBATBlockAndIndex(0).getBlock().hasFreeSectors());
|
|
|
|
assertEquals(true, fs.getBATBlockAndIndex(128).getBlock().hasFreeSectors());
|
|
|
|
assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(128));
|
|
|
|
assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(129));
|
|
|
|
|
2014-04-24 13:25:10 -04:00
|
|
|
// We now have 2 BATs, but no XBATs
|
|
|
|
assertBATCount(fs, 2, 0);
|
|
|
|
|
2010-12-23 03:02:50 -05:00
|
|
|
|
|
|
|
// Fill up to hold 109 BAT blocks
|
2011-01-01 01:49:53 -05:00
|
|
|
for(int i=0; i<109; i++) {
|
|
|
|
fs.getFreeBlock();
|
|
|
|
int startOffset = i*128;
|
|
|
|
while( fs.getBATBlockAndIndex(startOffset).getBlock().hasFreeSectors() ) {
|
|
|
|
free = fs.getFreeBlock();
|
|
|
|
fs.setNextBlock(free, POIFSConstants.END_OF_CHAIN);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
assertEquals(false, fs.getBATBlockAndIndex(109*128-1).getBlock().hasFreeSectors());
|
|
|
|
try {
|
|
|
|
assertEquals(false, fs.getBATBlockAndIndex(109*128).getBlock().hasFreeSectors());
|
|
|
|
fail("Should only be 109 BATs");
|
|
|
|
} catch(IndexOutOfBoundsException e) {}
|
|
|
|
|
2014-04-24 13:25:10 -04:00
|
|
|
// We now have 109 BATs, but no XBATs
|
|
|
|
assertBATCount(fs, 109, 0);
|
|
|
|
|
|
|
|
|
|
|
|
// Ask for it to be written out, and check the header
|
|
|
|
HeaderBlock header = writeOutAndReadHeader(fs);
|
|
|
|
assertEquals(109, header.getBATCount());
|
|
|
|
assertEquals(0, header.getXBATCount());
|
|
|
|
|
2010-12-23 03:02:50 -05:00
|
|
|
|
|
|
|
// Ask for another, will get our first XBAT
|
2011-01-01 01:49:53 -05:00
|
|
|
free = fs.getFreeBlock();
|
|
|
|
assertEquals(false, fs.getBATBlockAndIndex(109*128-1).getBlock().hasFreeSectors());
|
|
|
|
assertEquals(true, fs.getBATBlockAndIndex(110*128-1).getBlock().hasFreeSectors());
|
|
|
|
try {
|
|
|
|
assertEquals(false, fs.getBATBlockAndIndex(110*128).getBlock().hasFreeSectors());
|
|
|
|
fail("Should only be 110 BATs");
|
|
|
|
} catch(IndexOutOfBoundsException e) {}
|
2014-04-24 13:25:10 -04:00
|
|
|
assertBATCount(fs, 110, 1);
|
|
|
|
|
|
|
|
header = writeOutAndReadHeader(fs);
|
|
|
|
assertEquals(110, header.getBATCount());
|
|
|
|
assertEquals(1, header.getXBATCount());
|
2011-01-01 01:49:53 -05:00
|
|
|
|
2010-12-23 03:02:50 -05:00
|
|
|
|
2011-01-01 01:49:53 -05:00
|
|
|
// Fill the XBAT, which means filling 127 BATs
|
|
|
|
for(int i=109; i<109+127; i++) {
|
|
|
|
fs.getFreeBlock();
|
|
|
|
int startOffset = i*128;
|
|
|
|
while( fs.getBATBlockAndIndex(startOffset).getBlock().hasFreeSectors() ) {
|
|
|
|
free = fs.getFreeBlock();
|
|
|
|
fs.setNextBlock(free, POIFSConstants.END_OF_CHAIN);
|
|
|
|
}
|
2014-04-24 13:25:10 -04:00
|
|
|
assertBATCount(fs, i+1, 1);
|
2011-01-01 01:49:53 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// Should now have 109+127 = 236 BATs
|
|
|
|
assertEquals(false, fs.getBATBlockAndIndex(236*128-1).getBlock().hasFreeSectors());
|
|
|
|
try {
|
|
|
|
assertEquals(false, fs.getBATBlockAndIndex(236*128).getBlock().hasFreeSectors());
|
|
|
|
fail("Should only be 236 BATs");
|
|
|
|
} catch(IndexOutOfBoundsException e) {}
|
2014-04-24 13:25:10 -04:00
|
|
|
assertBATCount(fs, 236, 1);
|
2011-01-01 01:49:53 -05:00
|
|
|
|
2010-12-23 03:02:50 -05:00
|
|
|
|
|
|
|
// Ask for another, will get our 2nd XBAT
|
2011-01-01 01:49:53 -05:00
|
|
|
free = fs.getFreeBlock();
|
|
|
|
assertEquals(false, fs.getBATBlockAndIndex(236*128-1).getBlock().hasFreeSectors());
|
|
|
|
assertEquals(true, fs.getBATBlockAndIndex(237*128-1).getBlock().hasFreeSectors());
|
|
|
|
try {
|
|
|
|
assertEquals(false, fs.getBATBlockAndIndex(237*128).getBlock().hasFreeSectors());
|
|
|
|
fail("Should only be 237 BATs");
|
|
|
|
} catch(IndexOutOfBoundsException e) {}
|
2011-05-19 07:54:29 -04:00
|
|
|
|
|
|
|
|
2014-04-24 13:25:10 -04:00
|
|
|
// Check the counts now
|
|
|
|
assertBATCount(fs, 237, 2);
|
2011-01-01 01:49:53 -05:00
|
|
|
|
2014-04-24 13:25:10 -04:00
|
|
|
// Check the header
|
|
|
|
header = writeOutAndReadHeader(fs);
|
2010-12-23 03:02:50 -05:00
|
|
|
|
2014-04-24 13:25:10 -04:00
|
|
|
|
|
|
|
// Now, write it out, and read it back in again fully
|
2014-04-24 18:22:06 -04:00
|
|
|
fs = writeOutAndReadBack(fs);
|
2014-04-24 13:25:10 -04:00
|
|
|
|
|
|
|
// Check that it is seen correctly
|
|
|
|
assertBATCount(fs, 237, 2);
|
2014-04-24 16:23:43 -04:00
|
|
|
|
|
|
|
assertEquals(false, fs.getBATBlockAndIndex(236*128-1).getBlock().hasFreeSectors());
|
|
|
|
assertEquals(true, fs.getBATBlockAndIndex(237*128-1).getBlock().hasFreeSectors());
|
|
|
|
try {
|
|
|
|
assertEquals(false, fs.getBATBlockAndIndex(237*128).getBlock().hasFreeSectors());
|
|
|
|
fail("Should only be 237 BATs");
|
|
|
|
} catch(IndexOutOfBoundsException e) {}
|
|
|
|
|
2014-04-24 13:25:10 -04:00
|
|
|
|
|
|
|
// All done
|
|
|
|
fs.close();
|
2010-12-23 03:02:50 -05:00
|
|
|
}
|
2010-12-27 02:53:05 -05:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Test that we can correctly get the list of directory
|
|
|
|
* entries, and the details on the files in them
|
|
|
|
*/
|
2014-04-21 10:37:33 -04:00
|
|
|
@Test
|
|
|
|
public void listEntries() throws Exception {
|
2014-04-24 16:23:43 -04:00
|
|
|
for(NPOIFSFileSystem fs : get512and4kFileAndInput()) {
|
2010-12-28 01:21:40 -05:00
|
|
|
DirectoryEntry root = fs.getRoot();
|
|
|
|
assertEquals(5, root.getEntryCount());
|
|
|
|
|
|
|
|
// Check by the names
|
|
|
|
Entry thumbnail = root.getEntry("Thumbnail");
|
|
|
|
Entry dsi = root.getEntry("\u0005DocumentSummaryInformation");
|
|
|
|
Entry si = root.getEntry("\u0005SummaryInformation");
|
|
|
|
Entry image = root.getEntry("Image");
|
|
|
|
Entry tags = root.getEntry("Tags");
|
|
|
|
|
|
|
|
assertEquals(false, thumbnail.isDirectoryEntry());
|
|
|
|
assertEquals(false, dsi.isDirectoryEntry());
|
|
|
|
assertEquals(false, si.isDirectoryEntry());
|
|
|
|
assertEquals(true, image.isDirectoryEntry());
|
|
|
|
assertEquals(false, tags.isDirectoryEntry());
|
|
|
|
|
|
|
|
// Check via the iterator
|
|
|
|
Iterator<Entry> it = root.getEntries();
|
|
|
|
assertEquals(thumbnail.getName(), it.next().getName());
|
|
|
|
assertEquals(dsi.getName(), it.next().getName());
|
|
|
|
assertEquals(si.getName(), it.next().getName());
|
|
|
|
assertEquals(image.getName(), it.next().getName());
|
|
|
|
assertEquals(tags.getName(), it.next().getName());
|
|
|
|
|
|
|
|
// Look inside another
|
|
|
|
DirectoryEntry imageD = (DirectoryEntry)image;
|
|
|
|
assertEquals(7, imageD.getEntryCount());
|
2010-12-27 02:53:05 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Tests that we can get the correct contents for
|
|
|
|
* a document in the filesystem
|
|
|
|
*/
|
2014-04-21 10:37:33 -04:00
|
|
|
@Test
|
|
|
|
public void getDocumentEntry() throws Exception {
|
2014-04-24 16:23:43 -04:00
|
|
|
for(NPOIFSFileSystem fs : get512and4kFileAndInput()) {
|
2010-12-28 01:21:40 -05:00
|
|
|
DirectoryEntry root = fs.getRoot();
|
2010-12-28 03:52:50 -05:00
|
|
|
Entry si = root.getEntry("\u0005SummaryInformation");
|
|
|
|
|
|
|
|
assertEquals(true, si.isDocumentEntry());
|
|
|
|
DocumentNode doc = (DocumentNode)si;
|
2010-12-28 01:21:40 -05:00
|
|
|
|
2010-12-28 03:52:50 -05:00
|
|
|
// Check we can read it
|
|
|
|
NDocumentInputStream inp = new NDocumentInputStream(doc);
|
|
|
|
byte[] contents = new byte[doc.getSize()];
|
|
|
|
assertEquals(doc.getSize(), inp.read(contents));
|
2014-04-24 16:23:43 -04:00
|
|
|
inp.close();
|
2010-12-28 01:21:40 -05:00
|
|
|
|
2010-12-28 03:52:50 -05:00
|
|
|
// Now try to build the property set
|
|
|
|
inp = new NDocumentInputStream(doc);
|
|
|
|
PropertySet ps = PropertySetFactory.create(inp);
|
|
|
|
SummaryInformation inf = (SummaryInformation)ps;
|
2010-12-28 01:21:40 -05:00
|
|
|
|
2010-12-28 03:52:50 -05:00
|
|
|
// Check some bits in it
|
|
|
|
assertEquals(null, inf.getApplicationName());
|
|
|
|
assertEquals(null, inf.getAuthor());
|
|
|
|
assertEquals(null, inf.getSubject());
|
2014-04-24 13:25:10 -04:00
|
|
|
|
|
|
|
// Finish
|
|
|
|
inp.close();
|
2010-12-27 02:53:05 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-01-01 01:49:53 -05:00
|
|
|
/**
|
|
|
|
* Read a file, write it and read it again.
|
|
|
|
* Then, alter+add some streams, write and read
|
|
|
|
*/
|
2014-04-21 10:37:33 -04:00
|
|
|
@Test
|
|
|
|
public void readWriteRead() throws Exception {
|
2014-04-24 16:23:43 -04:00
|
|
|
for(NPOIFSFileSystem fs : get512and4kFileAndInput()) {
|
|
|
|
// Check we can find the entries we expect
|
|
|
|
// TODO Add check
|
|
|
|
|
|
|
|
// Write out, re-load
|
|
|
|
// TODO Add check
|
|
|
|
|
|
|
|
// Check they're still there
|
|
|
|
// TODO Add check
|
|
|
|
|
|
|
|
// Check the first few and last few bytes of a few
|
|
|
|
// TODO Add check
|
|
|
|
|
|
|
|
// Add a test mini stream
|
|
|
|
// TODO Add check
|
|
|
|
|
|
|
|
// Write out, re-load
|
|
|
|
// TODO Add check
|
|
|
|
|
|
|
|
// Check old and new are there
|
|
|
|
// TODO Add check
|
|
|
|
|
|
|
|
// Add a full stream, delete a full stream
|
|
|
|
// TODO Add check
|
|
|
|
|
|
|
|
// Write out, re-load
|
|
|
|
// TODO Add check
|
|
|
|
|
|
|
|
// Check it's all there
|
|
|
|
// TODO Add check
|
|
|
|
|
|
|
|
// All done
|
|
|
|
fs.close();
|
|
|
|
}
|
2011-01-01 01:49:53 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create a new file, write it and read it again
|
|
|
|
* Then, add some streams, write and read
|
|
|
|
*/
|
2014-04-21 10:37:33 -04:00
|
|
|
@Test
|
|
|
|
public void createWriteRead() throws Exception {
|
2011-05-12 18:10:51 -04:00
|
|
|
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());
|
2014-04-25 13:06:10 -04:00
|
|
|
|
|
|
|
// Check that no properties table has been written yet
|
|
|
|
assertEquals(POIFSConstants.END_OF_CHAIN, fs._get_property_table().getStartBlock());
|
2011-05-12 18:10:51 -04:00
|
|
|
|
|
|
|
// Write and read it
|
2014-04-24 18:22:06 -04:00
|
|
|
fs = writeOutAndReadBack(fs);
|
2011-05-12 18:10:51 -04:00
|
|
|
|
2014-04-21 10:37:33 -04:00
|
|
|
// Property table entries have been added to the blocks
|
2011-05-12 18:10:51 -04:00
|
|
|
assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(0));
|
|
|
|
assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(1));
|
2014-04-21 10:37:33 -04:00
|
|
|
assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(2));
|
|
|
|
assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(3));
|
2011-05-12 18:10:51 -04:00
|
|
|
assertEquals(POIFSConstants.END_OF_CHAIN, fs.getRoot().getProperty().getStartBlock());
|
2014-04-25 13:06:10 -04:00
|
|
|
assertEquals(2, fs._get_property_table().getStartBlock());
|
2011-05-12 18:10:51 -04:00
|
|
|
|
|
|
|
|
2014-04-24 17:08:34 -04:00
|
|
|
// Put everything within a new directory
|
|
|
|
DirectoryEntry testDir = fs.createDirectory("Test Directory");
|
|
|
|
|
|
|
|
// Add a new Normal Stream (Normal Streams minimum 4096 bytes)
|
|
|
|
byte[] main4096 = new byte[4096];
|
|
|
|
main4096[0] = -10;
|
|
|
|
main4096[4095] = -11;
|
|
|
|
testDir.createDocument("Normal4096", new ByteArrayInputStream(main4096));
|
|
|
|
|
|
|
|
assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(0));
|
|
|
|
assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(1));
|
|
|
|
assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(2));
|
2014-04-25 14:14:28 -04:00
|
|
|
assertEquals(4, fs.getNextBlock(3));
|
|
|
|
assertEquals(5, fs.getNextBlock(4));
|
|
|
|
assertEquals(6, fs.getNextBlock(5));
|
|
|
|
assertEquals(7, fs.getNextBlock(6));
|
|
|
|
assertEquals(8, fs.getNextBlock(7));
|
|
|
|
assertEquals(9, fs.getNextBlock(8));
|
|
|
|
assertEquals(10, fs.getNextBlock(9));
|
|
|
|
assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(10));
|
|
|
|
assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(11));
|
|
|
|
|
2014-04-24 17:08:34 -04:00
|
|
|
assertEquals(POIFSConstants.END_OF_CHAIN, fs.getRoot().getProperty().getStartBlock());
|
|
|
|
|
|
|
|
|
|
|
|
// Add a bigger Normal Stream
|
|
|
|
byte[] main5124 = new byte[5124];
|
|
|
|
main5124[0] = -22;
|
|
|
|
main5124[5123] = -33;
|
|
|
|
testDir.createDocument("Normal5124", new ByteArrayInputStream(main5124));
|
|
|
|
|
|
|
|
assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(0));
|
|
|
|
assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(1));
|
|
|
|
assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(2));
|
2014-04-25 14:14:28 -04:00
|
|
|
assertEquals(4, fs.getNextBlock(3));
|
|
|
|
assertEquals(5, fs.getNextBlock(4));
|
|
|
|
assertEquals(6, fs.getNextBlock(5));
|
|
|
|
assertEquals(7, fs.getNextBlock(6));
|
|
|
|
assertEquals(8, fs.getNextBlock(7));
|
|
|
|
assertEquals(9, fs.getNextBlock(8));
|
|
|
|
assertEquals(10, fs.getNextBlock(9));
|
|
|
|
assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(10));
|
|
|
|
|
|
|
|
assertEquals(12, fs.getNextBlock(11));
|
|
|
|
assertEquals(13, fs.getNextBlock(12));
|
|
|
|
assertEquals(14, fs.getNextBlock(13));
|
|
|
|
assertEquals(15, fs.getNextBlock(14));
|
|
|
|
assertEquals(16, fs.getNextBlock(15));
|
|
|
|
assertEquals(17, fs.getNextBlock(16));
|
|
|
|
assertEquals(18, fs.getNextBlock(17));
|
|
|
|
assertEquals(19, fs.getNextBlock(18));
|
|
|
|
assertEquals(20, fs.getNextBlock(19));
|
|
|
|
assertEquals(21, fs.getNextBlock(20));
|
|
|
|
assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(21));
|
|
|
|
assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(22));
|
|
|
|
|
2014-04-24 17:08:34 -04:00
|
|
|
assertEquals(POIFSConstants.END_OF_CHAIN, fs.getRoot().getProperty().getStartBlock());
|
|
|
|
|
|
|
|
|
|
|
|
// Now Add a mini stream
|
2014-04-25 14:14:28 -04:00
|
|
|
byte[] mini = new byte[] { 42, 0, 1, 2, 3, 4, 42 };
|
2014-04-24 17:08:34 -04:00
|
|
|
testDir.createDocument("Mini", new ByteArrayInputStream(mini));
|
|
|
|
|
|
|
|
// Mini stream will get one block for fat + one block for data
|
|
|
|
assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(0));
|
|
|
|
assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(1));
|
|
|
|
assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(2));
|
2014-04-25 14:14:28 -04:00
|
|
|
assertEquals(4, fs.getNextBlock(3));
|
|
|
|
assertEquals(5, fs.getNextBlock(4));
|
|
|
|
assertEquals(6, fs.getNextBlock(5));
|
|
|
|
assertEquals(7, fs.getNextBlock(6));
|
|
|
|
assertEquals(8, fs.getNextBlock(7));
|
|
|
|
assertEquals(9, fs.getNextBlock(8));
|
|
|
|
assertEquals(10, fs.getNextBlock(9));
|
|
|
|
assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(10));
|
|
|
|
|
|
|
|
assertEquals(12, fs.getNextBlock(11));
|
|
|
|
assertEquals(13, fs.getNextBlock(12));
|
|
|
|
assertEquals(14, fs.getNextBlock(13));
|
|
|
|
assertEquals(15, fs.getNextBlock(14));
|
|
|
|
assertEquals(16, fs.getNextBlock(15));
|
|
|
|
assertEquals(17, fs.getNextBlock(16));
|
|
|
|
assertEquals(18, fs.getNextBlock(17));
|
|
|
|
assertEquals(19, fs.getNextBlock(18));
|
|
|
|
assertEquals(20, fs.getNextBlock(19));
|
|
|
|
assertEquals(21, fs.getNextBlock(20));
|
|
|
|
assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(21));
|
|
|
|
assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(22));
|
|
|
|
assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(23));
|
|
|
|
assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(24));
|
|
|
|
|
2014-04-25 13:06:10 -04:00
|
|
|
// Check the mini stream location was set
|
2014-04-25 14:14:28 -04:00
|
|
|
// (22 is mini fat, 23 is first mini stream block)
|
|
|
|
assertEquals(23, fs.getRoot().getProperty().getStartBlock());
|
2014-04-24 17:08:34 -04:00
|
|
|
|
|
|
|
|
|
|
|
// Write and read back
|
2014-04-24 18:22:06 -04:00
|
|
|
fs = writeOutAndReadBack(fs);
|
|
|
|
|
|
|
|
// Check it's all unchanged
|
|
|
|
assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(0));
|
|
|
|
assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(1));
|
2014-04-25 14:14:28 -04:00
|
|
|
if(1==0) { // TODO FIX
|
2014-04-24 18:22:06 -04:00
|
|
|
assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(2));
|
2014-04-25 14:14:28 -04:00
|
|
|
assertEquals(4, fs.getNextBlock(3));
|
|
|
|
assertEquals(5, fs.getNextBlock(4));
|
|
|
|
assertEquals(6, fs.getNextBlock(5));
|
|
|
|
assertEquals(7, fs.getNextBlock(6));
|
|
|
|
assertEquals(8, fs.getNextBlock(7));
|
|
|
|
assertEquals(9, fs.getNextBlock(8));
|
|
|
|
assertEquals(10, fs.getNextBlock(9));
|
|
|
|
assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(10));
|
|
|
|
|
|
|
|
assertEquals(12, fs.getNextBlock(11));
|
|
|
|
assertEquals(13, fs.getNextBlock(12));
|
|
|
|
assertEquals(14, fs.getNextBlock(13));
|
|
|
|
assertEquals(15, fs.getNextBlock(14));
|
|
|
|
assertEquals(16, fs.getNextBlock(15));
|
|
|
|
assertEquals(17, fs.getNextBlock(16));
|
|
|
|
assertEquals(18, fs.getNextBlock(17));
|
|
|
|
assertEquals(19, fs.getNextBlock(18));
|
|
|
|
assertEquals(20, fs.getNextBlock(19));
|
|
|
|
assertEquals(21, fs.getNextBlock(20));
|
|
|
|
assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(21));
|
|
|
|
assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(22));
|
|
|
|
assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(23));
|
|
|
|
assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(24));
|
2014-04-25 13:06:10 -04:00
|
|
|
}
|
2014-04-25 14:14:28 -04:00
|
|
|
|
|
|
|
assertEquals(23, fs.getRoot().getProperty().getStartBlock());
|
2014-04-25 13:06:10 -04:00
|
|
|
|
2014-04-24 18:22:06 -04:00
|
|
|
|
|
|
|
// Check some data
|
2014-04-24 17:08:34 -04:00
|
|
|
// TODO
|
2014-04-24 18:22:06 -04:00
|
|
|
|
|
|
|
|
|
|
|
// All done
|
|
|
|
fs.close();
|
2014-04-24 17:08:34 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
public void addBeforeWrite() throws Exception {
|
|
|
|
NPOIFSFileSystem fs = new NPOIFSFileSystem();
|
2014-04-25 06:57:15 -04:00
|
|
|
NDocumentInputStream inp;
|
2014-04-25 13:06:10 -04:00
|
|
|
DocumentEntry miniDoc;
|
|
|
|
DocumentEntry normDoc;
|
|
|
|
HeaderBlock hdr;
|
2014-04-24 17:08:34 -04:00
|
|
|
|
|
|
|
// Initially has BAT + Properties but nothing else
|
|
|
|
assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(0));
|
|
|
|
assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(1));
|
|
|
|
assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(2));
|
2014-04-25 13:06:10 -04:00
|
|
|
|
|
|
|
hdr = writeOutAndReadHeader(fs);
|
|
|
|
// No mini stream, and no xbats
|
|
|
|
// Will have fat then properties stream
|
|
|
|
assertEquals(1, hdr.getBATCount());
|
|
|
|
assertEquals(0, hdr.getBATArray()[0]);
|
|
|
|
assertEquals(2, hdr.getPropertyStart());
|
|
|
|
assertEquals(POIFSConstants.END_OF_CHAIN, hdr.getSBATStart());
|
|
|
|
assertEquals(POIFSConstants.END_OF_CHAIN, hdr.getXBATIndex());
|
|
|
|
assertEquals(POIFSConstants.SMALLER_BIG_BLOCK_SIZE*4, fs.size());
|
|
|
|
|
|
|
|
|
|
|
|
// Get a clean filesystem to start with
|
|
|
|
fs = new NPOIFSFileSystem();
|
|
|
|
|
|
|
|
// Put our test files in a non-standard place
|
2014-04-25 06:57:15 -04:00
|
|
|
DirectoryEntry parentDir = fs.createDirectory("Parent Directory");
|
|
|
|
DirectoryEntry testDir = parentDir.createDirectory("Test Directory");
|
|
|
|
|
|
|
|
|
2014-04-24 17:08:34 -04:00
|
|
|
// Add to the mini stream
|
2014-04-25 13:06:10 -04:00
|
|
|
byte[] mini = new byte[] { 42, 0, 1, 2, 3, 4, 42 };
|
2014-04-25 06:57:15 -04:00
|
|
|
testDir.createDocument("Mini", new ByteArrayInputStream(mini));
|
2014-04-24 17:08:34 -04:00
|
|
|
|
|
|
|
// Add to the main stream
|
2014-04-25 06:57:15 -04:00
|
|
|
byte[] main4096 = new byte[4096];
|
|
|
|
main4096[0] = -10;
|
|
|
|
main4096[4095] = -11;
|
|
|
|
testDir.createDocument("Normal4096", new ByteArrayInputStream(main4096));
|
|
|
|
|
|
|
|
|
|
|
|
// Check the mini stream was added, then the main stream
|
|
|
|
assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(0));
|
2014-04-25 14:14:28 -04:00
|
|
|
assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(1));
|
|
|
|
assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(2)); // Mini Fat
|
|
|
|
assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(3)); // Mini Stream
|
|
|
|
assertEquals(5, fs.getNextBlock(4)); // Main Stream
|
2014-04-25 06:57:15 -04:00
|
|
|
assertEquals(6, fs.getNextBlock(5));
|
|
|
|
assertEquals(7, fs.getNextBlock(6));
|
|
|
|
assertEquals(8, fs.getNextBlock(7));
|
|
|
|
assertEquals(9, fs.getNextBlock(8));
|
|
|
|
assertEquals(10, fs.getNextBlock(9));
|
|
|
|
assertEquals(11, fs.getNextBlock(10));
|
|
|
|
assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(11));
|
|
|
|
assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(12));
|
2014-04-25 13:06:10 -04:00
|
|
|
assertEquals(POIFSConstants.SMALLER_BIG_BLOCK_SIZE*13, fs.size());
|
|
|
|
|
|
|
|
|
|
|
|
// Check that we can read the right data pre-write
|
|
|
|
miniDoc = (DocumentEntry)testDir.getEntry("Mini");
|
|
|
|
inp = new NDocumentInputStream(miniDoc);
|
|
|
|
byte[] miniRead = new byte[miniDoc.getSize()];
|
|
|
|
assertEquals(miniDoc.getSize(), inp.read(miniRead));
|
|
|
|
assertThat(mini, equalTo(miniRead));
|
|
|
|
inp.close();
|
|
|
|
|
|
|
|
normDoc = (DocumentEntry)testDir.getEntry("Normal4096");
|
|
|
|
inp = new NDocumentInputStream(normDoc);
|
|
|
|
byte[] normRead = new byte[normDoc.getSize()];
|
|
|
|
assertEquals(normDoc.getSize(), inp.read(normRead));
|
|
|
|
assertThat(main4096, equalTo(normRead));
|
|
|
|
inp.close();
|
2014-04-25 06:57:15 -04:00
|
|
|
|
2014-04-24 17:08:34 -04:00
|
|
|
|
|
|
|
// Write, read, check
|
2014-04-25 13:06:10 -04:00
|
|
|
hdr = writeOutAndReadHeader(fs);
|
2014-04-25 06:57:15 -04:00
|
|
|
fs = writeOutAndReadBack(fs);
|
|
|
|
|
2014-04-25 13:06:10 -04:00
|
|
|
// Check the header details - will have the sbat near the start,
|
|
|
|
// then the properties at the end
|
|
|
|
assertEquals(1, hdr.getBATCount());
|
|
|
|
assertEquals(0, hdr.getBATArray()[0]);
|
|
|
|
assertEquals(2, hdr.getSBATStart());
|
|
|
|
assertEquals(12, hdr.getPropertyStart());
|
|
|
|
assertEquals(POIFSConstants.END_OF_CHAIN, hdr.getXBATIndex());
|
|
|
|
|
|
|
|
// Check the block allocation is unchanged, other than
|
|
|
|
// the properties stream going in at the end
|
2014-04-25 06:57:15 -04:00
|
|
|
assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(0));
|
|
|
|
assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(1));
|
2014-04-25 14:14:28 -04:00
|
|
|
assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(2));
|
2014-04-25 06:57:15 -04:00
|
|
|
assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(3));
|
|
|
|
assertEquals(5, fs.getNextBlock(4));
|
|
|
|
assertEquals(6, fs.getNextBlock(5));
|
|
|
|
assertEquals(7, fs.getNextBlock(6));
|
|
|
|
assertEquals(8, fs.getNextBlock(7));
|
|
|
|
assertEquals(9, fs.getNextBlock(8));
|
|
|
|
assertEquals(10, fs.getNextBlock(9));
|
|
|
|
assertEquals(11, fs.getNextBlock(10));
|
|
|
|
assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(11));
|
2014-04-25 13:06:10 -04:00
|
|
|
assertEquals(13, fs.getNextBlock(12));
|
|
|
|
assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(13));
|
|
|
|
assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(14));
|
|
|
|
assertEquals(POIFSConstants.SMALLER_BIG_BLOCK_SIZE*15, fs.size());
|
|
|
|
|
2014-04-25 06:57:15 -04:00
|
|
|
|
|
|
|
// Check the data
|
|
|
|
DirectoryEntry fsRoot = fs.getRoot();
|
|
|
|
assertEquals(1, fsRoot.getEntryCount());
|
|
|
|
|
|
|
|
parentDir = (DirectoryEntry)fsRoot.getEntry("Parent Directory");
|
|
|
|
assertEquals(1, parentDir.getEntryCount());
|
|
|
|
|
|
|
|
testDir = (DirectoryEntry)parentDir.getEntry("Test Directory");
|
|
|
|
assertEquals(2, testDir.getEntryCount());
|
|
|
|
|
2014-04-25 13:06:10 -04:00
|
|
|
miniDoc = (DocumentEntry)testDir.getEntry("Mini");
|
2014-04-25 06:57:15 -04:00
|
|
|
inp = new NDocumentInputStream(miniDoc);
|
2014-04-25 13:06:10 -04:00
|
|
|
miniRead = new byte[miniDoc.getSize()];
|
2014-04-25 06:57:15 -04:00
|
|
|
assertEquals(miniDoc.getSize(), inp.read(miniRead));
|
|
|
|
assertThat(mini, equalTo(miniRead));
|
2014-04-25 13:06:10 -04:00
|
|
|
inp.close();
|
2014-04-25 06:57:15 -04:00
|
|
|
|
2014-04-25 13:06:10 -04:00
|
|
|
normDoc = (DocumentEntry)testDir.getEntry("Normal4096");
|
2014-04-25 06:57:15 -04:00
|
|
|
inp = new NDocumentInputStream(normDoc);
|
2014-04-25 13:06:10 -04:00
|
|
|
normRead = new byte[normDoc.getSize()];
|
2014-04-25 06:57:15 -04:00
|
|
|
assertEquals(normDoc.getSize(), inp.read(normRead));
|
|
|
|
assertThat(main4096, equalTo(normRead));
|
|
|
|
inp.close();
|
2014-04-25 13:06:10 -04:00
|
|
|
|
|
|
|
|
|
|
|
// Add one more stream to each, then save and re-load
|
|
|
|
|
|
|
|
// Recheck
|
|
|
|
// TODO
|
2011-01-01 01:49:53 -05:00
|
|
|
}
|
2014-04-21 10:37:33 -04:00
|
|
|
|
2014-04-24 13:32:47 -04:00
|
|
|
/**
|
|
|
|
* Test that we can read a file with NPOIFS, create a new NPOIFS instance,
|
|
|
|
* write it out, read it with POIFS, and see the original data
|
|
|
|
*/
|
2014-04-21 10:37:33 -04:00
|
|
|
@Test
|
2014-04-24 13:32:47 -04:00
|
|
|
public void NPOIFSReadCopyWritePOIFSRead() throws Exception {
|
2014-04-21 10:37:33 -04:00
|
|
|
File testFile = POIDataSamples.getSpreadSheetInstance().getFile("Simple.xls");
|
|
|
|
NPOIFSFileSystem src = new NPOIFSFileSystem(testFile);
|
|
|
|
byte wbDataExp[] = IOUtils.toByteArray(src.createDocumentInputStream("Workbook"));
|
|
|
|
|
|
|
|
NPOIFSFileSystem nfs = new NPOIFSFileSystem();
|
2014-04-24 13:32:47 -04:00
|
|
|
EntryUtils.copyNodes(src.getRoot(), nfs.getRoot());
|
2014-04-21 10:37:33 -04:00
|
|
|
src.close();
|
|
|
|
|
|
|
|
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
|
|
|
nfs.writeFilesystem(bos);
|
|
|
|
nfs.close();
|
|
|
|
|
|
|
|
POIFSFileSystem pfs = new POIFSFileSystem(new ByteArrayInputStream(bos.toByteArray()));
|
|
|
|
byte wbDataAct[] = IOUtils.toByteArray(pfs.createDocumentInputStream("Workbook"));
|
|
|
|
|
|
|
|
assertThat(wbDataExp, equalTo(wbDataAct));
|
|
|
|
}
|
2011-01-01 01:49:53 -05:00
|
|
|
|
2014-04-24 16:23:43 -04:00
|
|
|
// TODO Directory/Document create/write/read/delete/change tests
|
2010-12-19 03:06:48 -05:00
|
|
|
}
|