/** * Load the block, extending the underlying stream if needed */ public override ByteBuffer CreateBlockIfNeeded(int offset) { bool firstInStore = false; // If we are the first block to be allocated, initialise the stream if (_mini_stream.GetStartBlock() == POIFSConstants.END_OF_CHAIN) { firstInStore = true; } // Try to Get it without extending the stream if (!firstInStore) { try { return(GetBlockAt(offset)); }catch (IndexOutOfRangeException) {} } // Need to extend the stream // TODO Replace this with proper append support // For now, do the extending by hand... // Ask for another block int newBigBlock = _filesystem.GetFreeBlock(); _filesystem.CreateBlockIfNeeded(newBigBlock); // If we are the first block to be allocated, initialise the stream if (firstInStore) { _filesystem.PropertyTable.Root.StartBlock = (newBigBlock); _mini_stream = new NPOIFSStream(_filesystem, newBigBlock); } else { // Tack it onto the end of our chain ChainLoopDetector loopDetector = _filesystem.GetChainLoopDetector(); int block = _mini_stream.GetStartBlock(); while (true) { loopDetector.Claim(block); int next = _filesystem.GetNextBlock(block); if (next == POIFSConstants.END_OF_CHAIN) { break; } block = next; } _filesystem.SetNextBlock(block, newBigBlock); } _filesystem.SetNextBlock(newBigBlock, POIFSConstants.END_OF_CHAIN); // Now try again, to get the real small block return(CreateBlockIfNeeded(offset)); }
protected static void assertBATCount(NPOIFSFileSystem fs, int expectedBAT, int expectedXBAT) { 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++; } } Assert.AreEqual(expectedBAT, foundBAT, "Wrong number of BATs"); Assert.AreEqual(expectedXBAT, foundXBAT, "Wrong number of XBATs with " + expectedBAT + " BATs"); }
/** * Load the block, extending the underlying stream if needed */ public override ByteBuffer CreateBlockIfNeeded(int offset) { // Try to Get it without extending the stream try { return(GetBlockAt(offset)); } catch (IndexOutOfRangeException) { // Need to extend the stream // TODO Replace this with proper append support // For now, do the extending by hand... // Ask for another block int newBigBlock = _filesystem.GetFreeBlock(); _filesystem.CreateBlockIfNeeded(newBigBlock); // Tack it onto the end of our chain ChainLoopDetector loopDetector = _filesystem.GetChainLoopDetector(); int block = _mini_stream.GetStartBlock(); while (true) { loopDetector.Claim(block); int next = _filesystem.GetNextBlock(block); if (next == POIFSConstants.END_OF_CHAIN) { break; } block = next; } _filesystem.SetNextBlock(block, newBigBlock); _filesystem.SetNextBlock(newBigBlock, POIFSConstants.END_OF_CHAIN); // Now try again to Get it return(CreateBlockIfNeeded(offset)); } }
public void TestWriteStream4096() { NPOIFSFileSystem fs = new NPOIFSFileSystem(_inst.OpenResourceAsStream("BlockSize4096.zvi")); // 0 -> 1 -> 2 -> end Assert.AreEqual(1, fs.GetNextBlock(0)); Assert.AreEqual(2, fs.GetNextBlock(1)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(2)); Assert.AreEqual(4, fs.GetNextBlock(3)); // First free one is at 15 Assert.AreEqual(POIFSConstants.FAT_SECTOR_BLOCK, fs.GetNextBlock(14)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(15)); // Write a 5 block file byte[] data = new byte[4096 * 5]; for (int i = 0; i < data.Length; i++) { data[i] = (byte)(i % 256); } NPOIFSStream stream = new NPOIFSStream(fs, 0); stream.UpdateContents(data); // Check it Assert.AreEqual(1, fs.GetNextBlock(0)); Assert.AreEqual(2, fs.GetNextBlock(1)); Assert.AreEqual(15, fs.GetNextBlock(2)); // Jumps Assert.AreEqual(4, fs.GetNextBlock(3)); // Next stream Assert.AreEqual(POIFSConstants.FAT_SECTOR_BLOCK, fs.GetNextBlock(14)); Assert.AreEqual(16, fs.GetNextBlock(15)); // Continues Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(16)); // Ends Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(17)); // Free // Check the contents too IEnumerator<ByteBuffer> it = stream.GetBlockIterator(); int count = 0; while (it.MoveNext()) { ByteBuffer b = it.Current; data = new byte[512]; // b.get(data); // Array.Copy(b, 0, data, 0, b.Length); b.Read(data); for (int i = 0; i < data.Length; i++) { byte exp = (byte)(i % 256); Assert.AreEqual(exp, data[i]); } count++; } Assert.AreEqual(5, count); }
public void TestWriteNewStreamExtraFATs() { NPOIFSFileSystem fs = new NPOIFSFileSystem(_inst.OpenResourceAsStream("BlockSize512.zvi")); // Allocate almost all the blocks Assert.AreEqual(POIFSConstants.FAT_SECTOR_BLOCK, fs.GetNextBlock(99)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(100)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(127)); for (int i = 100; i < 127; i++) { fs.SetNextBlock(i, POIFSConstants.END_OF_CHAIN); } Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(127)); Assert.AreEqual(true, fs.GetBATBlockAndIndex(0).Block.HasFreeSectors); // Write a 3 block stream byte[] data = new byte[512 * 3]; for (int i = 0; i < data.Length; i++) { data[i] = (byte)(i % 256); } NPOIFSStream stream = new NPOIFSStream(fs); stream.UpdateContents(data); // Check we got another BAT Assert.AreEqual(false, fs.GetBATBlockAndIndex(0).Block.HasFreeSectors); Assert.AreEqual(true, fs.GetBATBlockAndIndex(128).Block.HasFreeSectors); // the BAT will be in the first spot of the new block Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(126)); Assert.AreEqual(129, fs.GetNextBlock(127)); Assert.AreEqual(POIFSConstants.FAT_SECTOR_BLOCK, fs.GetNextBlock(128)); Assert.AreEqual(130, fs.GetNextBlock(129)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(130)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(131)); }
public void TestWriteNewStream() { NPOIFSFileSystem fs = new NPOIFSFileSystem(_inst.OpenResourceAsStream("BlockSize512.zvi")); // 100 is our first free one Assert.AreEqual(POIFSConstants.FAT_SECTOR_BLOCK, fs.GetNextBlock(99)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(100)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(101)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(102)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(103)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(104)); // Add a single block one byte[] data = new byte[512]; for (int i = 0; i < data.Length; i++) { data[i] = (byte)(i % 256); } NPOIFSStream stream = new NPOIFSStream(fs); stream.UpdateContents(data); // Check it was allocated properly Assert.AreEqual(POIFSConstants.FAT_SECTOR_BLOCK, fs.GetNextBlock(99)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(100)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(101)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(102)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(103)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(104)); // And check the contents IEnumerator<ByteBuffer> it = stream.GetBlockIterator(); int count = 0; while (it.MoveNext()) { ByteBuffer b = it.Current; data = new byte[512]; //b.get(data); //Array.Copy(b, 0, data, 0, b.Length); b.Read(data); for (int i = 0; i < data.Length; i++) { byte exp = (byte)(i % 256); Assert.AreEqual(exp, data[i]); } count++; } Assert.AreEqual(1, count); // And a multi block one data = new byte[512 * 3]; for (int i = 0; i < data.Length; i++) { data[i] = (byte)(i % 256); } stream = new NPOIFSStream(fs); stream.UpdateContents(data); // Check it was allocated properly Assert.AreEqual(POIFSConstants.FAT_SECTOR_BLOCK, fs.GetNextBlock(99)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(100)); Assert.AreEqual(102, fs.GetNextBlock(101)); Assert.AreEqual(103, fs.GetNextBlock(102)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(103)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(104)); // And check the contents it = stream.GetBlockIterator(); count = 0; while (it.MoveNext()) { ByteBuffer b = it.Current; data = new byte[512]; //b.get(data); // Array.Copy(b, 0, data, 0, b.Length); b.Read(data); for (int i = 0; i < data.Length; i++) { byte exp = (byte)(i % 256); Assert.AreEqual(exp, data[i]); } count++; } Assert.AreEqual(3, count); // Free it stream.free(); Assert.AreEqual(POIFSConstants.FAT_SECTOR_BLOCK, fs.GetNextBlock(99)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(100)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(101)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(102)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(103)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(104)); }
public void TestReplaceStreamWithMore() { NPOIFSFileSystem fs = new NPOIFSFileSystem(_inst.OpenResourceAsStream("BlockSize512.zvi")); byte[] data = new byte[512 * 3]; for (int i = 0; i < data.Length; i++) { data[i] = (byte)(i % 256); } // 97 -> 98 -> end Assert.AreEqual(98, fs.GetNextBlock(97)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(98)); // 100 is our first free one Assert.AreEqual(POIFSConstants.FAT_SECTOR_BLOCK, fs.GetNextBlock(99)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(100)); // Create a 2 block stream, will become a 3 block one NPOIFSStream stream = new NPOIFSStream(fs, 97); stream.UpdateContents(data); // 97 -> 98 -> 100 -> end Assert.AreEqual(98, fs.GetNextBlock(97)); Assert.AreEqual(100, fs.GetNextBlock(98)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(100)); // Check the reading of blocks IEnumerator<ByteBuffer> it = stream.GetBlockIterator(); int count = 0; while (it.MoveNext()) { ByteBuffer b = it.Current; data = new byte[512]; //b.get(data); //Array.Copy(b, 0, data, 0, b.Length); b.Read(data); for (int i = 0; i < data.Length; i++) { byte exp = (byte)(i % 256); Assert.AreEqual(exp, data[i]); } count++; } Assert.AreEqual(3, count); }
public void TestReplaceStreamWithLess() { NPOIFSFileSystem fs = new NPOIFSFileSystem(_inst.OpenResourceAsStream("BlockSize512.zvi")); byte[] data = new byte[512]; for (int i = 0; i < data.Length; i++) { data[i] = (byte)(i % 256); } // 97 -> 98 -> end Assert.AreEqual(98, fs.GetNextBlock(97)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(98)); // Create a 2 block stream, will become a 1 block one NPOIFSStream stream = new NPOIFSStream(fs, 97); stream.UpdateContents(data); // 97 should now be the end, and 98 free Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(97)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(98)); // Check the reading of blocks IEnumerator<ByteBuffer> it = stream.GetBlockIterator(); Assert.AreEqual(true, it.MoveNext()); ByteBuffer b = it.Current; Assert.AreEqual(false, it.MoveNext()); // Now check the contents data = new byte[512]; // b.get(data); //for (int i = 0; i < b.Length; i++) // data[i] = b[i]; //Array.Copy(b, 0, data, 0, b.Length); b.Read(data); for (int i = 0; i < data.Length; i++) { byte exp = (byte)(i % 256); Assert.AreEqual(exp, data[i]); } }
public void CreateWriteRead() { NPOIFSFileSystem fs = new NPOIFSFileSystem(); DocumentEntry miniDoc; DocumentEntry normDoc; // Initially has a BAT but not SBAT Assert.AreEqual(POIFSConstants.FAT_SECTOR_BLOCK, fs.GetNextBlock(0)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(1)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(2)); // Check that the SBAT is empty Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.Root.Property.StartBlock); // Check that no properties table has been written yet Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.PropertyTable.StartBlock); // Write and read it fs = WriteOutAndReadBack(fs); // Property table entries have been added to the blocks Assert.AreEqual(POIFSConstants.FAT_SECTOR_BLOCK, fs.GetNextBlock(0)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(1)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(2)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(3)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.Root.Property.StartBlock); Assert.AreEqual(2, fs.PropertyTable.StartBlock); // 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] = unchecked((byte)-10); main4096[4095] = unchecked((byte)-11); testDir.CreateDocument("Normal4096", new MemoryStream(main4096)); Assert.AreEqual(POIFSConstants.FAT_SECTOR_BLOCK, fs.GetNextBlock(0)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(1)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(2)); Assert.AreEqual(4, fs.GetNextBlock(3)); Assert.AreEqual(5, fs.GetNextBlock(4)); Assert.AreEqual(6, fs.GetNextBlock(5)); Assert.AreEqual(7, fs.GetNextBlock(6)); Assert.AreEqual(8, fs.GetNextBlock(7)); Assert.AreEqual(9, fs.GetNextBlock(8)); Assert.AreEqual(10, fs.GetNextBlock(9)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(10)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(11)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.Root.Property.StartBlock); // Add a bigger Normal Stream byte[] main5124 = new byte[5124]; main5124[0] = unchecked((byte)-22); main5124[5123] = unchecked((byte)-33); testDir.CreateDocument("Normal5124", new MemoryStream(main5124)); Assert.AreEqual(POIFSConstants.FAT_SECTOR_BLOCK, fs.GetNextBlock(0)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(1)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(2)); Assert.AreEqual(4, fs.GetNextBlock(3)); Assert.AreEqual(5, fs.GetNextBlock(4)); Assert.AreEqual(6, fs.GetNextBlock(5)); Assert.AreEqual(7, fs.GetNextBlock(6)); Assert.AreEqual(8, fs.GetNextBlock(7)); Assert.AreEqual(9, fs.GetNextBlock(8)); Assert.AreEqual(10, fs.GetNextBlock(9)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(10)); Assert.AreEqual(12, fs.GetNextBlock(11)); Assert.AreEqual(13, fs.GetNextBlock(12)); Assert.AreEqual(14, fs.GetNextBlock(13)); Assert.AreEqual(15, fs.GetNextBlock(14)); Assert.AreEqual(16, fs.GetNextBlock(15)); Assert.AreEqual(17, fs.GetNextBlock(16)); Assert.AreEqual(18, fs.GetNextBlock(17)); Assert.AreEqual(19, fs.GetNextBlock(18)); Assert.AreEqual(20, fs.GetNextBlock(19)); Assert.AreEqual(21, fs.GetNextBlock(20)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(21)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(22)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.Root.Property.StartBlock); // Now Add a mini stream byte[] mini = new byte[] { 42, 0, 1, 2, 3, 4, 42 }; testDir.CreateDocument("Mini", new MemoryStream(mini)); // Mini stream will Get one block for fat + one block for data Assert.AreEqual(POIFSConstants.FAT_SECTOR_BLOCK, fs.GetNextBlock(0)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(1)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(2)); Assert.AreEqual(4, fs.GetNextBlock(3)); Assert.AreEqual(5, fs.GetNextBlock(4)); Assert.AreEqual(6, fs.GetNextBlock(5)); Assert.AreEqual(7, fs.GetNextBlock(6)); Assert.AreEqual(8, fs.GetNextBlock(7)); Assert.AreEqual(9, fs.GetNextBlock(8)); Assert.AreEqual(10, fs.GetNextBlock(9)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(10)); Assert.AreEqual(12, fs.GetNextBlock(11)); Assert.AreEqual(13, fs.GetNextBlock(12)); Assert.AreEqual(14, fs.GetNextBlock(13)); Assert.AreEqual(15, fs.GetNextBlock(14)); Assert.AreEqual(16, fs.GetNextBlock(15)); Assert.AreEqual(17, fs.GetNextBlock(16)); Assert.AreEqual(18, fs.GetNextBlock(17)); Assert.AreEqual(19, fs.GetNextBlock(18)); Assert.AreEqual(20, fs.GetNextBlock(19)); Assert.AreEqual(21, fs.GetNextBlock(20)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(21)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(22)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(23)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(24)); // Check the mini stream location was set // (22 is mini fat, 23 is first mini stream block) Assert.AreEqual(23, fs.Root.Property.StartBlock); // Write and read back fs = WriteOutAndReadBack(fs); HeaderBlock header = WriteOutAndReadHeader(fs); // Check the header has the right points in it Assert.AreEqual(1, header.BATCount); Assert.AreEqual(0, header.BATArray[0]); Assert.AreEqual(2, header.PropertyStart); Assert.AreEqual(1, header.SBATCount); Assert.AreEqual(22, header.SBATStart); Assert.AreEqual(23, fs.PropertyTable.Root.StartBlock); // 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 // Check it's all unChanged Assert.AreEqual(POIFSConstants.FAT_SECTOR_BLOCK, fs.GetNextBlock(0)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(1)); Assert.AreEqual(24, fs.GetNextBlock(2)); // Properties now extends over 2 blocks Assert.AreEqual(4, fs.GetNextBlock(3)); Assert.AreEqual(5, fs.GetNextBlock(4)); Assert.AreEqual(6, fs.GetNextBlock(5)); Assert.AreEqual(7, fs.GetNextBlock(6)); Assert.AreEqual(8, fs.GetNextBlock(7)); Assert.AreEqual(9, fs.GetNextBlock(8)); Assert.AreEqual(10, fs.GetNextBlock(9)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(10));// End of normal4096 Assert.AreEqual(12, fs.GetNextBlock(11)); Assert.AreEqual(13, fs.GetNextBlock(12)); Assert.AreEqual(14, fs.GetNextBlock(13)); Assert.AreEqual(15, fs.GetNextBlock(14)); Assert.AreEqual(16, fs.GetNextBlock(15)); Assert.AreEqual(17, fs.GetNextBlock(16)); Assert.AreEqual(18, fs.GetNextBlock(17)); Assert.AreEqual(19, fs.GetNextBlock(18)); Assert.AreEqual(20, fs.GetNextBlock(19)); Assert.AreEqual(21, fs.GetNextBlock(20)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(21)); // End of normal5124 Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(22)); // Mini Stream FAT Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(23)); // Mini Stream data Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(24)); // Properties #2 Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(25)); // Check some data Assert.AreEqual(1, fs.Root.EntryCount); testDir = (DirectoryEntry)fs.Root.GetEntry("Test Directory"); Assert.AreEqual(3, testDir.EntryCount); 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); Assert.AreEqual(POIFSConstants.FAT_SECTOR_BLOCK, fs.GetNextBlock(0)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(1)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(2)); // Props back in 1 block Assert.AreEqual(4, fs.GetNextBlock(3)); Assert.AreEqual(5, fs.GetNextBlock(4)); Assert.AreEqual(6, fs.GetNextBlock(5)); Assert.AreEqual(7, fs.GetNextBlock(6)); Assert.AreEqual(8, fs.GetNextBlock(7)); Assert.AreEqual(9, fs.GetNextBlock(8)); Assert.AreEqual(10, fs.GetNextBlock(9)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(10)); // End of normal4096 Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(11)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(12)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(13)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(14)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(15)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(16)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(17)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(18)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(19)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(20)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(21)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(22)); // Mini Stream FAT Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(23)); // Mini Stream data Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(24)); // Properties gone Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(25)); // All done fs.Close(); }
public void TestGetFreeBlockWithNoneSpare() { NPOIFSFileSystem fs = new NPOIFSFileSystem(_inst.OpenResourceAsStream("BlockSize512.zvi")); int free; Assert.AreEqual(POIFSConstants.FAT_SECTOR_BLOCK, fs.GetNextBlock(99)); assertBATCount(fs, 1, 0); for (int i = 100; i < 128; i++) Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(i)); Assert.AreEqual(true, fs.GetBATBlockAndIndex(0).Block.HasFreeSectors); for (int i = 100; i < 128; i++) fs.SetNextBlock(i, POIFSConstants.END_OF_CHAIN); Assert.AreEqual(false, fs.GetBATBlockAndIndex(0).Block.HasFreeSectors); try { Assert.AreEqual(false, fs.GetBATBlockAndIndex(128).Block.HasFreeSectors); Assert.Fail("Should only be one BAT"); } //catch (IndexOutOfRangeException) catch (ArgumentOutOfRangeException) { } assertBATCount(fs, 1, 0); // Now ask for a free one, will need to extend the file Assert.AreEqual(129, fs.GetFreeBlock()); Assert.AreEqual(false, fs.GetBATBlockAndIndex(0).Block.HasFreeSectors); Assert.AreEqual(true, fs.GetBATBlockAndIndex(128).Block.HasFreeSectors); Assert.AreEqual(POIFSConstants.FAT_SECTOR_BLOCK, fs.GetNextBlock(128)); Assert.AreEqual(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).Block.HasFreeSectors) { free = fs.GetFreeBlock(); fs.SetNextBlock(free, POIFSConstants.END_OF_CHAIN); } } Assert.AreEqual(false, fs.GetBATBlockAndIndex(109 * 128 - 1).Block.HasFreeSectors); try { Assert.AreEqual(false, fs.GetBATBlockAndIndex(109 * 128).Block.HasFreeSectors); Assert.Fail("Should only be 109 BATs"); } // catch (IndexOutOfRangeException) catch (ArgumentOutOfRangeException) { } // 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); Assert.AreEqual(109, header.BATCount); Assert.AreEqual(0, header.XBATCount); free = fs.GetFreeBlock(); Assert.AreEqual(false, fs.GetBATBlockAndIndex(109 * 128 - 1).Block.HasFreeSectors); Assert.AreEqual(true, fs.GetBATBlockAndIndex(110 * 128 - 1).Block.HasFreeSectors); try { Assert.AreEqual(false, fs.GetBATBlockAndIndex(110 * 128).Block.HasFreeSectors); Assert.Fail("Should only be 110 BATs"); } //catch (IndexOutOfRangeException) catch (ArgumentOutOfRangeException) { } assertBATCount(fs, 110, 1); header = WriteOutAndReadHeader(fs); Assert.AreEqual(110, header.BATCount); Assert.AreEqual(1, header.XBATCount); for (int i = 109; i < 109 + 127; i++) { fs.GetFreeBlock(); int startOffset = i * 128; while (fs.GetBATBlockAndIndex(startOffset).Block.HasFreeSectors) { free = fs.GetFreeBlock(); fs.SetNextBlock(free, POIFSConstants.END_OF_CHAIN); } assertBATCount(fs, i + 1, 1); } // Should now have 109+127 = 236 BATs Assert.AreEqual(false, fs.GetBATBlockAndIndex(236 * 128 - 1).Block.HasFreeSectors); try { Assert.AreEqual(false, fs.GetBATBlockAndIndex(236 * 128).Block.HasFreeSectors); Assert.Fail("Should only be 236 BATs"); } catch (ArgumentOutOfRangeException) { } assertBATCount(fs, 236, 1); // Ask for another, will get our 2nd XBAT free = fs.GetFreeBlock(); Assert.AreEqual(false, fs.GetBATBlockAndIndex(236 * 128 - 1).Block.HasFreeSectors); Assert.AreEqual(true, fs.GetBATBlockAndIndex(237 * 128 - 1).Block.HasFreeSectors); try { Assert.AreEqual(false, fs.GetBATBlockAndIndex(237 * 128).Block.HasFreeSectors); Assert.Fail("Should only be 237 BATs"); } // catch (IndexOutOfRangeException) { } catch (ArgumentOutOfRangeException) { } // 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); Assert.AreEqual(false, fs.GetBATBlockAndIndex(236 * 128 - 1).Block.HasFreeSectors); Assert.AreEqual(true, fs.GetBATBlockAndIndex(237 * 128 - 1).Block.HasFreeSectors); try { Assert.AreEqual(false, fs.GetBATBlockAndIndex(237 * 128).Block.HasFreeSectors); Assert.Fail("Should only be 237 BATs"); } catch (ArgumentOutOfRangeException) { } fs.Close(); }
public void TestGetFreeBlockWithSpare() { NPOIFSFileSystem fs = new NPOIFSFileSystem(_inst.GetFile("BlockSize512.zvi")); Assert.AreEqual(true, fs.GetBATBlockAndIndex(0).Block.HasFreeSectors); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(100)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(101)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(102)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(103)); Assert.AreEqual(100, fs.GetFreeBlock()); Assert.AreEqual(100, fs.GetFreeBlock()); fs.SetNextBlock(100, POIFSConstants.END_OF_CHAIN); Assert.AreEqual(101, fs.GetFreeBlock()); fs.Close(); }
public void AddBeforeWrite() { NPOIFSFileSystem fs = new NPOIFSFileSystem(); DocumentEntry miniDoc; DocumentEntry normDoc; HeaderBlock hdr; // Initially has BAT + Properties but nothing else Assert.AreEqual(POIFSConstants.FAT_SECTOR_BLOCK, fs.GetNextBlock(0)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(1)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(2)); hdr = WriteOutAndReadHeader(fs); // No mini stream, and no xbats // Will have fat then properties stream Assert.AreEqual(1, hdr.BATCount); Assert.AreEqual(0, hdr.BATArray[0]); Assert.AreEqual(2, hdr.PropertyStart); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, hdr.SBATStart); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, hdr.XBATIndex); Assert.AreEqual(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 MemoryStream(mini)); // Add to the main stream byte[] main4096 = new byte[4096]; main4096[0] = unchecked((byte)-10); main4096[4095] = unchecked((byte)-11); testDir.CreateDocument("Normal4096", new MemoryStream(main4096)); // Check the mini stream was Added, then the main stream Assert.AreEqual(POIFSConstants.FAT_SECTOR_BLOCK, fs.GetNextBlock(0)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(1)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(2)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(3)); Assert.AreEqual(5, fs.GetNextBlock(4)); Assert.AreEqual(6, fs.GetNextBlock(5)); Assert.AreEqual(7, fs.GetNextBlock(6)); Assert.AreEqual(8, fs.GetNextBlock(7)); Assert.AreEqual(9, fs.GetNextBlock(8)); Assert.AreEqual(10, fs.GetNextBlock(9)); Assert.AreEqual(11, fs.GetNextBlock(10)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(11)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(12)); Assert.AreEqual(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 Assert.AreEqual(1, hdr.BATCount); Assert.AreEqual(0, hdr.BATArray[0]); Assert.AreEqual(2, hdr.SBATStart); Assert.AreEqual(12, hdr.PropertyStart); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, hdr.XBATIndex); // Check the block allocation is unChanged, other than // the properties stream going in at the end Assert.AreEqual(POIFSConstants.FAT_SECTOR_BLOCK, fs.GetNextBlock(0)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(1)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(2)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(3)); Assert.AreEqual(5, fs.GetNextBlock(4)); Assert.AreEqual(6, fs.GetNextBlock(5)); Assert.AreEqual(7, fs.GetNextBlock(6)); Assert.AreEqual(8, fs.GetNextBlock(7)); Assert.AreEqual(9, fs.GetNextBlock(8)); Assert.AreEqual(10, fs.GetNextBlock(9)); Assert.AreEqual(11, fs.GetNextBlock(10)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(11)); Assert.AreEqual(13, fs.GetNextBlock(12)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(13)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(14)); Assert.AreEqual(POIFSConstants.SMALLER_BIG_BLOCK_SIZE * 15, fs.Size); // Check the data DirectoryEntry fsRoot = fs.Root; Assert.AreEqual(1, fsRoot.EntryCount); parentDir = (DirectoryEntry)fsRoot.GetEntry("Parent Directory"); Assert.AreEqual(1, parentDir.EntryCount); testDir = (DirectoryEntry)parentDir.GetEntry("Test Directory"); Assert.AreEqual(2, testDir.EntryCount); miniDoc = (DocumentEntry)testDir.GetEntry("Mini"); assertContentsMatches(mini, miniDoc); normDoc = (DocumentEntry)testDir.GetEntry("Normal4096"); assertContentsMatches(main4096, normDoc); byte[] mini2 = new byte[] { unchecked((byte)-42), 0, unchecked((byte)-1), unchecked((byte)-2), unchecked((byte)-3), unchecked((byte)-4), unchecked((byte)-42) }; testDir.CreateDocument("Mini2", new MemoryStream(mini2)); // Add to the main stream byte[] main4106 = new byte[4106]; main4106[0] = 41; main4106[4105] = 42; testDir.CreateDocument("Normal4106", new MemoryStream(main4106)); // Recheck the data in all 4 streams fs = WriteOutAndReadBack(fs); fsRoot = fs.Root; Assert.AreEqual(1, fsRoot.EntryCount); parentDir = (DirectoryEntry)fsRoot.GetEntry("Parent Directory"); Assert.AreEqual(1, parentDir.EntryCount); testDir = (DirectoryEntry)parentDir.GetEntry("Test Directory"); Assert.AreEqual(4, testDir.EntryCount); miniDoc = (DocumentEntry)testDir.GetEntry("Mini"); assertContentsMatches(mini, miniDoc); miniDoc = (DocumentEntry)testDir.GetEntry("Mini2"); assertContentsMatches(mini2, miniDoc); normDoc = (DocumentEntry)testDir.GetEntry("Normal4106"); assertContentsMatches(main4106, normDoc); }
public void TestCreateWriteRead() { NPOIFSFileSystem fs = new NPOIFSFileSystem(); // Initially has a BAT but not SBAT Assert.AreEqual(POIFSConstants.FAT_SECTOR_BLOCK, fs.GetNextBlock(0)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(1)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(2)); // Check that the SBAT is empty Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.Root.Property.StartBlock); // Write and read it MemoryStream baos = new MemoryStream(); fs.WriteFilesystem(baos); byte[] temp = baos.ToArray(); fs = new NPOIFSFileSystem(new MemoryStream(temp)); //fs = new NPOIFSFileSystem(new MemoryStream(baos.ToArray())); // Check it's still like that Assert.AreEqual(POIFSConstants.FAT_SECTOR_BLOCK, fs.GetNextBlock(0)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(1)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(2)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.Root.Property.StartBlock); // Now add a normal stream and a mini stream // TODO // TODO The rest of the test }
public void TestGetFreeBlockWithNoneSpare() { NPOIFSFileSystem fs = new NPOIFSFileSystem(_inst.OpenResourceAsStream("BlockSize512.zvi")); int free; Assert.AreEqual(POIFSConstants.FAT_SECTOR_BLOCK, fs.GetNextBlock(99)); for (int i = 100; i < 128; i++) Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(i)); Assert.AreEqual(true, fs.GetBATBlockAndIndex(0).Block.HasFreeSectors); for (int i = 100; i < 128; i++) fs.SetNextBlock(i, POIFSConstants.END_OF_CHAIN); Assert.AreEqual(false, fs.GetBATBlockAndIndex(0).Block.HasFreeSectors); try { Assert.AreEqual(false, fs.GetBATBlockAndIndex(128).Block.HasFreeSectors); Assert.Fail("Should only be one BAT"); } //catch (IndexOutOfRangeException) catch(ArgumentOutOfRangeException) { } // Now ask for a free one, will need to extend the file Assert.AreEqual(129, fs.GetFreeBlock()); Assert.AreEqual(false, fs.GetBATBlockAndIndex(0).Block.HasFreeSectors); Assert.AreEqual(true, fs.GetBATBlockAndIndex(128).Block.HasFreeSectors); Assert.AreEqual(POIFSConstants.FAT_SECTOR_BLOCK, fs.GetNextBlock(128)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(129)); // Fill up to hold 109 BAT blocks for (int i = 0; i < 109; i++) { fs.GetFreeBlock(); int startOffset = i * 128; while (fs.GetBATBlockAndIndex(startOffset).Block.HasFreeSectors) { free = fs.GetFreeBlock(); fs.SetNextBlock(free, POIFSConstants.END_OF_CHAIN); } } Assert.AreEqual(false, fs.GetBATBlockAndIndex(109 * 128 - 1).Block.HasFreeSectors); try { Assert.AreEqual(false, fs.GetBATBlockAndIndex(109 * 128).Block.HasFreeSectors); Assert.Fail("Should only be 109 BATs"); } // catch (IndexOutOfRangeException) catch(ArgumentOutOfRangeException) { } free = fs.GetFreeBlock(); Assert.AreEqual(false, fs.GetBATBlockAndIndex(109 * 128 - 1).Block.HasFreeSectors); Assert.AreEqual(true, fs.GetBATBlockAndIndex(110 * 128 - 1).Block.HasFreeSectors); try { Assert.AreEqual(false, fs.GetBATBlockAndIndex(110 * 128).Block.HasFreeSectors); Assert.Fail("Should only be 110 BATs"); } //catch (IndexOutOfRangeException) catch(ArgumentOutOfRangeException) { } for (int i = 109; i < 109 + 127; i++) { fs.GetFreeBlock(); int startOffset = i * 128; while (fs.GetBATBlockAndIndex(startOffset).Block.HasFreeSectors) { free = fs.GetFreeBlock(); fs.SetNextBlock(free, POIFSConstants.END_OF_CHAIN); } } // Should now have 109+127 = 236 BATs Assert.AreEqual(false, fs.GetBATBlockAndIndex(236 * 128 - 1).Block.HasFreeSectors); try { Assert.AreEqual(false, fs.GetBATBlockAndIndex(236 * 128).Block.HasFreeSectors); Assert.Fail("Should only be 236 BATs"); } catch (ArgumentOutOfRangeException) { } // Ask for another, will get our 2nd XBAT free = fs.GetFreeBlock(); Assert.AreEqual(false, fs.GetBATBlockAndIndex(236 * 128 - 1).Block.HasFreeSectors); Assert.AreEqual(true, fs.GetBATBlockAndIndex(237 * 128 - 1).Block.HasFreeSectors); try { Assert.AreEqual(false, fs.GetBATBlockAndIndex(237 * 128).Block.HasFreeSectors); Assert.Fail("Should only be 237 BATs"); } // catch (IndexOutOfRangeException) { } catch (ArgumentOutOfRangeException) { } // Check the counts int numBATs = 0; int numXBATs = 0; for (int i = 0; i < 237 * 128; i++) { if (fs.GetNextBlock(i) == POIFSConstants.FAT_SECTOR_BLOCK) { numBATs++; } if (fs.GetNextBlock(i) == POIFSConstants.DIFAT_SECTOR_BLOCK) { numXBATs++; } } Assert.AreEqual(237, numBATs); #if !HIDE_UNREACHABLE_CODE if (1 == 2) { // TODO Fix this - actual is 128 Assert.AreEqual(2, numXBATs); } #endif MemoryStream stream = new MemoryStream(); fs.WriteFilesystem(stream); HeaderBlock header = new HeaderBlock(new MemoryStream(stream.ToArray())); Assert.AreEqual(237, header.BATCount); #if !HIDE_UNREACHABLE_CODE if (1 == 2) // TODO Fix this - actual is 128 { Assert.AreEqual(2, header.XBATCount); fs = new NPOIFSFileSystem(new MemoryStream(stream.ToArray())); } #endif }