/// <summary> /// Initializes a new instance of the <see cref="SmallBlockTableWriter"/> class. /// </summary> /// <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); }
/// <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; }