Exemple #1
0
        /// <summary>
        /// Reads data from the stream.
        /// </summary>
        /// <param name="buffer">The buffer to fill.</param>
        /// <param name="offset">The buffer offset to start from.</param>
        /// <param name="count">The number of bytes to read.</param>
        /// <returns>The number of bytes read.</returns>
        public override int Read(byte[] buffer, int offset, int count)
        {
            int numRead;

            if (_diffStream == null)
            {
                _baseStream.Position = _position;
                numRead = _baseStream.Read(buffer, offset, count);
            }
            else
            {
                if (_position > _diffStream.Length)
                {
                    throw new IOException("Attempt to read beyond end of file");
                }

                int toRead = (int)Math.Min(count, _diffStream.Length - _position);

                // If the read is within the base stream's range, then touch it first to get the
                // (potentially) stale data.
                if (_position < _baseStream.Length)
                {
                    int baseToRead = (int)Math.Min(toRead, _baseStream.Length - _position);
                    _baseStream.Position = _position;

                    int totalBaseRead = 0;
                    while (totalBaseRead < baseToRead)
                    {
                        totalBaseRead += _baseStream.Read(buffer, offset + totalBaseRead, baseToRead - totalBaseRead);
                    }
                }

                // Now overlay any data from the overlay stream (if any)
                IEnumerable <StreamExtent> overlayExtents = StreamExtent.Intersect(_diffExtents,
                                                                                   new StreamExtent(_position, toRead));
                foreach (StreamExtent extent in overlayExtents)
                {
                    _diffStream.Position = extent.Start;
                    int overlayNumRead = 0;
                    while (overlayNumRead < extent.Length)
                    {
                        overlayNumRead += _diffStream.Read(
                            buffer,
                            (int)(offset + (extent.Start - _position) + overlayNumRead),
                            (int)(extent.Length - overlayNumRead));
                    }
                }

                numRead = toRead;
            }

            _position += numRead;

            return(numRead);
        }
        public void TestIntersect1()
        {
            StreamExtent[] s1 = new StreamExtent[] {
                new StreamExtent(0, 4)
            };
            StreamExtent[] s2 = new StreamExtent[] {
                new StreamExtent(4, 8)
            };
            StreamExtent[] r = new StreamExtent[] { };

            Compare(r, StreamExtent.Intersect(s1, s2));
        }
        public void TestUnion4()
        {
            StreamExtent[] s1 = new StreamExtent[] {
                new StreamExtent(0, 4),
                new StreamExtent(4, 4)
            };
            StreamExtent[] r = new StreamExtent[] {
                new StreamExtent(0, 8)
            };

            Compare(r, StreamExtent.Union(s1));
        }
        public void TestUnion3()
        {
            StreamExtent[] s1 = new StreamExtent[] {
                new StreamExtent(0, 4)
            };
            StreamExtent[] s2 = new StreamExtent[] {
                new StreamExtent(2, 8)
            };
            StreamExtent[] r = new StreamExtent[] {
                new StreamExtent(0, 10)
            };

            Compare(r, StreamExtent.Union(s1, s2));
        }
        public void TestIntersect5()
        {
            StreamExtent[] s1 = new StreamExtent[] {
                new StreamExtent(0, 10)
            };
            StreamExtent[] s2 = new StreamExtent[] {
                new StreamExtent(3, 5)
            };
            StreamExtent[] r = new StreamExtent[] {
                new StreamExtent(3, 5)
            };

            Compare(r, StreamExtent.Intersect(s1, s2));
        }
        public void TestIntersect4()
        {
            StreamExtent[] s1 = new StreamExtent[] {
                new StreamExtent(0, 4)
            };
            StreamExtent[] s2 = new StreamExtent[] {
                new StreamExtent(3, 8)
            };
            StreamExtent[] s3 = new StreamExtent[] {
                new StreamExtent(10, 10)
            };
            StreamExtent[] r = new StreamExtent[] {
            };

            Compare(r, StreamExtent.Intersect(s1, s2, s3));
        }
        public void TestIntersect3()
        {
            StreamExtent[] s1 = new StreamExtent[] {
                new StreamExtent(0, 4),
                new StreamExtent(10, 10)
            };
            StreamExtent[] s2 = new StreamExtent[] {
                new StreamExtent(3, 8)
            };
            StreamExtent[] r = new StreamExtent[] {
                new StreamExtent(3, 1),
                new StreamExtent(10, 1)
            };

            Compare(r, StreamExtent.Intersect(s1, s2));
        }
        /// <summary>
        /// Writes data to the stream at the current location.
        /// </summary>
        /// <param name="buffer">The data to write</param>
        /// <param name="offset">The first byte to write from buffer</param>
        /// <param name="count">The number of bytes to write</param>
        public override void Write(byte[] buffer, int offset, int count)
        {
            CheckFrozen();

            if (_diffStream != null)
            {
                _diffStream.Position = _position;
                _diffStream.Write(buffer, offset, count);

                // Beware of Linq's delayed model - force execution now by placing into a list.
                // Without this, large execution chains can build up (v. slow) and potential for stack overflow.
                _diffExtents = new List <StreamExtent>(StreamExtent.Union(_diffExtents, new StreamExtent(_position, count)));

                _position += count;
            }
            else
            {
                _baseStream.Position = _position;
                _baseStream.Write(buffer, offset, count);
                _position += count;
            }
        }
        public void TestBlocks()
        {
            StreamExtent[] s = new StreamExtent[] {
                new StreamExtent(0, 8),
                new StreamExtent(11, 4)
            };

            List <Range <long, long> > ranges = new List <Range <long, long> >(StreamExtent.Blocks(s, 10));

            Assert.AreEqual(1, ranges.Count);
            Assert.AreEqual(0, ranges[0].Offset);
            Assert.AreEqual(2, ranges[0].Count);

            s = new StreamExtent[] {
                new StreamExtent(0, 8),
                new StreamExtent(9, 8)
            };

            ranges = new List <Range <long, long> >(StreamExtent.Blocks(s, 10));

            Assert.AreEqual(1, ranges.Count);
            Assert.AreEqual(0, ranges[0].Offset);
            Assert.AreEqual(2, ranges[0].Count);

            s = new StreamExtent[] {
                new StreamExtent(3, 4),
                new StreamExtent(19, 4),
                new StreamExtent(44, 4)
            };

            ranges = new List <Range <long, long> >(StreamExtent.Blocks(s, 10));

            Assert.AreEqual(2, ranges.Count);
            Assert.AreEqual(0, ranges[0].Offset);
            Assert.AreEqual(3, ranges[0].Count);
            Assert.AreEqual(4, ranges[1].Offset);
            Assert.AreEqual(1, ranges[1].Count);
        }
        public void TestBlockCount()
        {
            StreamExtent[] s = new StreamExtent[] {
                new StreamExtent(0, 8),
                new StreamExtent(11, 4)
            };

            Assert.AreEqual(2, StreamExtent.BlockCount(s, 10));

            s = new StreamExtent[] {
                new StreamExtent(0, 8),
                new StreamExtent(9, 8)
            };

            Assert.AreEqual(2, StreamExtent.BlockCount(s, 10));

            s = new StreamExtent[] {
                new StreamExtent(3, 4),
                new StreamExtent(19, 4),
                new StreamExtent(44, 4)
            };

            Assert.AreEqual(4, StreamExtent.BlockCount(s, 10));
        }
Exemple #11
0
 /// <summary>
 /// Gets the parts of a stream that are stored, within a specified range.
 /// </summary>
 /// <param name="start">The offset of the first byte of interest.</param>
 /// <param name="count">The number of bytes of interest.</param>
 /// <returns>An enumeration of stream extents, indicating stored bytes.</returns>
 public virtual IEnumerable <StreamExtent> GetExtentsInRange(long start, long count)
 {
     return(StreamExtent.Intersect(Extents, new[] { new StreamExtent(start, count) }));
 }
        public void TestUnion5()
        {
            StreamExtent[] r = new StreamExtent[] { };

            Compare(r, StreamExtent.Union());
        }