Пример #1
0
        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();
        }
Пример #2
0
        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();
        }
Пример #3
0
        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();
        }
Пример #4
0
        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();
        }
Пример #5
0
        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();
        }