/// <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 <object> documents, RootProperty root) { _sbat = new BlockAllocationTableWriter(bigBlockSize); _small_blocks = new List <object>(); _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> /// convert a single long array into an array of SmallDocumentBlock /// instances /// </summary> /// <param name="bigBlockSize">the poifs bigBlockSize</param> /// <param name="array">the byte array to be converted</param> /// <param name="size">the intended size of the array (which may be smaller)</param> /// <returns>an array of SmallDocumentBlock instances, filled from /// the array</returns> public static SmallDocumentBlock [] Convert(POIFSBigBlockSize bigBlockSize, byte [] array, int size) { SmallDocumentBlock[] rval = new SmallDocumentBlock[(size + _block_size - 1) / _block_size]; int offset = 0; for (int k = 0; k < rval.Length; k++) { rval[k] = new SmallDocumentBlock(bigBlockSize); if (offset < array.Length) { int length = Math.Min(_block_size, array.Length - offset); Array.Copy(array, offset, rval[k]._data, 0, length); if (length != _block_size) { for (int i = length; i < _block_size; i++) { rval[k]._data[i] = _default_fill; } } } else { for (int j = 0; j < rval[k]._data.Length; j++) { rval[k]._data[j] = _default_fill; } } offset += _block_size; } return(rval); }
/// <summary> /// Makes the empty small document block. /// </summary> /// <returns></returns> private static SmallDocumentBlock MakeEmptySmallDocumentBlock(POIFSBigBlockSize bigBlockSize) { SmallDocumentBlock block = new SmallDocumentBlock(bigBlockSize); for (int i = 0; i < block._data.Length; i++) { block._data[i] = _default_fill; } return(block); }
/// <summary> /// fetch the small document block list from an existing file /// </summary> /// <param name="bigBlockSize">the poifs bigBlockSize</param> /// <param name="blockList">the raw data from which the small block table will be extracted</param> /// <param name="root">the root property (which contains the start block and small block table size)</param> /// <param name="sbatStart">the start block of the SBAT</param> /// <returns>the small document block list</returns> public static BlockList GetSmallDocumentBlocks(POIFSBigBlockSize bigBlockSize, RawDataBlockList blockList, RootProperty root, int sbatStart) { BlockList list = new SmallDocumentBlockList( SmallDocumentBlock.Extract(bigBlockSize, blockList.FetchBlocks(root.StartBlock, -1))); new BlockAllocationTableReader(bigBlockSize, blockList.FetchBlocks(sbatStart, -1), list); return(list); }
/// <summary> /// Factory for creating SmallDocumentBlocks from DocumentBlocks /// </summary> /// <param name="bigBlocksSize"></param> /// <param name="store">the original DocumentBlocks</param> /// <param name="size">the total document size</param> /// <returns>an array of new SmallDocumentBlocks instances</returns> public static SmallDocumentBlock [] Convert(POIFSBigBlockSize bigBlocksSize, BlockWritable [] store, int size) { using (MemoryStream stream = new MemoryStream()) { for (int j = 0; j < store.Length; j++) { store[j].WriteBlocks(stream); } byte[] data = stream.ToArray(); SmallDocumentBlock[] rval = new SmallDocumentBlock[ConvertToBlockCount(size)]; for (int index = 0; index < rval.Length; index++) { rval[index] = new SmallDocumentBlock(bigBlocksSize, data, index); } return(rval); } }