Пример #1
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 TestWritingConstructor()
        {
            ArrayList documents = new ArrayList();

            documents.Add(
                new POIFSDocument(
                    "doc340", new MemoryStream(new byte[340])));
            documents.Add(
                new POIFSDocument(
                    "doc5000", new MemoryStream(new byte[5000])));
            documents
                .Add(new POIFSDocument("doc0",
                                       new MemoryStream(new byte[0])));
            documents
                .Add(new POIFSDocument("doc1",
                                       new MemoryStream(new byte[1])));
            documents
                .Add(new POIFSDocument("doc2",
                                       new MemoryStream(new byte[2])));
            documents
                .Add(new POIFSDocument("doc3",
                                       new MemoryStream(new byte[3])));
            documents
                .Add(new POIFSDocument("doc4",
                                       new MemoryStream(new byte[4])));
            documents
                .Add(new POIFSDocument("doc5",
                                       new MemoryStream(new byte[5])));
            documents
                .Add(new POIFSDocument("doc6",
                                       new MemoryStream(new byte[6])));
            documents
                .Add(new POIFSDocument("doc7",
                                       new MemoryStream(new byte[7])));
            documents
                .Add(new POIFSDocument("doc8",
                                       new MemoryStream(new byte[8])));
            documents
                .Add(new POIFSDocument("doc9",
                                       new MemoryStream(new byte[9])));
            HeaderBlock header = new HeaderBlock(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS);
            RootProperty root = new PropertyTable(header).Root;
            SmallBlockTableWriter sbtw = new SmallBlockTableWriter(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, documents, root);
            BlockAllocationTableWriter bat = sbtw.SBAT;

            // 15 small blocks: 6 for doc340, 0 for doc5000 (too big), 0
            // for doc0 (no storage needed), 1 each for doc1 through doc9
            Assert.AreEqual(15 * 64, root.Size);

            // 15 small blocks rounds up to 2 big blocks
            Assert.AreEqual(2, sbtw.CountBlocks);
            int start_block = 1000 + root.StartBlock;

            sbtw.StartBlock = start_block;
            Assert.AreEqual(start_block, root.StartBlock);
        }