/// <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>
        /// 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>
        /// 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);
        }
Beispiel #10
0
		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);
			}
		}
Beispiel #11
0
		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]);
		}
Beispiel #12
0
		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);
        }