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 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(); }