예제 #1
0
        public override int Read(byte[] buffer, int offset, int count)
        {
            if (_position >= _length)
            {
                return(0);
            }

            int totalRead = 0;

            while (totalRead < count && _position < _length)
            {
                // If current region is outside the area of interest, clean it up
                if (_currentExtent != null && (_position < _currentExtent.Start || _position >= _currentExtent.Start + _currentExtent.Length))
                {
                    _currentExtent.DisposeReadState();
                    _currentExtent = null;
                }

                // If we need to find a new region, look for it
                if (_currentExtent == null)
                {
                    using (SearchExtent searchExtent = new SearchExtent(_position))
                    {
                        int idx = _extents.BinarySearch(searchExtent, new ExtentRangeComparer());
                        if (idx >= 0)
                        {
                            BuilderExtent extent = _extents[idx];
                            extent.PrepareForRead();
                            _currentExtent = extent;
                        }
                    }
                }

                int numRead = 0;

                // If the block is outside any known extent, defer to base stream.
                if (_currentExtent == null)
                {
                    _baseStream.Position = _position;
                    BuilderExtent nextExtent = FindNext(_position);
                    if (nextExtent != null)
                    {
                        numRead = _baseStream.Read(buffer, offset + totalRead, (int)Math.Min(count - totalRead, nextExtent.Start - _position));
                    }
                    else
                    {
                        numRead = _baseStream.Read(buffer, offset + totalRead, count - totalRead);
                    }
                }
                else
                {
                    numRead = _currentExtent.Read(_position, buffer, offset + totalRead, count - totalRead);
                }

                _position += numRead;
                totalRead += numRead;
            }

            return(totalRead);
        }
예제 #2
0
 protected override void Dispose(bool disposing)
 {
     try
     {
         if (disposing)
         {
             if (_currentExtent != null)
             {
                 _currentExtent.DisposeReadState();
                 _currentExtent = null;
             }
             if (_baseStream != null)
             {
                 _baseStream.Dispose();
                 _baseStream = null;
             }
         }
     }
     finally
     {
         base.Dispose(disposing);
     }
 }