/** * Read and process the PropertiesTable and the * FAT / XFAT blocks, so that we're Ready to * work with the file */ private void ReadCoreContents() { // Grab the block size bigBlockSize = _header.BigBlockSize; // Each block should only ever be used by one of the // FAT, XFAT or Property Table. Ensure it does ChainLoopDetector loopDetector = GetChainLoopDetector(); // Read the FAT blocks foreach (int fatAt in _header.BATArray) { ReadBAT(fatAt, loopDetector); } // Now read the XFAT blocks, and the FATs within them BATBlock xfat; int nextAt = _header.XBATIndex; for (int i = 0; i < _header.XBATCount; i++) { loopDetector.Claim(nextAt); ByteBuffer fatData = GetBlockAt(nextAt); xfat = BATBlock.CreateBATBlock(bigBlockSize, fatData); xfat.OurBlockIndex = nextAt; nextAt = xfat.GetValueAt(bigBlockSize.GetXBATEntriesPerBlock()); _xbat_blocks.Add(xfat); for (int j = 0; j < bigBlockSize.GetXBATEntriesPerBlock(); j++) { int fatAt = xfat.GetValueAt(j); if (fatAt == POIFSConstants.UNUSED_BLOCK) { break; } ReadBAT(fatAt, loopDetector); } } // We're now able to load steams // Use this to read in the properties _property_table = new NPropertyTable(_header, this); // Finally read the Small Stream FAT (SBAT) blocks BATBlock sfat; List <BATBlock> sbats = new List <BATBlock>(); _mini_store = new NPOIFSMiniStore(this, _property_table.Root, sbats, _header); nextAt = _header.SBATStart; for (int i = 0; i < _header.SBATCount; i++) { loopDetector.Claim(nextAt); ByteBuffer fatData = GetBlockAt(nextAt); sfat = BATBlock.CreateBATBlock(bigBlockSize, fatData); sfat.OurBlockIndex = nextAt; sbats.Add(sfat); nextAt = GetNextBlock(nextAt); } }
private NPOIFSFileSystem(bool newFS) { _header = new HeaderBlock(bigBlockSize); _property_table = new NPropertyTable(_header); _mini_store = new NPOIFSMiniStore(this, _property_table.Root, new List <BATBlock>(), _header); _xbat_blocks = new List <BATBlock>(); _bat_blocks = new List <BATBlock>(); _root = null; if (newFS) { // Data needs to Initially hold just the header block, // a single bat block, and an empty properties section _data = new ByteArrayBackedDataSource(new byte[bigBlockSize.GetBigBlockSize() * 3]); } }
public void TestPropertiesAndFatOnRead() { NPOIFSFileSystem fsA, fsB; fsA = new NPOIFSFileSystem(_inst.GetFile("BlockSize512.zvi")); fsB = new NPOIFSFileSystem(_inst.OpenResourceAsStream("BlockSize512.zvi")); foreach (NPOIFSFileSystem fs in new NPOIFSFileSystem[] { fsA, fsB }) { fs.GetBATBlockAndIndex(0); fs.GetBATBlockAndIndex(1); try { fs.GetBATBlockAndIndex(140); Assert.Fail("Should only be one BAT, but a 2nd was found"); } //catch (IndexOutOfRangeException) catch (ArgumentOutOfRangeException) { } Assert.AreEqual(98, fs.GetNextBlock(97)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(98)); NPropertyTable props = fs.PropertyTable; Assert.AreEqual(90, props.StartBlock); Assert.AreEqual(7, props.CountBlocks); RootProperty root = props.Root; Assert.AreEqual("Root Entry", root.Name); Assert.AreEqual(11564, root.Size); Assert.AreEqual(0, root.StartBlock); NStorage.Properties.Property prop; IEnumerator <NStorage.Properties.Property> pi = root.Children; //prop = pi.Current; pi.MoveNext(); prop = pi.Current; Assert.AreEqual("Thumbnail", prop.Name); pi.MoveNext(); prop = pi.Current; Assert.AreEqual("\x0005DocumentSummaryInformation", prop.Name); pi.MoveNext(); prop = pi.Current; Assert.AreEqual("\x0005SummaryInformation", prop.Name); pi.MoveNext(); prop = pi.Current; Assert.AreEqual("Image", prop.Name); pi.MoveNext(); prop = pi.Current; Assert.AreEqual(false, pi.MoveNext()); NPOIFSMiniStore miniStore = fs.GetMiniStore(); miniStore.GetBATBlockAndIndex(0); miniStore.GetBATBlockAndIndex(128); try { miniStore.GetBATBlockAndIndex(256); Assert.Fail("Should only be two SBATs, but a 3rd was found"); } //catch (IndexOutOfRangeException) catch (ArgumentOutOfRangeException) { } for (int i = 0; i < 50; i++) { Assert.AreEqual(i + 1, miniStore.GetNextBlock(i)); } Assert.AreEqual(POIFSConstants.END_OF_CHAIN, miniStore.GetNextBlock(50)); fs.Close(); } fsA = new NPOIFSFileSystem(_inst.GetFile("BlockSize4096.zvi")); fsB = new NPOIFSFileSystem(_inst.OpenResourceAsStream("BlockSize4096.zvi")); foreach (NPOIFSFileSystem fs in new NPOIFSFileSystem[] { fsA, fsB }) { fs.GetBATBlockAndIndex(0); fs.GetBATBlockAndIndex(1); try { fs.GetBATBlockAndIndex(1040); Assert.Fail("Should only be one BAT, but a 2nd was found"); } //catch (IndexOutOfRangeException) catch (ArgumentOutOfRangeException) { } Assert.AreEqual(1, fs.GetNextBlock(0)); Assert.AreEqual(2, fs.GetNextBlock(1)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(2)); NPropertyTable props = fs.PropertyTable; Assert.AreEqual(12, props.StartBlock); Assert.AreEqual(1, props.CountBlocks); RootProperty root = props.Root; Assert.AreEqual("Root Entry", root.Name); Assert.AreEqual(11564, root.Size); Assert.AreEqual(0, root.StartBlock); NStorage.Properties.Property prop; IEnumerator <NStorage.Properties.Property> pi = root.Children; pi.MoveNext(); prop = pi.Current; Assert.AreEqual("Thumbnail", prop.Name); pi.MoveNext(); prop = pi.Current; Assert.AreEqual("\x0005DocumentSummaryInformation", prop.Name); pi.MoveNext(); prop = pi.Current; Assert.AreEqual("\x0005SummaryInformation", prop.Name); pi.MoveNext(); prop = pi.Current; Assert.AreEqual("Image", prop.Name); pi.MoveNext(); prop = pi.Current; Assert.AreEqual("Tags", prop.Name); Assert.AreEqual(false, pi.MoveNext()); NPOIFSMiniStore miniStore = fs.GetMiniStore(); miniStore.GetBATBlockAndIndex(0); miniStore.GetBATBlockAndIndex(128); miniStore.GetBATBlockAndIndex(1023); try { miniStore.GetBATBlockAndIndex(1024); Assert.Fail("Should only be one SBAT, but a 2nd was found"); } //catch(IndexOutOfRangeException) catch (ArgumentOutOfRangeException) { } for (int i = 0; i < 50; i++) { Assert.AreEqual(i + 1, miniStore.GetNextBlock(i)); } Assert.AreEqual(POIFSConstants.END_OF_CHAIN, miniStore.GetNextBlock(50)); fs.Close(); } }