/// <summary> /// create a document block from a raw data block /// </summary> /// <param name="block">The block.</param> public DocumentBlock(RawDataBlock block) : base(block.BigBlockSize == POIFSConstants.SMALLER_BIG_BLOCK_SIZE ? POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS : POIFSConstants.LARGER_BIG_BLOCK_SIZE_DETAILS) { _data = block.Data; _bytes_Read = _data.Length; }
/// <summary> /// Initializes a new instance of the <see cref="RawDataBlockList"/> class. /// </summary> /// <param name="stream">the InputStream from which the data will be read</param> /// <param name="bigBlockSize">The big block size, either 512 bytes or 4096 bytes</param> public RawDataBlockList(Stream stream, POIFSBigBlockSize bigBlockSize) { List<RawDataBlock> blocks = new List<RawDataBlock>(); while (true) { RawDataBlock block = new RawDataBlock(stream, bigBlockSize.GetBigBlockSize()); // If there was data, add the block to the list if(block.HasData) { blocks.Add(block); } // If the stream is now at the End Of File, we're done if (block.EOF) { break; } } SetBlocks((ListManagedBlock[])blocks.ToArray()); }
/// <summary> /// create a BlockAllocationTableReader for an existing filesystem. Side /// effect: when this method finishes, the BAT blocks will have /// been Removed from the raw block list, and any blocks labeled as /// 'unused' in the block allocation table will also have been /// Removed from the raw block list. </summary> /// <param name="block_count">the number of BAT blocks making up the block allocation table</param> /// <param name="block_array">the array of BAT block indices from the /// filesystem's header</param> /// <param name="xbat_count">the number of XBAT blocks</param> /// <param name="xbat_index">the index of the first XBAT block</param> /// <param name="raw_block_list">the list of RawDataBlocks</param> public BlockAllocationTableReader(POIFSBigBlockSize bigBlockSizse, int block_count, int[] block_array, int xbat_count, int xbat_index, BlockList raw_block_list) : this(bigBlockSizse) { SanityCheckBlockCount(block_count); RawDataBlock[] blocks = new RawDataBlock[block_count]; int limit = Math.Min(block_count, block_array.Length); int block_index; for (block_index = 0; block_index < limit; block_index++) { int nextOffset = block_array[block_index]; if (nextOffset > raw_block_list.BlockCount()) { throw new IOException("Your file contains " + raw_block_list.BlockCount() + " sectors, but the initial DIFAT array at index " + block_index + " referenced block # " + nextOffset + ". This isn't allowed and " + " your file is corrupt"); } blocks[block_index] = (RawDataBlock)raw_block_list.Remove(nextOffset); } if (block_index < block_count) { // must have extended blocks if (xbat_index < 0) { throw new IOException( "BAT count exceeds limit, yet XBAT index indicates no valid entries"); } int chain_index = xbat_index; int max_entries_per_block = BATBlock.EntriesPerXBATBlock; int chain_index_offset = BATBlock.XBATChainOffset; // Each XBAT block contains either: // (maximum number of sector indexes) + index of next XBAT // some sector indexes + FREE sectors to max # + EndOfChain for (int j = 0; j < xbat_count; j++) { limit = Math.Min(block_count - block_index, max_entries_per_block); byte[] data = raw_block_list.Remove(chain_index).Data; int offset = 0; for (int k = 0; k < limit; k++) { blocks[block_index++] = (RawDataBlock)raw_block_list.Remove(LittleEndian.GetInt(data, offset)); offset += LittleEndianConsts.INT_SIZE; } chain_index = LittleEndian.GetInt(data, chain_index_offset); if (chain_index == POIFSConstants.END_OF_CHAIN) { break; } } } if (block_index != block_count) { throw new IOException("Could not find all blocks"); } // now that we have all of the raw data blocks, go through and // create the indices SetEntries((ListManagedBlock[])blocks, raw_block_list); }