/// <summary>
        /// Initializes a new instance of the <see cref="SmallBlockTableWriter"/> class.
        /// </summary>
        /// <param name="bigBlockSize">the poifs bigBlockSize</param>
        /// <param name="documents">a IList of POIFSDocument instances</param>
        /// <param name="root">the Filesystem's root property</param>
        public SmallBlockTableWriter(POIFSBigBlockSize bigBlockSize, IList documents,
                                     RootProperty root)
        {
            _sbat = new BlockAllocationTableWriter(bigBlockSize);
            _small_blocks = new ArrayList();
            _root         = root;
            IEnumerator iter = documents.GetEnumerator();

            while (iter.MoveNext())
            {
                POIFSDocument   doc    = ( POIFSDocument ) iter.Current;
                BlockWritable[] blocks = doc.SmallBlocks;

                if (blocks.Length != 0)
                {
                    doc.StartBlock=_sbat.AllocateSpace(blocks.Length);
                    for (int j = 0; j < blocks.Length; j++)
                    {
                        _small_blocks.Add(blocks[ j ]);
                    }
                } else {
            	    doc.StartBlock=POIFSConstants.END_OF_CHAIN;
                }
            }
            _sbat.SimpleCreateBlocks();
            _root.Size=_small_blocks.Count;
            _big_block_count = SmallDocumentBlock.Fill(bigBlockSize, _small_blocks);
        }
        public void TestAllocateSpace()
        {
            BlockAllocationTableWriter table = new BlockAllocationTableWriter(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS);

            int[] blockSizes = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

            int expectedIndex = 0;

            for (int i = 0; i < blockSizes.Length; i++)
            {
                Assert.AreEqual(expectedIndex, table.AllocateSpace(blockSizes[i]));
                expectedIndex += blockSizes[i];
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Writes the file system.
        /// </summary>
        /// <param name="stream">the OutputStream to which the filesystem will be
        /// written</param>
        public void WriteFileSystem(Stream stream)
        {

            // Get the property table Ready
            _property_table.PreWrite();

            // Create the small block store, and the SBAT
            SmallBlockTableWriter      sbtw       =
                new SmallBlockTableWriter(bigBlockSize,_documents, _property_table.Root);

            // Create the block allocation table
            BlockAllocationTableWriter bat        =
                new BlockAllocationTableWriter(bigBlockSize);

            // Create a list of BATManaged objects: the documents plus the
            // property table and the small block table
            ArrayList bm_objects = new ArrayList();

            bm_objects.AddRange(_documents);
            bm_objects.Add(_property_table);
            bm_objects.Add(sbtw);
            bm_objects.Add(sbtw.SBAT);

            // walk the list, allocating space for each and assigning each
            // a starting block number
            IEnumerator iter = bm_objects.GetEnumerator();

            while (iter.MoveNext())
            {
                BATManaged bmo         = ( BATManaged ) iter.Current;
                int        block_count = bmo.CountBlocks;

                if (block_count != 0)
                {
                    bmo.StartBlock=bat.AllocateSpace(block_count);
                }
                else
                {

                    // Either the BATManaged object is empty or its data
                    // is composed of SmallBlocks; in either case,
                    // allocating space in the BAT is inappropriate
                }
            }

            // allocate space for the block allocation table and take its
            // starting block
            int               batStartBlock       = bat.CreateBlocks();

            // Get the extended block allocation table blocks
            HeaderBlockWriter header_block_Writer = new HeaderBlockWriter(bigBlockSize);
            BATBlock[] xbat_blocks =
                header_block_Writer.SetBATBlocks(bat.CountBlocks,
                                                    batStartBlock);

            // Set the property table start block
            header_block_Writer.PropertyStart=_property_table.StartBlock;

            // Set the small block allocation table start block
            header_block_Writer.SBATStart=sbtw.SBAT.StartBlock;

            // Set the small block allocation table block count
            header_block_Writer.SBATBlockCount=sbtw.SBATBlockCount;

            // the header is now properly initialized. Make a list of
            // Writers (the header block, followed by the documents, the
            // property table, the small block store, the small block
            // allocation table, the block allocation table, and the
            // extended block allocation table blocks)
            ArrayList Writers = new ArrayList();

            Writers.Add(header_block_Writer);
            Writers.AddRange(_documents);
            Writers.Add(_property_table);
            Writers.Add(sbtw);
            Writers.Add(sbtw.SBAT);
            Writers.Add(bat);
            for (int j = 0; j < xbat_blocks.Length; j++)
            {
                Writers.Add(xbat_blocks[j]);
            }

            // now, Write everything out
            iter = Writers.GetEnumerator();
            while (iter.MoveNext())
            {
                BlockWritable Writer = ( BlockWritable ) iter.Current;

                Writer.WriteBlocks(stream);
            }

            Writers=null;
            iter = null;
        }
        public void TestCreateBlocks()
        {
            BlockAllocationTableWriter table = new BlockAllocationTableWriter(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS);

            table.AllocateSpace(127);
            table.CreateBlocks();
            VerifyBlocksCreated(table, 1);

            table = new BlockAllocationTableWriter(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS);
            table.AllocateSpace(128);
            table.CreateBlocks();
            VerifyBlocksCreated(table, 2);

            table = new BlockAllocationTableWriter(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS);
            table.AllocateSpace(254);
            table.CreateBlocks();
            VerifyBlocksCreated(table, 2);

            table = new BlockAllocationTableWriter(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS);
            table.AllocateSpace(255);
            table.CreateBlocks();
            VerifyBlocksCreated(table, 3);

            table = new BlockAllocationTableWriter(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS);
            table.AllocateSpace(13843);
            table.CreateBlocks();
            VerifyBlocksCreated(table, 109);

            table = new BlockAllocationTableWriter(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS);
            table.AllocateSpace(13844);
            table.CreateBlocks();
            VerifyBlocksCreated(table, 110);

            table = new BlockAllocationTableWriter(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS);
            table.AllocateSpace(13969);
            table.CreateBlocks();
            VerifyBlocksCreated(table, 110);

            table = new BlockAllocationTableWriter(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS);
            table.AllocateSpace(13970);
            table.CreateBlocks();
            VerifyBlocksCreated(table, 111);
        }
        public void TestProduct()
        {
            BlockAllocationTableWriter table = new BlockAllocationTableWriter(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS);

            for (int i = 1; i <= 22; i++)
                table.AllocateSpace(i);

            table.CreateBlocks();
            MemoryStream stream = new MemoryStream();

            table.WriteBlocks(stream);
            byte[] output = stream.ToArray();

            Assert.AreEqual(1024, output.Length);
            byte[] expected = new byte[1024];

            for (int i = 0; i < expected.Length; i++)
            {
                expected[i] = (byte)0xFF;
            }
            int offset = 0;
            int blockIndex = 1;

            for (int i = 1; i <= 22; i++)
            {
                int limit = i - 1;

                for (int j = 0; j < limit; j++)
                {
                    LittleEndian.PutInt(expected, offset, blockIndex++);
                    offset += LittleEndianConsts.INT_SIZE;
                }

                LittleEndian.PutInt(expected, offset, POIFSConstants.END_OF_CHAIN);

                offset += 4;
                blockIndex++;
            }

            LittleEndian.PutInt(expected, offset, blockIndex++);
            offset += LittleEndianConsts.INT_SIZE;
            LittleEndian.PutInt(expected, offset, POIFSConstants.END_OF_CHAIN);

            for (int i = 0; i < expected.Length; i++)
                Assert.AreEqual(expected[i], output[i], "At offset " + i);
        }