Exemple #1
0
        /// <summary>
        /// Appends a block to the end of the underlying BlockArray.
        /// </summary>
        /// <param name="block">The block to append.</param>
        /// <remarks>
        /// <para>
        /// The underyling block array's SetExactSize() method will be
        /// called before appending the block.  The stream position will
        /// be set to the end of the stream before the method returns.
        /// </para>
        /// <para>
        /// This method is a performance improvement over writing the
        /// a buffer to the stream via one of the write methods.
        /// </para>
        /// </remarks>
        public void Append(Block block)
        {
            blocks.SetExactSize(length);
            blocks.Append(block);

            length += block.Length;
            pos     = length;
        }
Exemple #2
0
        /// <summary>
        /// Extracts a range of bytes from the array into newly
        /// created block array.
        /// </summary>
        /// <param name="index">Logical index of the first byte.</param>
        /// <param name="length">Number of bytes to extract.</param>
        /// <returns>A new block array referencing the bytes.</returns>
        /// <remarks>
        /// <note>
        /// Although this method does create a new BlockArray
        /// and Block objects, it does not copy the underlying buffers.
        /// Instead, it adjusts the new Block objects to reference the
        /// requested portions of the original underlying buffers.
        /// </note>
        /// </remarks>
        public BlockArray Extract(int index, int length)
        {
            BlockArray extracted = new BlockArray();
            int        cbRemain;
            int        blockIndex;
            int        pos;
            int        cb;
            Block      srcBlock;
            Block      dstBlock;

            if (length <= 0)
            {
                return(extracted);
            }

            if (index + length > size)
            {
                throw new IndexOutOfRangeException();
            }

            if (index == 0 && length == size)
            {
                // Return a clone of this instance.

                for (int i = 0; i < list.Count; i++)
                {
                    srcBlock = list[i];
                    extracted.Append(new Block(srcBlock.Buffer, srcBlock.Offset, srcBlock.Length));
                }

                return(extracted);
            }

            CalcPos(index);

            cbRemain   = length;
            blockIndex = lastBlockIndex;
            srcBlock   = list[blockIndex];
            pos        = lastBlockPos + srcBlock.Offset;

            while (true)
            {
                cb = srcBlock.Length + srcBlock.Offset - pos;
                if (cb > cbRemain)
                {
                    cb = cbRemain;
                }

                dstBlock = new Block(srcBlock.Buffer, pos, cb);
                extracted.Append(dstBlock);

                cbRemain -= cb;
                if (cbRemain <= 0)
                {
                    break;
                }

                srcBlock = list[++blockIndex];
                pos      = srcBlock.Offset;
            }

            return(extracted);
        }