/// <summary> /// For a given number of BAT blocks, calculate how many XBAT /// blocks will be needed /// </summary> /// <param name="blockCount">number of BAT blocks</param> /// <returns>number of XBAT blocks needed</returns> public static int CalculateXBATStorageRequirements(int blockCount) { return((blockCount > HeaderBlockConstants._max_bats_in_header) ? BATBlock.CalculateXBATStorageRequirements(blockCount - HeaderBlockConstants._max_bats_in_header) : 0); }
/// <summary> /// Create the BATBlocks we need /// </summary> /// <returns>start block index of BAT blocks</returns> public int CreateBlocks() { int xbat_blocks = 0; int bat_blocks = 0; while (true) { int calculated_bat_blocks = BATBlock.CalculateStorageRequirements(bat_blocks + xbat_blocks + _entries.Count); int calculated_xbat_blocks = HeaderBlockWriter .CalculateXBATStorageRequirements(calculated_bat_blocks); if ((bat_blocks == calculated_bat_blocks) && (xbat_blocks == calculated_xbat_blocks)) { // stable ... we're OK break; } else { bat_blocks = calculated_bat_blocks; xbat_blocks = calculated_xbat_blocks; } } int startBlock = AllocateSpace(bat_blocks); AllocateSpace(xbat_blocks); SimpleCreateBlocks(); return(startBlock); }
/// <summary> /// Create an array of XBATBlocks from an array of int block /// allocation table entries /// </summary> /// <param name="bigBlockSize"></param> /// <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); }
/// <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(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(entries, j, (remaining > _entries_per_block) ? j + _entries_per_block : entries.Length); remaining -= _entries_per_block; } return blocks; }
/** * Create a single BATBlock from the byte buffer, which must hold at least * one big block of data to be read. */ public static BATBlock CreateBATBlock(POIFSBigBlockSize bigBlockSize, BinaryReader data) { // Create an empty block BATBlock block = new BATBlock(bigBlockSize); // Fill it byte[] buffer = new byte[LittleEndianConsts.INT_SIZE]; for (int i = 0; i < block._values.Length; i++) { data.Read(buffer, 0, buffer.Length); block._values[i] = LittleEndian.GetInt(buffer); } block.RecomputeFree(); // All done return(block); }
/// <summary> /// Create an array of BATBlocks from an array of int block /// allocation table entries /// </summary> /// <param name="bigBlockSize">the poifs bigBlockSize</param> /// <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); }
/// <summary> /// Set BAT block parameters. Assumes that all BAT blocks are /// contiguous. Will construct XBAT blocks if necessary and return /// the array of newly constructed XBAT blocks. /// </summary> /// <param name="blockCount">count of BAT blocks</param> /// <param name="startBlock">index of first BAT block</param> /// <returns>array of XBAT blocks; may be zero Length, will not be /// null</returns> public BATBlock[] SetBATBlocks(int blockCount, int startBlock) { BATBlock[] rvalue; POIFSBigBlockSize bigBlockSize = _header_block.BigBlockSize; _header_block.BATCount = blockCount; int limit = Math.Min(blockCount, _max_bats_in_header); int[] bat_blocks = new int[limit]; for (int j = 0; j < limit; j++) { bat_blocks[j] = startBlock + j; } _header_block.BATArray = bat_blocks; if (blockCount > _max_bats_in_header) { int excess_blocks = blockCount - _max_bats_in_header; int[] excess_block_array = new int[excess_blocks]; for (int j = 0; j < excess_blocks; j++) { excess_block_array[j] = startBlock + j + _max_bats_in_header; } rvalue = BATBlock.CreateXBATBlocks(bigBlockSize, excess_block_array, startBlock + blockCount); _header_block.XBATStart = startBlock + blockCount; } else { rvalue = BATBlock.CreateXBATBlocks(bigBlockSize, new int[0], 0); _header_block.XBATStart = POIFSConstants.END_OF_CHAIN; } _header_block.XBATCount = rvalue.Length; 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); }
/// <summary> /// Set BAT block parameters. Assumes that all BAT blocks are /// contiguous. Will construct XBAT blocks if necessary and return /// the array of newly constructed XBAT blocks. /// </summary> /// <param name="blockCount">count of BAT blocks</param> /// <param name="startBlock">index of first BAT block</param> /// <returns>array of XBAT blocks; may be zero Length, will not be /// null</returns> public BATBlock [] SetBATBlocks(int blockCount, int startBlock) { BATBlock[] rvalue; _bat_count.Set(blockCount, _data); int limit = Math.Min(blockCount, HeaderBlockConstants._max_bats_in_header); int offset = HeaderBlockConstants._bat_array_offset; for (int j = 0; j < limit; j++) { new IntegerField(offset, startBlock + j, _data); offset += LittleEndianConstants.INT_SIZE; } if (blockCount > HeaderBlockConstants._max_bats_in_header) { int excess_blocks = blockCount - HeaderBlockConstants._max_bats_in_header; int[] excess_block_array = new int[excess_blocks]; for (int j = 0; j < excess_blocks; j++) { excess_block_array[j] = startBlock + j + HeaderBlockConstants._max_bats_in_header; } rvalue = BATBlock.CreateXBATBlocks(excess_block_array, startBlock + blockCount); _xbat_start.Set(startBlock + blockCount, _data); } else { rvalue = BATBlock.CreateXBATBlocks(new int[0], 0); _xbat_start.Set(POIFSConstants.END_OF_CHAIN, _data); } _xbat_count.Set(rvalue.Length, _data); 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; }
//public static void WriteBlock(BATBlock bat, byte[] block) public static void WriteBlock(BATBlock bat, ByteBuffer block) { bat.WriteData(block); }
private void VerifyContents(BATBlock[] blocks, int entries) { byte[] expected = new byte[512 * blocks.Length]; for (int i = 0; i < expected.Length; i++) { expected[i] = (byte)0xFF; } int offset = 0; for (int j = 0; j < entries; j++) { expected[offset++] = (byte)j; expected[offset++] = 0; expected[offset++] = 0; expected[offset++] = 0; } MemoryStream stream = new MemoryStream(512 * blocks.Length); for (int j = 0; j < blocks.Length; j++) { blocks[j].WriteBlocks(stream); } byte[] actual = stream.ToArray(); Assert.AreEqual(expected.Length, actual.Length); for (int j = 0; j < expected.Length; j++) { Assert.AreEqual(expected[j], actual[j]); } }
/// <summary> /// For a given number of BAT blocks, calculate how many XBAT /// blocks will be needed /// </summary> /// <param name="bigBlockSize"></param> /// <param name="blockCount">number of BAT blocks</param> /// <returns>number of XBAT blocks needed</returns> public static int CalculateXBATStorageRequirements(POIFSBigBlockSize bigBlockSize, int blockCount) { return((blockCount > _max_bats_in_header) ? BATBlock.CalculateXBATStorageRequirements(bigBlockSize, blockCount - _max_bats_in_header) : 0); }
private void verifyXBATContents(BATBlock[] blocks, int entries, int start_block) { byte[] expected = new byte[512 * blocks.Length]; for (int i = 0; i < expected.Length; i++) { expected[i] = (byte)0xFF; } int offset = 0; for (int j = 0; j < entries; j++) { if ((j % 127) == 0) { if (j != 0) { offset += 4; } } expected[offset++] = (byte)j; expected[offset++] = 0; expected[offset++] = 0; expected[offset++] = 0; } for (int j = 0; j < (blocks.Length - 1); j++) { offset = 508 + (j * 512); expected[offset++] = (byte)(start_block + j + 1); expected[offset++] = 0; expected[offset++] = 0; expected[offset++] = 0; } offset = (blocks.Length * 512) - 4; expected[offset++] = unchecked((byte)-2); expected[offset++] = unchecked((byte)-1); expected[offset++] = unchecked((byte)-1); expected[offset++] = unchecked((byte)-1); MemoryStream stream = new MemoryStream(512 * blocks.Length); for (int j = 0; j < blocks.Length; j++) { blocks[j].WriteBlocks(stream); } byte[] actual = stream.ToArray(); Assert.AreEqual(expected.Length, actual.Length); for (int j = 0; j < expected.Length; j++) { Assert.AreEqual(expected[j], actual[j], "offset " + j); } }
public BATBlockAndIndex(int index, BATBlock block) { this.index = index; this.block = block; }
/// <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; }
/// <summary> /// create the BATBlocks /// </summary> internal void SimpleCreateBlocks() { _blocks = BATBlock.CreateBATBlocks(_entries.ToArray()); }
/** * Create a single BATBlock from the byte buffer, which must hold at least * one big block of data to be read. */ public static BATBlock CreateBATBlock(POIFSBigBlockSize bigBlockSize, BinaryReader data) { // Create an empty block BATBlock block = new BATBlock(bigBlockSize); // Fill it byte[] buffer = new byte[LittleEndianConsts.INT_SIZE]; for (int i = 0; i < block._values.Length; i++) { data.Read(buffer,0,buffer.Length); block._values[i] = LittleEndian.GetInt(buffer); } block.RecomputeFree(); // All done return block; }
///** // * 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; }