12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424 |
- /* ====================================================================
- 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.hamcrest.core.IsCollectionContaining.hasItem;
- import static org.hamcrest.core.IsEqual.equalTo;
- import static org.junit.Assert.assertEquals;
- import static org.junit.Assert.assertThat;
- import static org.junit.Assert.assertNotNull;
- import static org.junit.Assert.fail;
-
- import java.io.ByteArrayInputStream;
- import java.io.ByteArrayOutputStream;
- import java.io.File;
- import java.io.IOException;
- import java.nio.ByteBuffer;
- import java.util.Iterator;
-
- import org.apache.poi.POIDataSamples;
- import org.apache.poi.hpsf.DocumentSummaryInformation;
- import org.apache.poi.hpsf.PropertySet;
- import org.apache.poi.hpsf.PropertySetFactory;
- import org.apache.poi.hpsf.SummaryInformation;
- import org.apache.poi.poifs.common.POIFSConstants;
- import org.apache.poi.poifs.property.NPropertyTable;
- import org.apache.poi.poifs.property.Property;
- import org.apache.poi.poifs.property.RootProperty;
- import org.apache.poi.poifs.storage.HeaderBlock;
- import org.apache.poi.util.IOUtils;
- import org.junit.Ignore;
- import org.junit.Test;
-
- /**
- * Tests for the new NIO POIFSFileSystem implementation
- */
- public final class TestNPOIFSFileSystem {
- private static final POIDataSamples _inst = POIDataSamples.getPOIFSInstance();
-
- /**
- * 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};
- }
-
- 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 void assertContentsMatches(byte[] expected, DocumentEntry doc) throws IOException {
- NDocumentInputStream inp = new NDocumentInputStream(doc);
- byte[] contents = new byte[doc.getSize()];
- assertEquals(doc.getSize(), inp.read(contents));
- inp.close();
-
- if (expected != null)
- assertThat(expected, equalTo(contents));
- }
-
- 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;
- }
-
- protected static NPOIFSFileSystem writeOutAndReadBack(NPOIFSFileSystem original) throws IOException {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- original.writeFilesystem(baos);
- original.close();
- return new NPOIFSFileSystem(new ByteArrayInputStream(baos.toByteArray()));
- }
-
- @Test
- public void basicOpen() throws Exception {
- 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());
- }
- fsA.close();
- fsB.close();
-
- // 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());
- }
- fsA.close();
- fsB.close();
- }
-
- @Test
- public void propertiesAndFatOnRead() throws Exception {
- 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}) {
- // 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));
-
-
- // Check the properties
- 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
- 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));
-
- fs.close();
- }
-
- // 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
- // 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));
-
-
- // Check the properties
- 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
- 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));
-
- fs.close();
- }
- }
-
- /**
- * Check that for a given block, we can correctly figure
- * out what the next one is
- */
- @Test
- public void nextBlock() throws Exception {
- 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));
- }
-
- fs.close();
- }
-
- // 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));
-
- fs.close();
- }
- }
-
- /**
- * Check we get the right data back for each block
- */
- @Test
- public void getBlock() throws Exception {
- 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());
-
- fs.close();
- }
-
- // 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());
-
- fs.close();
- }
- }
-
- /**
- * Ask for free blocks where there are some already
- * to be had from the FAT
- */
- @Test
- public void getFreeBlockWithSpare() throws Exception {
- 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());
-
- // All done
- fs.close();
- }
-
- /**
- * Ask for free blocks where no free ones exist, and so the
- * file needs to be extended and another BAT/XBAT added
- */
- @Test
- public void getFreeBlockWithNoneSpare() throws Exception {
- NPOIFSFileSystem fs = new NPOIFSFileSystem(_inst.openResourceAsStream("BlockSize512.zvi"));
- int free;
-
- // We have one BAT at block 99
- assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(99));
- assertBATCount(fs, 1, 0);
-
- // 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) {}
- assertBATCount(fs, 1, 0);
-
-
- // 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));
-
- // We now have 2 BATs, but no XBATs
- assertBATCount(fs, 2, 0);
-
-
- // Fill up to hold 109 BAT blocks
- 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) {}
-
- // 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());
-
-
- // Ask for another, will get our first XBAT
- 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) {}
- assertBATCount(fs, 110, 1);
-
- header = writeOutAndReadHeader(fs);
- assertEquals(110, header.getBATCount());
- assertEquals(1, header.getXBATCount());
-
-
- // 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);
- }
- assertBATCount(fs, i+1, 1);
- }
-
- // 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) {}
- assertBATCount(fs, 236, 1);
-
-
- // Ask for another, will get our 2nd XBAT
- 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) {}
-
-
- // Check the counts now
- assertBATCount(fs, 237, 2);
-
- // Check the header
- header = writeOutAndReadHeader(fs);
-
-
- // Now, write it out, and read it back in again fully
- fs = writeOutAndReadBack(fs);
-
- // Check that it is seen correctly
- assertBATCount(fs, 237, 2);
-
- 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) {}
-
-
- // All done
- fs.close();
- }
-
- /**
- * Test that we can correctly get the list of directory
- * entries, and the details on the files in them
- */
- @Test
- public void listEntries() throws Exception {
- for(NPOIFSFileSystem fs : get512and4kFileAndInput()) {
- 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());
-
- fs.close();
- }
- }
-
- /**
- * Tests that we can get the correct contents for
- * a document in the filesystem
- */
- @Test
- public void getDocumentEntry() throws Exception {
- for(NPOIFSFileSystem fs : get512and4kFileAndInput()) {
- DirectoryEntry root = fs.getRoot();
- Entry si = root.getEntry("\u0005SummaryInformation");
-
- assertEquals(true, si.isDocumentEntry());
- DocumentNode doc = (DocumentNode)si;
-
- // Check we can read it
- assertContentsMatches(null, doc);
-
- // Now try to build the property set
- DocumentInputStream inp = new NDocumentInputStream(doc);
- PropertySet ps = PropertySetFactory.create(inp);
- SummaryInformation inf = (SummaryInformation)ps;
-
- // Check some bits in it
- assertEquals(null, inf.getApplicationName());
- assertEquals(null, inf.getAuthor());
- assertEquals(null, inf.getSubject());
- assertEquals(131333, inf.getOSVersion());
-
- // Finish with this one
- inp.close();
-
-
- // Try the other summary information
- si = root.getEntry("\u0005DocumentSummaryInformation");
- assertEquals(true, si.isDocumentEntry());
- doc = (DocumentNode)si;
- assertContentsMatches(null, doc);
-
- inp = new NDocumentInputStream(doc);
- ps = PropertySetFactory.create(inp);
- DocumentSummaryInformation dinf = (DocumentSummaryInformation)ps;
- assertEquals(131333, dinf.getOSVersion());
-
- fs.close();
- }
- }
-
- /**
- * Read a file, write it and read it again.
- * Then, alter+add some streams, write and read
- */
- @Test
- public void readWriteRead() throws Exception {
- SummaryInformation sinf = null;
- DocumentSummaryInformation dinf = null;
- DirectoryEntry root = null, testDir = null;
-
- for(NPOIFSFileSystem fs : get512and4kFileAndInput()) {
- // Check we can find the entries we expect
- root = fs.getRoot();
- assertEquals(5, root.getEntryCount());
- assertThat(root.getEntryNames(), hasItem("Thumbnail"));
- assertThat(root.getEntryNames(), hasItem("Image"));
- assertThat(root.getEntryNames(), hasItem("Tags"));
- assertThat(root.getEntryNames(), hasItem("\u0005DocumentSummaryInformation"));
- assertThat(root.getEntryNames(), hasItem("\u0005SummaryInformation"));
-
-
- // Write out, re-load
- fs = writeOutAndReadBack(fs);
-
- // Check they're still there
- root = fs.getRoot();
- assertEquals(5, root.getEntryCount());
- assertThat(root.getEntryNames(), hasItem("Thumbnail"));
- assertThat(root.getEntryNames(), hasItem("Image"));
- assertThat(root.getEntryNames(), hasItem("Tags"));
- assertThat(root.getEntryNames(), hasItem("\u0005DocumentSummaryInformation"));
- assertThat(root.getEntryNames(), hasItem("\u0005SummaryInformation"));
-
-
- // Check the contents of them - parse the summary block and check
- sinf = (SummaryInformation)PropertySetFactory.create(new NDocumentInputStream(
- (DocumentEntry)root.getEntry(SummaryInformation.DEFAULT_STREAM_NAME)));
- assertEquals(131333, sinf.getOSVersion());
-
- dinf = (DocumentSummaryInformation)PropertySetFactory.create(new NDocumentInputStream(
- (DocumentEntry)root.getEntry(DocumentSummaryInformation.DEFAULT_STREAM_NAME)));
- assertEquals(131333, dinf.getOSVersion());
-
-
- // Add a test mini stream
- testDir = root.createDirectory("Testing 123");
- testDir.createDirectory("Testing 456");
- testDir.createDirectory("Testing 789");
- byte[] mini = new byte[] { 42, 0, 1, 2, 3, 4, 42 };
- testDir.createDocument("Mini", new ByteArrayInputStream(mini));
-
-
- // Write out, re-load
- fs = writeOutAndReadBack(fs);
-
- root = fs.getRoot();
- testDir = (DirectoryEntry)root.getEntry("Testing 123");
- assertEquals(6, root.getEntryCount());
- assertThat(root.getEntryNames(), hasItem("Thumbnail"));
- assertThat(root.getEntryNames(), hasItem("Image"));
- assertThat(root.getEntryNames(), hasItem("Tags"));
- assertThat(root.getEntryNames(), hasItem("Testing 123"));
- assertThat(root.getEntryNames(), hasItem("\u0005DocumentSummaryInformation"));
- assertThat(root.getEntryNames(), hasItem("\u0005SummaryInformation"));
-
-
- // Check old and new are there
- sinf = (SummaryInformation)PropertySetFactory.create(new NDocumentInputStream(
- (DocumentEntry)root.getEntry(SummaryInformation.DEFAULT_STREAM_NAME)));
- assertEquals(131333, sinf.getOSVersion());
-
- dinf = (DocumentSummaryInformation)PropertySetFactory.create(new NDocumentInputStream(
- (DocumentEntry)root.getEntry(DocumentSummaryInformation.DEFAULT_STREAM_NAME)));
- assertEquals(131333, dinf.getOSVersion());
-
- assertContentsMatches(mini, (DocumentEntry)testDir.getEntry("Mini"));
-
-
- // Write out and read once more, just to be sure
- fs = writeOutAndReadBack(fs);
-
- root = fs.getRoot();
- testDir = (DirectoryEntry)root.getEntry("Testing 123");
- assertEquals(6, root.getEntryCount());
- assertThat(root.getEntryNames(), hasItem("Thumbnail"));
- assertThat(root.getEntryNames(), hasItem("Image"));
- assertThat(root.getEntryNames(), hasItem("Tags"));
- assertThat(root.getEntryNames(), hasItem("Testing 123"));
- assertThat(root.getEntryNames(), hasItem("\u0005DocumentSummaryInformation"));
- assertThat(root.getEntryNames(), hasItem("\u0005SummaryInformation"));
-
- sinf = (SummaryInformation)PropertySetFactory.create(new NDocumentInputStream(
- (DocumentEntry)root.getEntry(SummaryInformation.DEFAULT_STREAM_NAME)));
- assertEquals(131333, sinf.getOSVersion());
-
- dinf = (DocumentSummaryInformation)PropertySetFactory.create(new NDocumentInputStream(
- (DocumentEntry)root.getEntry(DocumentSummaryInformation.DEFAULT_STREAM_NAME)));
- assertEquals(131333, dinf.getOSVersion());
-
- assertContentsMatches(mini, (DocumentEntry)testDir.getEntry("Mini"));
-
-
- // Add a full stream, delete a full stream
- byte[] main4096 = new byte[4096];
- main4096[0] = -10;
- main4096[4095] = -11;
- testDir.createDocument("Normal4096", new ByteArrayInputStream(main4096));
-
- root.getEntry("Tags").delete();
-
-
- // Write out, re-load
- fs = writeOutAndReadBack(fs);
-
- // Check it's all there
- root = fs.getRoot();
- testDir = (DirectoryEntry)root.getEntry("Testing 123");
- assertEquals(5, root.getEntryCount());
- assertThat(root.getEntryNames(), hasItem("Thumbnail"));
- assertThat(root.getEntryNames(), hasItem("Image"));
- assertThat(root.getEntryNames(), hasItem("Testing 123"));
- assertThat(root.getEntryNames(), hasItem("\u0005DocumentSummaryInformation"));
- assertThat(root.getEntryNames(), hasItem("\u0005SummaryInformation"));
-
-
- // Check old and new are there
- sinf = (SummaryInformation)PropertySetFactory.create(new NDocumentInputStream(
- (DocumentEntry)root.getEntry(SummaryInformation.DEFAULT_STREAM_NAME)));
- assertEquals(131333, sinf.getOSVersion());
-
- dinf = (DocumentSummaryInformation)PropertySetFactory.create(new NDocumentInputStream(
- (DocumentEntry)root.getEntry(DocumentSummaryInformation.DEFAULT_STREAM_NAME)));
- assertEquals(131333, dinf.getOSVersion());
-
- assertContentsMatches(mini, (DocumentEntry)testDir.getEntry("Mini"));
- assertContentsMatches(main4096, (DocumentEntry)testDir.getEntry("Normal4096"));
-
-
- // Delete a directory, and add one more
- testDir.getEntry("Testing 456").delete();
- testDir.createDirectory("Testing ABC");
-
-
- // Save
- fs = writeOutAndReadBack(fs);
-
- // Check
- root = fs.getRoot();
- testDir = (DirectoryEntry)root.getEntry("Testing 123");
-
- assertEquals(5, root.getEntryCount());
- assertThat(root.getEntryNames(), hasItem("Thumbnail"));
- assertThat(root.getEntryNames(), hasItem("Image"));
- assertThat(root.getEntryNames(), hasItem("Testing 123"));
- assertThat(root.getEntryNames(), hasItem("\u0005DocumentSummaryInformation"));
- assertThat(root.getEntryNames(), hasItem("\u0005SummaryInformation"));
-
- assertEquals(4, testDir.getEntryCount());
- assertThat(testDir.getEntryNames(), hasItem("Mini"));
- assertThat(testDir.getEntryNames(), hasItem("Normal4096"));
- assertThat(testDir.getEntryNames(), hasItem("Testing 789"));
- assertThat(testDir.getEntryNames(), hasItem("Testing ABC"));
-
-
- // Add another mini stream
- byte[] mini2 = new byte[] { -42, 0, -1, -2, -3, -4, -42 };
- testDir.createDocument("Mini2", new ByteArrayInputStream(mini2));
-
- // Save, load, check
- fs = writeOutAndReadBack(fs);
-
- root = fs.getRoot();
- testDir = (DirectoryEntry)root.getEntry("Testing 123");
-
- assertEquals(5, root.getEntryCount());
- assertThat(root.getEntryNames(), hasItem("Thumbnail"));
- assertThat(root.getEntryNames(), hasItem("Image"));
- assertThat(root.getEntryNames(), hasItem("Testing 123"));
- assertThat(root.getEntryNames(), hasItem("\u0005DocumentSummaryInformation"));
- assertThat(root.getEntryNames(), hasItem("\u0005SummaryInformation"));
-
- assertEquals(5, testDir.getEntryCount());
- assertThat(testDir.getEntryNames(), hasItem("Mini"));
- assertThat(testDir.getEntryNames(), hasItem("Mini2"));
- assertThat(testDir.getEntryNames(), hasItem("Normal4096"));
- assertThat(testDir.getEntryNames(), hasItem("Testing 789"));
- assertThat(testDir.getEntryNames(), hasItem("Testing ABC"));
-
- assertContentsMatches(mini, (DocumentEntry)testDir.getEntry("Mini"));
- assertContentsMatches(mini2, (DocumentEntry)testDir.getEntry("Mini2"));
- assertContentsMatches(main4096, (DocumentEntry)testDir.getEntry("Normal4096"));
-
-
- // Delete a mini stream, add one more
- testDir.getEntry("Mini").delete();
-
- byte[] mini3 = new byte[] { 42, 0, 42, 0, 42, 0, 42 };
- testDir.createDocument("Mini3", new ByteArrayInputStream(mini3));
-
-
- // Save, load, check
- fs = writeOutAndReadBack(fs);
-
- root = fs.getRoot();
- testDir = (DirectoryEntry)root.getEntry("Testing 123");
-
- assertEquals(5, root.getEntryCount());
- assertThat(root.getEntryNames(), hasItem("Thumbnail"));
- assertThat(root.getEntryNames(), hasItem("Image"));
- assertThat(root.getEntryNames(), hasItem("Testing 123"));
- assertThat(root.getEntryNames(), hasItem("\u0005DocumentSummaryInformation"));
- assertThat(root.getEntryNames(), hasItem("\u0005SummaryInformation"));
-
- assertEquals(5, testDir.getEntryCount());
- assertThat(testDir.getEntryNames(), hasItem("Mini2"));
- assertThat(testDir.getEntryNames(), hasItem("Mini3"));
- assertThat(testDir.getEntryNames(), hasItem("Normal4096"));
- assertThat(testDir.getEntryNames(), hasItem("Testing 789"));
- assertThat(testDir.getEntryNames(), hasItem("Testing ABC"));
-
- assertContentsMatches(mini2, (DocumentEntry)testDir.getEntry("Mini2"));
- assertContentsMatches(mini3, (DocumentEntry)testDir.getEntry("Mini3"));
- assertContentsMatches(main4096, (DocumentEntry)testDir.getEntry("Normal4096"));
-
-
- // Change some existing streams
- NPOIFSDocument mini2Doc = new NPOIFSDocument((DocumentNode)testDir.getEntry("Mini2"));
- mini2Doc.replaceContents(new ByteArrayInputStream(mini));
-
- byte[] main4106 = new byte[4106];
- main4106[0] = 41;
- main4106[4105] = 42;
- NPOIFSDocument mainDoc = new NPOIFSDocument((DocumentNode)testDir.getEntry("Normal4096"));
- mainDoc.replaceContents(new ByteArrayInputStream(main4106));
-
-
- // Re-check
- fs = writeOutAndReadBack(fs);
-
- root = fs.getRoot();
- testDir = (DirectoryEntry)root.getEntry("Testing 123");
-
- assertEquals(5, root.getEntryCount());
- assertThat(root.getEntryNames(), hasItem("Thumbnail"));
- assertThat(root.getEntryNames(), hasItem("Image"));
- assertThat(root.getEntryNames(), hasItem("Testing 123"));
- assertThat(root.getEntryNames(), hasItem("\u0005DocumentSummaryInformation"));
- assertThat(root.getEntryNames(), hasItem("\u0005SummaryInformation"));
-
- assertEquals(5, testDir.getEntryCount());
- assertThat(testDir.getEntryNames(), hasItem("Mini2"));
- assertThat(testDir.getEntryNames(), hasItem("Mini3"));
- assertThat(testDir.getEntryNames(), hasItem("Normal4096"));
- assertThat(testDir.getEntryNames(), hasItem("Testing 789"));
- assertThat(testDir.getEntryNames(), hasItem("Testing ABC"));
-
- assertContentsMatches(mini, (DocumentEntry)testDir.getEntry("Mini2"));
- assertContentsMatches(mini3, (DocumentEntry)testDir.getEntry("Mini3"));
- assertContentsMatches(main4106, (DocumentEntry)testDir.getEntry("Normal4096"));
-
-
- // All done
- fs.close();
- }
- }
-
- /**
- * Create a new file, write it and read it again
- * Then, add some streams, write and read
- */
- @Test
- @SuppressWarnings("resource")
- public void createWriteRead() throws Exception {
- NPOIFSFileSystem fs = new NPOIFSFileSystem();
- DocumentEntry miniDoc;
- DocumentEntry normDoc;
-
- // 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());
-
- // Check that no properties table has been written yet
- assertEquals(POIFSConstants.END_OF_CHAIN, fs._get_property_table().getStartBlock());
-
- // Write and read it
- fs = writeOutAndReadBack(fs);
-
- // Property table entries have been added to the blocks
- assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(0));
- assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(1));
- assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(2));
- assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(3));
- assertEquals(POIFSConstants.END_OF_CHAIN, fs.getRoot().getProperty().getStartBlock());
- assertEquals(2, fs._get_property_table().getStartBlock());
-
-
- // 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));
- 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));
-
- 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));
- 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));
-
- assertEquals(POIFSConstants.END_OF_CHAIN, fs.getRoot().getProperty().getStartBlock());
-
-
- // Now Add a mini stream
- byte[] mini = new byte[] { 42, 0, 1, 2, 3, 4, 42 };
- 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));
- 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));
-
- // Check the mini stream location was set
- // (22 is mini fat, 23 is first mini stream block)
- assertEquals(23, fs.getRoot().getProperty().getStartBlock());
-
-
- // Write and read back
- fs = writeOutAndReadBack(fs);
- HeaderBlock header = writeOutAndReadHeader(fs);
-
- // Check the header has the right points in it
- assertEquals(1, header.getBATCount());
- assertEquals(0, header.getBATArray()[0]);
- assertEquals(2, header.getPropertyStart());
- assertEquals(1, header.getSBATCount());
- assertEquals(22, header.getSBATStart());
- assertEquals(23, fs._get_property_table().getRoot().getStartBlock());
-
- // Block use should be almost the same, except the properties
- // stream will have grown out to cover 2 blocks
- // Check the block use is all unchanged
- assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(0));
- assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(1));
- assertEquals(24, fs.getNextBlock(2)); // Properties now extends over 2 blocks
-
- 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)); // End of normal4096
-
- 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)); // End of normal5124
-
- assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(22)); // Mini Stream FAT
- assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(23)); // Mini Stream data
- assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(24)); // Properties #2
- assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(25));
-
-
- // Check some data
- assertEquals(1, fs.getRoot().getEntryCount());
- testDir = (DirectoryEntry)fs.getRoot().getEntry("Test Directory");
- assertEquals(3, testDir.getEntryCount());
-
- miniDoc = (DocumentEntry)testDir.getEntry("Mini");
- assertContentsMatches(mini, miniDoc);
-
- normDoc = (DocumentEntry)testDir.getEntry("Normal4096");
- assertContentsMatches(main4096, normDoc);
-
- normDoc = (DocumentEntry)testDir.getEntry("Normal5124");
- assertContentsMatches(main5124, normDoc);
-
-
- // Delete a couple of streams
- miniDoc.delete();
- normDoc.delete();
-
-
- // Check - will have un-used sectors now
- fs = writeOutAndReadBack(fs);
-
- assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(0));
- assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(1));
- assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(2)); // Props back in 1 block
-
- 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)); // End of normal4096
-
- assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(11));
- assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(12));
- assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(13));
- assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(14));
- assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(15));
- assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(16));
- assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(17));
- assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(18));
- assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(19));
- assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(20));
- assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(21));
-
- assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(22)); // Mini Stream FAT
- assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(23)); // Mini Stream data
- assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(24)); // Properties gone
- assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(25));
-
- // All done
- fs.close();
- }
-
- @Test
- public void addBeforeWrite() throws Exception {
- NPOIFSFileSystem fs = new NPOIFSFileSystem();
- DocumentEntry miniDoc;
- DocumentEntry normDoc;
- HeaderBlock hdr;
-
- // 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));
-
- 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
- DirectoryEntry parentDir = fs.createDirectory("Parent Directory");
- DirectoryEntry testDir = parentDir.createDirectory("Test Directory");
-
-
- // Add to the mini stream
- byte[] mini = new byte[] { 42, 0, 1, 2, 3, 4, 42 };
- testDir.createDocument("Mini", new ByteArrayInputStream(mini));
-
- // Add to the main stream
- 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));
- 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
- 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));
- assertEquals(POIFSConstants.SMALLER_BIG_BLOCK_SIZE*13, fs.size());
-
-
- // Check that we can read the right data pre-write
- miniDoc = (DocumentEntry)testDir.getEntry("Mini");
- assertContentsMatches(mini, miniDoc);
-
- normDoc = (DocumentEntry)testDir.getEntry("Normal4096");
- assertContentsMatches(main4096, normDoc);
-
-
- // Write, read, check
- hdr = writeOutAndReadHeader(fs);
- fs = writeOutAndReadBack(fs);
-
- // 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
- assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(0));
- assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(1));
- assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(2));
- 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));
- 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());
-
-
- // 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());
-
- miniDoc = (DocumentEntry)testDir.getEntry("Mini");
- assertContentsMatches(mini, miniDoc);
-
- normDoc = (DocumentEntry)testDir.getEntry("Normal4096");
- assertContentsMatches(main4096, normDoc);
-
-
- // Add one more stream to each, then save and re-load
- byte[] mini2 = new byte[] { -42, 0, -1, -2, -3, -4, -42 };
- testDir.createDocument("Mini2", new ByteArrayInputStream(mini2));
-
- // Add to the main stream
- byte[] main4106 = new byte[4106];
- main4106[0] = 41;
- main4106[4105] = 42;
- testDir.createDocument("Normal4106", new ByteArrayInputStream(main4106));
-
-
- // Recheck the data in all 4 streams
- fs = writeOutAndReadBack(fs);
-
- fsRoot = fs.getRoot();
- assertEquals(1, fsRoot.getEntryCount());
-
- parentDir = (DirectoryEntry)fsRoot.getEntry("Parent Directory");
- assertEquals(1, parentDir.getEntryCount());
-
- testDir = (DirectoryEntry)parentDir.getEntry("Test Directory");
- assertEquals(4, testDir.getEntryCount());
-
- miniDoc = (DocumentEntry)testDir.getEntry("Mini");
- assertContentsMatches(mini, miniDoc);
-
- miniDoc = (DocumentEntry)testDir.getEntry("Mini2");
- assertContentsMatches(mini2, miniDoc);
-
- normDoc = (DocumentEntry)testDir.getEntry("Normal4106");
- assertContentsMatches(main4106, normDoc);
- }
-
- @Test
- public void readZeroLengthEntries() throws Exception {
- NPOIFSFileSystem fs = new NPOIFSFileSystem(_inst.getFile("only-zero-byte-streams.ole2"));
- DirectoryNode testDir = fs.getRoot();
- assertEquals(3, testDir.getEntryCount());
- DocumentEntry entry;
-
- entry = (DocumentEntry)testDir.getEntry("test-zero-1");
- assertNotNull(entry);
- assertEquals(0, entry.getSize());
-
- entry = (DocumentEntry)testDir.getEntry("test-zero-2");
- assertNotNull(entry);
- assertEquals(0, entry.getSize());
-
- entry = (DocumentEntry)testDir.getEntry("test-zero-3");
- assertNotNull(entry);
- assertEquals(0, entry.getSize());
-
- // Check properties, all have zero length, no blocks
- NPropertyTable props = fs._get_property_table();
- assertEquals(POIFSConstants.END_OF_CHAIN, props.getRoot().getStartBlock());
- for (Property prop : props.getRoot()) {
- assertEquals("test-zero-", prop.getName().substring(0, 10));
- assertEquals(POIFSConstants.END_OF_CHAIN, prop.getStartBlock());
- }
- }
-
- // TODO Should these have a mini-sbat entry or not?
- // TODO Is the reading of zero-length properties exactly correct?
- @Test
- public void writeZeroLengthEntries() throws Exception {
- NPOIFSFileSystem fs = new NPOIFSFileSystem();
- DirectoryNode testDir = fs.getRoot();
- DocumentEntry miniDoc;
- DocumentEntry normDoc;
- DocumentEntry emptyDoc;
-
- // Add mini and normal sized entries to start
- byte[] mini2 = new byte[] { -42, 0, -1, -2, -3, -4, -42 };
- testDir.createDocument("Mini2", new ByteArrayInputStream(mini2));
-
- // Add to the main stream
- byte[] main4106 = new byte[4106];
- main4106[0] = 41;
- main4106[4105] = 42;
- testDir.createDocument("Normal4106", new ByteArrayInputStream(main4106));
-
- // Now add some empty ones
- byte[] empty = new byte[0];
- testDir.createDocument("empty-1", new ByteArrayInputStream(empty));
- testDir.createDocument("empty-2", new ByteArrayInputStream(empty));
- testDir.createDocument("empty-3", new ByteArrayInputStream(empty));
-
- // Check
- miniDoc = (DocumentEntry)testDir.getEntry("Mini2");
- assertContentsMatches(mini2, miniDoc);
-
- normDoc = (DocumentEntry)testDir.getEntry("Normal4106");
- assertContentsMatches(main4106, normDoc);
-
- emptyDoc = (DocumentEntry)testDir.getEntry("empty-1");
- assertContentsMatches(empty, emptyDoc);
-
- emptyDoc = (DocumentEntry)testDir.getEntry("empty-2");
- assertContentsMatches(empty, emptyDoc);
-
- emptyDoc = (DocumentEntry)testDir.getEntry("empty-3");
- assertContentsMatches(empty, emptyDoc);
-
- // Save and re-check
- fs = writeOutAndReadBack(fs);
- testDir = fs.getRoot();
-
- miniDoc = (DocumentEntry)testDir.getEntry("Mini2");
- assertContentsMatches(mini2, miniDoc);
-
- normDoc = (DocumentEntry)testDir.getEntry("Normal4106");
- assertContentsMatches(main4106, normDoc);
-
- emptyDoc = (DocumentEntry)testDir.getEntry("empty-1");
- assertContentsMatches(empty, emptyDoc);
-
- emptyDoc = (DocumentEntry)testDir.getEntry("empty-2");
- assertContentsMatches(empty, emptyDoc);
-
- emptyDoc = (DocumentEntry)testDir.getEntry("empty-3");
- assertContentsMatches(empty, emptyDoc);
- }
-
- /**
- * 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
- */
- @Test
- public void NPOIFSReadCopyWritePOIFSRead() throws Exception {
- File testFile = POIDataSamples.getSpreadSheetInstance().getFile("Simple.xls");
- NPOIFSFileSystem src = new NPOIFSFileSystem(testFile);
- byte wbDataExp[] = IOUtils.toByteArray(src.createDocumentInputStream("Workbook"));
-
- NPOIFSFileSystem nfs = new NPOIFSFileSystem();
- EntryUtils.copyNodes(src.getRoot(), nfs.getRoot());
- 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));
- }
- }
|