/// <summary> /// Initializes a new instance of the <see cref="BlockAllocationTableWriter"/> class. /// </summary> public BlockAllocationTableWriter(POIFSBigBlockSize bigBlockSize) { _start_block = POIFSConstants.END_OF_CHAIN; _entries = new List<int>(_default_size); _blocks = new BATBlock[ 0 ]; _bigBlockSize = bigBlockSize; }
/// <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> /// convert a single long array into an array of SmallDocumentBlock /// instances /// </summary> /// <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; }
public NPropertyTable(HeaderBlock headerBlock, NPOIFSFileSystem fileSystem) :base(headerBlock, BuildProperties( (new NPOIFSStream(fileSystem, headerBlock.PropertyStart)).GetEnumerator(),headerBlock.BigBlockSize) ) { _bigBigBlockSize = headerBlock.BigBlockSize; }
/// <summary> /// Create a single instance initialized with default values /// </summary> /// <param name="properties">the properties to be inserted</param> /// <param name="offset">the offset into the properties array</param> protected PropertyBlock(POIFSBigBlockSize bigBlockSize, Property[] properties, int offset) : base(bigBlockSize) { _properties = new Property[ bigBlockSize.GetPropertiesPerBlock() ]; for (int j = 0; j < _properties.Length; j++) { _properties[ j ] = properties[ j + offset ]; } }
public SmallDocumentBlock(POIFSBigBlockSize bigBlockSize, byte[] data, int index) { _bigBlockSize = bigBlockSize; _blocks_per_big_block = GetBlocksPerBigBlock(bigBlockSize); _data = new byte[_block_size]; System.Array.Copy(data, index*_block_size, _data, 0, _block_size); }
/** * reading constructor (used when we've read in a file and we want * to extract the property table from it). Populates the * properties thoroughly * * @param startBlock the first block of the property table * @param blockList the list of blocks * * @exception IOException if anything goes wrong (which should be * a result of the input being NFG) */ public PropertyTable(HeaderBlock headerBlock, RawDataBlockList blockList) : base(headerBlock, PropertyFactory.ConvertToProperties( blockList.FetchBlocks(headerBlock.PropertyStart, -1) ) ) { _bigBigBlockSize = headerBlock.BigBlockSize; _blocks = null; }
/// <summary> /// fetch the small document block list from an existing file /// </summary> /// <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; }
public POIFSDocument(string name, RawDataBlock[] blocks, int length) { _size = length; if (blocks.Length == 0) _bigBigBlockSize = POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS; else { _bigBigBlockSize = (blocks[0].BigBlockSize == POIFSConstants.SMALLER_BIG_BLOCK_SIZE ? POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS : POIFSConstants.LARGER_BIG_BLOCK_SIZE_DETAILS); } _big_store = new BigBlockStore(_bigBigBlockSize, ConvertRawBlocksToBigBlocks(blocks)); _property = new DocumentProperty(name, _size); _small_store = new SmallBlockStore(_bigBigBlockSize, EMPTY_SMALL_BLOCK_ARRAY); _property.Document = this; }
/// <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()); }
// private static List<Property> BuildProperties(IEnumerator<byte[]> dataSource, POIFSBigBlockSize bigBlockSize) private static List<Property> BuildProperties(IEnumerator<ByteBuffer> dataSource, POIFSBigBlockSize bigBlockSize) { try { List<Property> properties = new List<Property>(); while(dataSource.MoveNext()) { ByteBuffer bb = dataSource.Current; //byte[] bb = (byte[])dataSource.Current; // Turn it into an array byte[] data; if (bb.HasBuffer && bb.Offset == 0 && bb.Buffer.Length == bigBlockSize.GetBigBlockSize()) { data = bb.Buffer; } else { data = new byte[bigBlockSize.GetBigBlockSize()]; //bb.get(data, 0, data.length); bb.Read(data, 0, data.Length); } //} //data = new byte[bigBlockSize.GetBigBlockSize()]; //System.Array.Copy(bb, data, bb.Length); PropertyFactory.ConvertToProperties(data, properties); } return properties; } catch(System.IO.IOException ex) { throw ex; } }
/// <summary> /// Create an array of PropertyBlocks from an array of Property /// instances, creating empty Property instances to make up any /// shortfall /// </summary> /// <param name="properties">the Property instances to be converted into PropertyBlocks, in a java List</param> /// <returns>the array of newly created PropertyBlock instances</returns> public static BlockWritable [] CreatePropertyBlockArray( POIFSBigBlockSize bigBlockSize, List<Property> properties) { int _properties_per_block = bigBlockSize.GetPropertiesPerBlock(); int blockCount = (properties.Count + _properties_per_block - 1) / _properties_per_block; Property[] toBeWritten = new Property[blockCount * _properties_per_block]; System.Array.Copy(properties.ToArray(), 0, toBeWritten, 0, properties.Count); for (int i = properties.Count; i < toBeWritten.Length; i++) { toBeWritten[i] = new AnonymousProperty(); } BlockWritable[] rvalue = new BlockWritable[blockCount]; for (int i = 0; i < blockCount; i++) rvalue[i] = new PropertyBlock(bigBlockSize, toBeWritten, i * _properties_per_block); return rvalue; }
//public static BATBlock CreateBATBlock(POIFSBigBlockSize bigBlockSize, byte[] data) public static BATBlock CreateBATBlock(POIFSBigBlockSize bigBlockSize, ByteBuffer data) { // Create an empty block BATBlock block = new BATBlock(bigBlockSize); // Fill it byte[] buffer = new byte[LittleEndianConsts.INT_SIZE]; //int index = 0; for (int i = 0; i < block._values.Length; i++) { //data.Read(buffer, 0, buffer.Length); //for (int j = 0; j < buffer.Length; j++, index++) // buffer[j] = data[index]; data.Read(buffer); block._values[i] = LittleEndian.GetInt(buffer); } block.RecomputeFree(); // All done return block; }
internal BigBlockStore(POIFSBigBlockSize bigBlockSize, POIFSDocumentPath path, string name, int size, POIFSWriterListener writer) { this.bigBlockSize = bigBlockSize; this.bigBlocks = new DocumentBlock[0]; this.path = path; this.name = name; this.size = size; this.writer = writer; }
internal BigBlockStore(POIFSBigBlockSize bigBlockSize, DocumentBlock[] blocks) { this.bigBlockSize = bigBlockSize; bigBlocks = (DocumentBlock[])blocks.Clone(); path = null; name = null; size = -1; writer = null; }
internal SmallBlockStore(POIFSBigBlockSize bigBlockSize, SmallDocumentBlock[] blocks) { this.bigBlockSize = bigBlockSize; smallBlocks = (SmallDocumentBlock[])blocks.Clone(); this.path = null; this.name = null; this.size = -1; this.writer = null; }
public POIFSDocument(string name, int size, POIFSBigBlockSize bigBlockSize, POIFSDocumentPath path, POIFSWriterListener writer) { _size = size; _bigBigBlockSize = bigBlockSize; _property = new DocumentProperty(name, _size); _property.Document = this; if (_property.ShouldUseSmallBlocks) { _small_store = new SmallBlockStore(_bigBigBlockSize, path, name, size, writer); _big_store = new BigBlockStore(_bigBigBlockSize, EMPTY_BIG_BLOCK_ARRAY); } else { _small_store = new SmallBlockStore(_bigBigBlockSize, EMPTY_SMALL_BLOCK_ARRAY); _big_store = new BigBlockStore(_bigBigBlockSize, path, name, size, writer); } }
public POIFSDocument(string name, POIFSBigBlockSize bigBlockSize, Stream stream) { List<DocumentBlock> blocks = new List<DocumentBlock>(); _size = 0; _bigBigBlockSize = bigBlockSize; while (true) { DocumentBlock block = new DocumentBlock(stream, bigBlockSize); int blockSize = block.Size; if (blockSize > 0) { blocks.Add(block); _size += blockSize; } if (block.PartiallyRead) break; } DocumentBlock[] bigBlocks = blocks.ToArray(); _big_store = new BigBlockStore(bigBlockSize, bigBlocks); _property = new DocumentProperty(name, _size); _property.Document = this; if (_property.ShouldUseSmallBlocks) { _small_store = new SmallBlockStore(bigBlockSize, SmallDocumentBlock.Convert(bigBlockSize, bigBlocks, _size)); _big_store = new BigBlockStore(bigBlockSize, new DocumentBlock[0]); } else { _small_store = new SmallBlockStore(bigBlockSize, EMPTY_SMALL_BLOCK_ARRAY); } }
/// <summary> /// Create an array of XBATBlocks from an array of int block /// allocation table entries /// </summary> /// <param name="entries">the array of int entries</param> /// <param name="startBlock">the start block of the array of XBAT blocks</param> /// <returns>the newly created array of BATBlocks</returns> public static BATBlock[] CreateXBATBlocks(POIFSBigBlockSize bigBlockSize, int[] entries, int startBlock) { int block_count = CalculateXBATStorageRequirements(entries.Length); BATBlock[] blocks = new BATBlock[block_count]; int index = 0; int remaining = entries.Length; if (block_count != 0) { for (int j = 0; j < entries.Length; j += _entries_per_xbat_block) { blocks[index++] = new BATBlock(bigBlockSize, entries, j, (remaining > _entries_per_xbat_block) ? j + _entries_per_xbat_block : entries.Length); remaining -= _entries_per_xbat_block; } for (index = 0; index < blocks.Length - 1; index++) { blocks[index].SetXBATChain(bigBlockSize, startBlock + index + 1); } blocks[index].SetXBATChain(bigBlockSize, POIFSConstants.END_OF_CHAIN); } return blocks; }
///** // * Creates a single BATBlock, with all the values set to empty. // */ public static BATBlock CreateEmptyBATBlock(POIFSBigBlockSize bigBlockSize, bool isXBAT) { BATBlock block = new BATBlock(bigBlockSize); if (isXBAT) { block.SetXBATChain(bigBlockSize, POIFSConstants.END_OF_CHAIN); } return block; }
/** * Default constructor */ public PropertyTable(HeaderBlock headerBlock) : base(headerBlock) { _bigBigBlockSize = headerBlock.BigBlockSize; _blocks = null; }
protected BATBlock(POIFSBigBlockSize bigBlockSize) : base(bigBlockSize) { int _entries_per_block = bigBlockSize.GetBATEntriesPerBlock(); _values = new int[_entries_per_block]; _has_free_sectors = true; for (int i = 0; i < _values.Length; i++) _values[i] = POIFSConstants.UNUSED_BLOCK; }
/** * Calculates the maximum size of a file which is addressable given the * number of FAT (BAT) sectors specified. (We don't care if those BAT * blocks come from the 109 in the header, or from header + XBATS, it * won't affect the calculation) * * The actual file size will be between [size of fatCount-1 blocks] and * [size of fatCount blocks]. * For 512 byte block sizes, this means we may over-estimate by up to 65kb. * For 4096 byte block sizes, this means we may over-estimate by up to 4mb */ public static int CalculateMaximumSize(POIFSBigBlockSize bigBlockSize, int numBATs) { int size = 1; // Header isn't FAT addressed // The header has up to 109 BATs, and extra ones are referenced // from XBATs // However, all BATs can contain 128/1024 blocks size += (numBATs * bigBlockSize.GetBATEntriesPerBlock()); // So far we've been in sector counts, turn into bytes return size * bigBlockSize.GetBigBlockSize(); }
public static int CalculateXBATStorageRequirements(POIFSBigBlockSize bigBlockSize, int entryCount) { int _entries_per_xbat_block = bigBlockSize.GetXBATEntriesPerBlock(); return (entryCount + _entries_per_xbat_block - 1) / _entries_per_xbat_block; }
public POIFSDocument(string name, SmallDocumentBlock[] blocks, int length) { _size = length; if(blocks.Length == 0) _bigBigBlockSize = POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS; else _bigBigBlockSize = blocks[0].BigBlockSize; _big_store = new BigBlockStore(_bigBigBlockSize, EMPTY_BIG_BLOCK_ARRAY); _property = new DocumentProperty(name, _size); _small_store = new SmallBlockStore(_bigBigBlockSize, blocks); _property.Document = this; }
public POIFSDocument(string name, POIFSBigBlockSize bigBlockSize, ListManagedBlock[] blocks, int length) { _size = length; _bigBigBlockSize = bigBlockSize; _property = new DocumentProperty(name, _size); _property.Document = this; if (Property.IsSmall(_size)) { _big_store = new BigBlockStore(bigBlockSize, EMPTY_BIG_BLOCK_ARRAY); _small_store = new SmallBlockStore(bigBlockSize, ConvertRawBlocksToSmallBlocks(blocks)); } else { _big_store = new BigBlockStore(bigBlockSize, ConvertRawBlocksToBigBlocks(blocks)); _small_store = new SmallBlockStore(bigBlockSize, EMPTY_SMALL_BLOCK_ARRAY); } }
public void PrivateHeaderBlock(byte[] data) { _data = data; long signature = LittleEndian.GetLong(_data, _signature_offset); if (signature != _signature) { byte[] OOXML_FILE_HEADER = POIFSConstants.OOXML_FILE_HEADER; if (_data[0] == OOXML_FILE_HEADER[0] && _data[1] == OOXML_FILE_HEADER[1] && _data[2] == OOXML_FILE_HEADER[2] && _data[3] == OOXML_FILE_HEADER[3]) { throw new OfficeXmlFileException("The supplied data appears to be in the Office 2007+ XML. You are calling the part of POI that deals with OLE2 Office Documents. You need to call a different part of POI to process this data (eg XSSF instead of HSSF)"); } if ((signature & unchecked((long)0xFF8FFFFFFFFFFFFFL)) == 0x0010000200040009L) { throw new ArgumentException("The supplied data appears to be in BIFF2 format. " + "POI only supports BIFF8 format"); } throw new IOException("Invalid header signature; read " + LongToHex(signature) + ", expected " + LongToHex(_signature)); } if (_data[30] == 12) { bigBlockSize = POIFSConstants.LARGER_BIG_BLOCK_SIZE_DETAILS; } else if (_data[30] == 9) { bigBlockSize = POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS; } else { throw new IOException("Unsupported blocksize (2^" + _data[30] + "). Expected 2^9 or 2^12."); } // Setup the fields to read and write the counts and starts _bat_count = new IntegerField(HeaderBlockConstants._bat_count_offset, _data).Value; _property_start = new IntegerField(HeaderBlockConstants._property_start_offset, _data).Value; _sbat_start = new IntegerField(HeaderBlockConstants._sbat_start_offset, _data).Value; _sbat_count = new IntegerField(HeaderBlockConstants._sbat_block_count_offset, _data).Value; _xbat_start = new IntegerField(HeaderBlockConstants._xbat_start_offset, _data).Value; _xbat_count = new IntegerField(HeaderBlockConstants._xbat_count_offset, _data).Value; }
/// <summary> /// Create an array of BATBlocks from an array of int block /// allocation table entries /// </summary> /// <param name="entries">the array of int entries</param> /// <returns>the newly created array of BATBlocks</returns> public static BATBlock[] CreateBATBlocks(POIFSBigBlockSize bigBlockSize, int[] entries) { int block_count = CalculateStorageRequirements(entries.Length); BATBlock[] blocks = new BATBlock[block_count]; int index = 0; int remaining = entries.Length; for (int j = 0; j < entries.Length; j += _entries_per_block) { blocks[index++] = new BATBlock(bigBlockSize, entries, j, (remaining > _entries_per_block) ? j + _entries_per_block : entries.Length); remaining -= _entries_per_block; } return blocks; }
private void SetXBATChain(POIFSBigBlockSize bigBlockSize, int chainIndex) { int _entries_per_xbat_block = bigBlockSize.GetXBATEntriesPerBlock(); _values[_entries_per_xbat_block] = chainIndex; }
public HeaderBlock(POIFSBigBlockSize bigBlockSize) { this.bigBlockSize = bigBlockSize; _data = new byte[POIFSConstants.SMALLER_BIG_BLOCK_SIZE]; //fill the array. for (int i = 0; i < _data.Length; i++) _data[i] = _default_value; new LongField(_signature_offset, _signature, _data); new IntegerField(0x08, 0, _data); new IntegerField(0x0c, 0, _data); new IntegerField(0x10, 0, _data); new IntegerField(0x14, 0, _data); new ShortField((int)0x18, (short)0x3b, ref _data); new ShortField((int)0x1a, (short)0x3, ref _data); new ShortField((int)0x1c, (short)-2, ref _data); new ShortField(0x1e, bigBlockSize.GetHeaderValue(), ref _data); new IntegerField(0x20, 0x6, _data); new IntegerField(0x24, 0, _data); new IntegerField(0x28, 0, _data); new IntegerField(0x34, 0, _data); new IntegerField(0x38, 0x1000, _data); _bat_count = 0; _sbat_count = 0; _xbat_count = 0; _property_start = POIFSConstants.END_OF_CHAIN; _sbat_start = POIFSConstants.END_OF_CHAIN; _xbat_start = POIFSConstants.END_OF_CHAIN; }