/// <summary> /// walk the entries from a specified point and return the /// associated blocks. The associated blocks are Removed from the block list /// </summary> /// <param name="startBlock">the first block in the chain</param> /// <param name="blockList">the raw data block list</param> /// <returns>array of ListManagedBlocks, in their correct order</returns> public ListManagedBlock[] FetchBlocks(int startBlock, int headerPropertiesStartBlock, BlockList blockList) { IList blocks = new ArrayList(); int currentBlock = startBlock; bool firstPass = true; while (currentBlock != POIFSConstants.END_OF_CHAIN) { try { blocks.Add(blockList.Remove(currentBlock)); currentBlock = _entries[currentBlock]; firstPass = false; } catch (Exception) { if (currentBlock == headerPropertiesStartBlock) { // Special case where things are in the wrong order Console.Error.WriteLine("Warning, header block comes after data blocks in POIFS block listing"); currentBlock = POIFSConstants.END_OF_CHAIN; } else if (currentBlock == 0 && firstPass) { // Special case where the termination isn't done right // on an empty set Console.Error.WriteLine("Warning, incorrectly terminated empty data blocks in POIFS block listing (should end at -2, ended at 0)"); currentBlock = POIFSConstants.END_OF_CHAIN; } else { // Ripple up throw; } } } ListManagedBlock[] array = new ListManagedBlock[blocks.Count]; blocks.CopyTo(array, 0); return(array); }
/// <summary> /// walk the entries from a specified point and return the /// associated blocks. The associated blocks are Removed from the block list /// </summary> /// <param name="startBlock">the first block in the chain</param> /// <param name="headerPropertiesStartBlock"></param> /// <param name="blockList">the raw data block list</param> /// <returns>array of ListManagedBlocks, in their correct order</returns> public ListManagedBlock[] FetchBlocks(int startBlock, int headerPropertiesStartBlock, BlockList blockList) { List <ListManagedBlock> blocks = new List <ListManagedBlock>(); int currentBlock = startBlock; bool firstPass = true; ListManagedBlock dataBlock = null; while (currentBlock != POIFSConstants.END_OF_CHAIN) { try { dataBlock = blockList.Remove(currentBlock); blocks.Add(dataBlock); currentBlock = _entries[currentBlock]; firstPass = false; } catch (Exception) { if (currentBlock == headerPropertiesStartBlock) { // Special case where things are in the wrong order _logger.Log(POILogger.WARN, "Warning, header block comes after data blocks in POIFS block listing"); currentBlock = POIFSConstants.END_OF_CHAIN; } else if (currentBlock == 0 && firstPass) { // Special case where the termination isn't done right // on an empty set _logger.Log(POILogger.WARN, "Warning, incorrectly terminated empty data blocks in POIFS block listing (should end at -2, ended at 0)"); currentBlock = POIFSConstants.END_OF_CHAIN; } else { // Ripple up throw; } } } ListManagedBlock[] array = blocks.ToArray(); return(array); }
/// <summary> remove a specific tag </summary> public bool Remove(object tag) { List <GLObjectsWithLabels> toremove = new List <GLObjectsWithLabels>(); if (TagsToBlocks.TryGetValue(tag, out List <GLObjectsWithLabels.BlockRef> blocklist)) { if (blocklist != null) // tag may be reserved, not set, so just remove tag. if set, remove blocklist { foreach (var b in blocklist) { b.owl.Remove(b.blockindex); // in owl, remove block if (b.owl.Emptied) // if block has gone emptied, add to remove list { toremove.Add(b.owl); } Objects -= b.count; } foreach (var removeit in toremove) { robjects.Remove(removeit.ObjectRenderer); // remove renders robjects.Remove(removeit.TextRenderer); removeit.Dispose(); // then dispose set.Remove(removeit); } BlockList.Remove(blocklist); } TagsToBlocks.Remove(tag); return(true); } else { return(false); } }
/// <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="bigBlockSizse">the poifs bigBlockSize</param> /// <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); }
/// <summary> /// walk the entries from a specified point and return the /// associated blocks. The associated blocks are Removed from the block list /// </summary> /// <param name="startBlock">the first block in the chain</param> /// <param name="headerPropertiesStartBlock"></param> /// <param name="blockList">the raw data block list</param> /// <returns>array of ListManagedBlocks, in their correct order</returns> public ListManagedBlock[] FetchBlocks(int startBlock, int headerPropertiesStartBlock, BlockList blockList) { List<ListManagedBlock> blocks = new List<ListManagedBlock>(); int currentBlock = startBlock; bool firstPass = true; ListManagedBlock dataBlock = null; while (currentBlock != POIFSConstants.END_OF_CHAIN) { try { dataBlock = blockList.Remove(currentBlock); blocks.Add(dataBlock); currentBlock = _entries[currentBlock]; firstPass = false; } catch(Exception) { if (currentBlock == headerPropertiesStartBlock) { // Special case where things are in the wrong order _logger.Log(POILogger.WARN, "Warning, header block comes after data blocks in POIFS block listing"); currentBlock = POIFSConstants.END_OF_CHAIN; } else if (currentBlock == 0 && firstPass) { // Special case where the termination isn't done right // on an empty set _logger.Log(POILogger.WARN, "Warning, incorrectly terminated empty data blocks in POIFS block listing (should end at -2, ended at 0)"); currentBlock = POIFSConstants.END_OF_CHAIN; } else { // Ripple up throw; } } } ListManagedBlock[] array = blocks.ToArray(); return (array); }
/// <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(int block_count, int[] block_array, int xbat_count, int xbat_index, BlockList raw_block_list) : this() { if (block_count <= 0) { throw new IOException( "Illegal block count; minimum count is 1, got " + block_count + " instead"); } // acquire raw data blocks containing the BAT block data 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++) { blocks[block_index] = (RawDataBlock)raw_block_list .Remove(block_array[block_index]); } 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; 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 += LittleEndianConstants.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); }
/// <summary> /// walk the entries from a specified point and return the /// associated blocks. The associated blocks are Removed from the block list /// </summary> /// <param name="startBlock">the first block in the chain</param> /// <param name="blockList">the raw data block list</param> /// <returns>array of ListManagedBlocks, in their correct order</returns> public ListManagedBlock[] FetchBlocks(int startBlock, BlockList blockList) { IList blocks = new ArrayList(); int currentBlock = startBlock; while (currentBlock != POIFSConstants.END_OF_CHAIN) { blocks.Add(blockList.Remove(currentBlock)); currentBlock = _entries[currentBlock]; } ListManagedBlock[] array = new ListManagedBlock[blocks.Count]; blocks.CopyTo(array, 0); return (array); }
public virtual void TestRemoveRejectsBadIndexes() { BlockList<int> list = new BlockList<int>(4); list.AddItem(Sharpen.Extensions.ValueOf(41)); try { list.Remove(-1); } catch (IndexOutOfRangeException badIndex) { NUnit.Framework.Assert.AreEqual((-1).ToString(), badIndex.Message); } try { list.Remove(4); } catch (IndexOutOfRangeException badIndex) { NUnit.Framework.Assert.AreEqual(4.ToString(), badIndex.Message); } }
public virtual void TestAddRemoveAdd() { BlockList<int> list = new BlockList<int>(); for (int i = 0; i < BlockList<int>.BLOCK_SIZE + 1; i++) { list.AddItem(Sharpen.Extensions.ValueOf(i)); } NUnit.Framework.Assert.AreEqual(Sharpen.Extensions.ValueOf(BlockList<int>.BLOCK_SIZE), list.Remove(list.Count - 1)); NUnit.Framework.Assert.AreEqual(Sharpen.Extensions.ValueOf(BlockList<int>.BLOCK_SIZE - 1), list.Remove(list.Count - 1)); NUnit.Framework.Assert.IsTrue(list.AddItem(Sharpen.Extensions.ValueOf(1))); NUnit.Framework.Assert.AreEqual(Sharpen.Extensions.ValueOf(1), list[list.Count - 1]); }
public virtual void TestRemoveSlowPath() { BlockList<string> list = new BlockList<string>(4); string fooStr = "foo"; string barStr = "bar"; string foobarStr = "foobar"; list.AddItem(fooStr); list.AddItem(barStr); list.AddItem(foobarStr); NUnit.Framework.Assert.AreSame(barStr, list.Remove(1)); NUnit.Framework.Assert.AreEqual(2, list.Count); NUnit.Framework.Assert.AreSame(fooStr, list[0]); NUnit.Framework.Assert.AreSame(foobarStr, list[1]); NUnit.Framework.Assert.AreSame(fooStr, list.Remove(0)); NUnit.Framework.Assert.AreEqual(1, list.Count); NUnit.Framework.Assert.AreSame(foobarStr, list[0]); NUnit.Framework.Assert.AreSame(foobarStr, list.Remove(0)); NUnit.Framework.Assert.AreEqual(0, list.Count); }
/// <summary> /// walk the entries from a specified point and return the /// associated blocks. The associated blocks are Removed from the block list /// </summary> /// <param name="startBlock">the first block in the chain</param> /// <param name="blockList">the raw data block list</param> /// <returns>array of ListManagedBlocks, in their correct order</returns> public ListManagedBlock[] FetchBlocks(int startBlock, int headerPropertiesStartBlock, BlockList blockList) { IList blocks = new ArrayList(); int currentBlock = startBlock; bool firstPass = true; while (currentBlock != POIFSConstants.END_OF_CHAIN) { try { blocks.Add(blockList.Remove(currentBlock)); currentBlock = _entries[currentBlock]; firstPass = false; } catch(Exception) { if (currentBlock == headerPropertiesStartBlock) { // Special case where things are in the wrong order Console.Error.WriteLine("Warning, header block comes after data blocks in POIFS block listing"); currentBlock = POIFSConstants.END_OF_CHAIN; } else if (currentBlock == 0 && firstPass) { // Special case where the termination isn't done right // on an empty set Console.Error.WriteLine("Warning, incorrectly terminated empty data blocks in POIFS block listing (should end at -2, ended at 0)"); currentBlock = POIFSConstants.END_OF_CHAIN; } else { // Ripple up throw; } } } ListManagedBlock[] array = new ListManagedBlock[blocks.Count]; blocks.CopyTo(array, 0); return (array); }