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 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)); fs.Close(); }
public void TestReadWriteNewStream() { NPOIFSFileSystem fs = new NPOIFSFileSystem(); NPOIFSStream stream = new NPOIFSStream(fs); // Check our filesystem has a BAT and the Properties Assert.AreEqual(2, fs.GetFreeBlock()); BATBlock bat = fs.GetBATBlockAndIndex(0).Block; Assert.AreEqual(POIFSConstants.FAT_SECTOR_BLOCK, bat.GetValueAt(0)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, bat.GetValueAt(1)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, bat.GetValueAt(2)); // Check the stream as-is Assert.AreEqual(POIFSConstants.END_OF_CHAIN, stream.GetStartBlock()); try { stream.GetBlockIterator(); Assert.Fail("Shouldn't be able to get an iterator before writing"); } catch (Exception) { } // Write in two blocks byte[] data = new byte[512 + 20]; for (int i = 0; i < 512; i++) { data[i] = (byte)(i % 256); } for (int i = 512; i < data.Length; i++) { data[i] = (byte)(i % 256 + 100); } stream.UpdateContents(data); // Check now Assert.AreEqual(4, fs.GetFreeBlock()); bat = fs.GetBATBlockAndIndex(0).Block; Assert.AreEqual(POIFSConstants.FAT_SECTOR_BLOCK, bat.GetValueAt(0)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, bat.GetValueAt(1)); Assert.AreEqual(3, bat.GetValueAt(2)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, bat.GetValueAt(3)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, bat.GetValueAt(4)); IEnumerator<ByteBuffer> it = stream.GetBlockIterator(); Assert.AreEqual(true, it.MoveNext()); ByteBuffer b = it.Current; byte[] read = new byte[512]; //b.get(read); // Array.Copy(b, 0, read, 0, b.Length); b.Read(read); for (int i = 0; i < read.Length; i++) { //Assert.AreEqual("Wrong value at " + i, data[i], read[i]); Assert.AreEqual(data[i], read[i], "Wrong value at " + i); } Assert.AreEqual(true, it.MoveNext()); b = it.Current; read = new byte[512]; //b.get(read); //Array.Copy(b, 0, read, 0, b.Length); b.Read(read); for (int i = 0; i < 20; i++) { Assert.AreEqual(data[i + 512], read[i]); } for (int i = 20; i < read.Length; i++) { Assert.AreEqual(0, read[i]); } Assert.AreEqual(false, it.MoveNext()); fs.Close(); }
public void TestWriteThenReplace() { NPOIFSFileSystem fs = new NPOIFSFileSystem(); // Starts empty BATBlock bat = fs.GetBATBlockAndIndex(0).Block; Assert.AreEqual(POIFSConstants.FAT_SECTOR_BLOCK, bat.GetValueAt(0)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, bat.GetValueAt(1)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, bat.GetValueAt(2)); // Write something that uses a main stream byte[] main4106 = new byte[4106]; main4106[0] = unchecked((byte)-10); main4106[4105] = unchecked((byte)-11); DocumentEntry normal = fs.Root.CreateDocument( "Normal", new MemoryStream(main4106)); // Should have used 9 blocks Assert.AreEqual(POIFSConstants.FAT_SECTOR_BLOCK, bat.GetValueAt(0)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, bat.GetValueAt(1)); Assert.AreEqual(3, bat.GetValueAt(2)); Assert.AreEqual(4, bat.GetValueAt(3)); Assert.AreEqual(5, bat.GetValueAt(4)); Assert.AreEqual(6, bat.GetValueAt(5)); Assert.AreEqual(7, bat.GetValueAt(6)); Assert.AreEqual(8, bat.GetValueAt(7)); Assert.AreEqual(9, bat.GetValueAt(8)); Assert.AreEqual(10, bat.GetValueAt(9)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, bat.GetValueAt(10)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, bat.GetValueAt(11)); normal = (DocumentEntry)fs.Root.GetEntry("Normal"); Assert.AreEqual(4106, normal.Size); Assert.AreEqual(4106, ((DocumentNode)normal).Property.Size); // Replace with one still big enough for a main stream, but one block smaller byte[] main4096 = new byte[4096]; main4096[0] = unchecked((byte)-10); main4096[4095] = unchecked((byte)-11); NDocumentOutputStream nout = new NDocumentOutputStream(normal); nout.Write(main4096); nout.Close(); // Will have dropped to 8 Assert.AreEqual(POIFSConstants.FAT_SECTOR_BLOCK, bat.GetValueAt(0)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, bat.GetValueAt(1)); Assert.AreEqual(3, bat.GetValueAt(2)); Assert.AreEqual(4, bat.GetValueAt(3)); Assert.AreEqual(5, bat.GetValueAt(4)); Assert.AreEqual(6, bat.GetValueAt(5)); Assert.AreEqual(7, bat.GetValueAt(6)); Assert.AreEqual(8, bat.GetValueAt(7)); Assert.AreEqual(9, bat.GetValueAt(8)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, bat.GetValueAt(9)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, bat.GetValueAt(10)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, bat.GetValueAt(11)); normal = (DocumentEntry)fs.Root.GetEntry("Normal"); Assert.AreEqual(4096, normal.Size); Assert.AreEqual(4096, ((DocumentNode)normal).Property.Size); // Write and check fs = TestNPOIFSFileSystem.WriteOutAndReadBack(fs); bat = fs.GetBATBlockAndIndex(0).Block; // Will have properties, but otherwise the same Assert.AreEqual(POIFSConstants.FAT_SECTOR_BLOCK, bat.GetValueAt(0)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, bat.GetValueAt(1)); Assert.AreEqual(3, bat.GetValueAt(2)); Assert.AreEqual(4, bat.GetValueAt(3)); Assert.AreEqual(5, bat.GetValueAt(4)); Assert.AreEqual(6, bat.GetValueAt(5)); Assert.AreEqual(7, bat.GetValueAt(6)); Assert.AreEqual(8, bat.GetValueAt(7)); Assert.AreEqual(9, bat.GetValueAt(8)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, bat.GetValueAt(9)); // End of Normal Assert.AreEqual(POIFSConstants.END_OF_CHAIN, bat.GetValueAt(10)); // Props Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, bat.GetValueAt(11)); normal = (DocumentEntry)fs.Root.GetEntry("Normal"); Assert.AreEqual(4096, normal.Size); Assert.AreEqual(4096, ((DocumentNode)normal).Property.Size); // Make longer, take 1 block After the properties too normal = (DocumentEntry)fs.Root.GetEntry("Normal"); nout = new NDocumentOutputStream(normal); nout.Write(main4106); nout.Close(); Assert.AreEqual(POIFSConstants.FAT_SECTOR_BLOCK, bat.GetValueAt(0)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, bat.GetValueAt(1)); Assert.AreEqual(3, bat.GetValueAt(2)); Assert.AreEqual(4, bat.GetValueAt(3)); Assert.AreEqual(5, bat.GetValueAt(4)); Assert.AreEqual(6, bat.GetValueAt(5)); Assert.AreEqual(7, bat.GetValueAt(6)); Assert.AreEqual(8, bat.GetValueAt(7)); Assert.AreEqual(9, bat.GetValueAt(8)); Assert.AreEqual(11, bat.GetValueAt(9)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, bat.GetValueAt(10)); // Props Assert.AreEqual(POIFSConstants.END_OF_CHAIN, bat.GetValueAt(11)); // Normal Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, bat.GetValueAt(12)); normal = (DocumentEntry)fs.Root.GetEntry("Normal"); Assert.AreEqual(4106, normal.Size); Assert.AreEqual(4106, ((DocumentNode)normal).Property.Size); // Make it small, will trigger the SBAT stream and free lots up byte[] mini = new byte[] { 42, 0, 1, 2, 3, 4, 42 }; normal = (DocumentEntry)fs.Root.GetEntry("Normal"); nout = new NDocumentOutputStream(normal); nout.Write(mini); nout.Close(); Assert.AreEqual(POIFSConstants.FAT_SECTOR_BLOCK, bat.GetValueAt(0)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, bat.GetValueAt(1)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, bat.GetValueAt(2)); // SBAT Assert.AreEqual(POIFSConstants.END_OF_CHAIN, bat.GetValueAt(3)); // Mini Stream Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, bat.GetValueAt(4)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, bat.GetValueAt(5)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, bat.GetValueAt(6)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, bat.GetValueAt(7)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, bat.GetValueAt(8)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, bat.GetValueAt(9)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, bat.GetValueAt(10)); // Props Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, bat.GetValueAt(11)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, bat.GetValueAt(12)); normal = (DocumentEntry)fs.Root.GetEntry("Normal"); Assert.AreEqual(7, normal.Size); Assert.AreEqual(7, ((DocumentNode)normal).Property.Size); // Finally back to big again nout = new NDocumentOutputStream(normal); nout.Write(main4096); nout.Close(); // Will keep the mini stream, now empty Assert.AreEqual(POIFSConstants.FAT_SECTOR_BLOCK, bat.GetValueAt(0)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, bat.GetValueAt(1)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, bat.GetValueAt(2)); // SBAT Assert.AreEqual(POIFSConstants.END_OF_CHAIN, bat.GetValueAt(3)); // Mini Stream Assert.AreEqual(5, bat.GetValueAt(4)); Assert.AreEqual(6, bat.GetValueAt(5)); Assert.AreEqual(7, bat.GetValueAt(6)); Assert.AreEqual(8, bat.GetValueAt(7)); Assert.AreEqual(9, bat.GetValueAt(8)); Assert.AreEqual(11, bat.GetValueAt(9)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, bat.GetValueAt(10)); // Props Assert.AreEqual(12, bat.GetValueAt(11)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, bat.GetValueAt(12)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, bat.GetValueAt(13)); normal = (DocumentEntry)fs.Root.GetEntry("Normal"); Assert.AreEqual(4096, normal.Size); Assert.AreEqual(4096, ((DocumentNode)normal).Property.Size); // Save, re-load, re-check fs = TestNPOIFSFileSystem.WriteOutAndReadBack(fs); bat = fs.GetBATBlockAndIndex(0).Block; Assert.AreEqual(POIFSConstants.FAT_SECTOR_BLOCK, bat.GetValueAt(0)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, bat.GetValueAt(1)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, bat.GetValueAt(2)); // SBAT Assert.AreEqual(POIFSConstants.END_OF_CHAIN, bat.GetValueAt(3)); // Mini Stream Assert.AreEqual(5, bat.GetValueAt(4)); Assert.AreEqual(6, bat.GetValueAt(5)); Assert.AreEqual(7, bat.GetValueAt(6)); Assert.AreEqual(8, bat.GetValueAt(7)); Assert.AreEqual(9, bat.GetValueAt(8)); Assert.AreEqual(11, bat.GetValueAt(9)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, bat.GetValueAt(10)); // Props Assert.AreEqual(12, bat.GetValueAt(11)); Assert.AreEqual(POIFSConstants.END_OF_CHAIN, bat.GetValueAt(12)); Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, bat.GetValueAt(13)); normal = (DocumentEntry)fs.Root.GetEntry("Normal"); Assert.AreEqual(4096, normal.Size); Assert.AreEqual(4096, ((DocumentNode)normal).Property.Size); fs.Close(); }