/// <summary>
        /// Initializes a new instance of the BlockCacheStream class.
        /// </summary>
        /// <param name="toWrap">The stream to wrap.</param>
        /// <param name="ownership">Whether to assume ownership of <c>toWrap</c>.</param>
        /// <param name="settings">The cache settings.</param>
        public BlockCacheStream(SparseStream toWrap, Ownership ownership, BlockCacheSettings settings)
        {
            if (!toWrap.CanRead)
            {
                throw new ArgumentException("The wrapped stream does not support reading", "toWrap");
            }

            if (!toWrap.CanSeek)
            {
                throw new ArgumentException("The wrapped stream does not support seeking", "toWrap");
            }

            _wrappedStream = toWrap;
            _ownWrapped = ownership;
            _settings = new BlockCacheSettings(settings);

            if (_settings.OptimumReadSize % _settings.BlockSize != 0)
            {
                throw new ArgumentException("Invalid settings, OptimumReadSize must be a multiple of BlockSize", "settings");
            }

            _readBuffer = new byte[_settings.OptimumReadSize];
            _blocksInReadBuffer = _settings.OptimumReadSize / _settings.BlockSize;

            int totalBlocks = (int)(_settings.ReadCacheSize / _settings.BlockSize);

            _cache = new BlockCache<Block>(_settings.BlockSize, totalBlocks);
            _stats = new BlockCacheStatistics();
            _stats.FreeReadBlocks = totalBlocks;
        }
 public override void Dispose()
 {
     if (_stream != null && _ownership == Ownership.Dispose)
     {
         _stream.Dispose();
         _stream = null;
     }
 }
Beispiel #3
0
 /// <summary>
 /// Disposes of this instance.
 /// </summary>
 public void Dispose()
 {
     if (_ownership == Ownership.Dispose)
     {
         if (_stream != null)
         {
             _stream.Dispose();
             _stream = null;
         }
     }
 }
        /// <summary>
        /// Creates a new instance, wrapping an existing stream.
        /// </summary>
        /// <param name="toWrap">The stream to wrap</param>
        /// <param name="ownership">Whether to transfer ownership of <c>toWrap</c> to the new instance</param>
        /// <remarks>Do not directly modify <c>toWrap</c> after wrapping it, unless the thread-safe views
        /// will no longer be used.</remarks>
        public ThreadSafeStream(SparseStream toWrap, Ownership ownership)
        {
            if (!toWrap.CanSeek)
            {
                throw new ArgumentException("Wrapped stream must support seeking", "toWrap");
            }

            _common = new CommonState {
                WrappedStream = toWrap,
                WrappedStreamOwnership = ownership };
            _ownsCommon = true;
        }
        /// <summary>
        /// Initializes a new instance of the ThreadSafeStream class.
        /// </summary>
        /// <param name="toWrap">The stream to wrap.</param>
        /// <param name="ownership">Whether to transfer ownership of <c>toWrap</c> to the new instance.</param>
        /// <remarks>Do not directly modify <c>toWrap</c> after wrapping it, unless the thread-safe views
        /// will no longer be used.</remarks>
        public ThreadSafeStream(SparseStream toWrap, Ownership ownership)
        {
            if (!toWrap.CanSeek)
            {
                throw new ArgumentException("Wrapped stream must support seeking", nameof(toWrap));
            }

            _common = new CommonState
            {
                WrappedStream          = toWrap,
                WrappedStreamOwnership = ownership
            };
            _ownsCommon = true;
        }
        /// <summary>
        /// Disposes of this instance, freeing up associated resources.
        /// </summary>
        /// <param name="disposing"><c>true</c> if invoked from <c>Dispose</c>, else <c>false</c>.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (_wrappedStream != null && _ownWrapped == Ownership.Dispose)
                {
                    _wrappedStream.Dispose();
                }

                _wrappedStream = null;
            }

            base.Dispose(disposing);
        }
Beispiel #7
0
 protected override void Dispose(bool disposing)
 {
     try
     {
         if (disposing && _ownsWrapped == Ownership.Dispose && _wrapped != null)
         {
             _wrapped.Dispose();
             _wrapped = null;
         }
     }
     finally
     {
         base.Dispose(disposing);
     }
 }
        /// <summary>
        /// Writes data to the stream (not currently supported).
        /// </summary>
        /// <param name="buffer">The data to write.</param>
        /// <param name="offset">The first byte to write.</param>
        /// <param name="count">The number of bytes to write.</param>
        public override void Write(byte[] buffer, int offset, int count)
        {
            lock (_common)
            {
                SparseStream wrapped = Wrapped;

                if (_position + count > wrapped.Length)
                {
                    throw new IOException("Attempt to extend stream");
                }

                wrapped.Position = _position;
                wrapped.Write(buffer, offset, count);
                _position += count;
            }
        }
        public void DisposeView()
        {
            SparseMemoryStream memStream = new SparseMemoryStream(new SparseMemoryBuffer(1), FileAccess.ReadWrite);

            memStream.SetLength(1024);

            ThreadSafeStream tss = new ThreadSafeStream(memStream);

            SparseStream altView = tss.OpenView();

            altView.Dispose();

            tss.ReadByte();

            SparseStream altView2 = tss.OpenView();

            altView2.ReadByte();
        }
        public void ReadThrough()
        {
            MemoryStream       ms       = CreateSequencedMemStream(100, false);
            BlockCacheSettings settings = new BlockCacheSettings()
            {
                BlockSize = 10, OptimumReadSize = 20, ReadCacheSize = 100, LargeReadSize = 30
            };
            BlockCacheStream cacheStream = new BlockCacheStream(SparseStream.FromStream(ms, Ownership.Dispose), Ownership.Dispose, settings);

            byte[] buffer = new byte[20];
            cacheStream.Position = 0;
            cacheStream.Read(buffer, 0, buffer.Length);

            AssertSequenced(buffer, 0);
            Assert.AreEqual(0, cacheStream.Statistics.LargeReadsIn);
            Assert.AreEqual(0, cacheStream.Statistics.ReadCacheHits);
            Assert.AreEqual(1, cacheStream.Statistics.TotalReadsIn);
        }
Beispiel #11
0
        /// <summary>
        /// Creates a new instance.
        /// </summary>
        /// <param name="stream">The stream to wrap</param>
        /// <param name="ownership">Whether to dispose stream, when this object is disposed</param>
        public StreamBuffer(Stream stream, Ownership ownership)
        {
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }

            _stream = stream as SparseStream;
            if (_stream == null)
            {
                _stream    = SparseStream.FromStream(stream, ownership);
                _ownership = Ownership.Dispose;
            }
            else
            {
                _ownership = ownership;
            }
        }
Beispiel #12
0
        /// <summary>
        /// Creates a new instance.
        /// </summary>
        /// <param name="stream">The stream to wrap</param>
        /// <param name="ownership">Whether to dispose stream, when this object is disposed</param>
        public StreamBuffer(Stream stream, Ownership ownership)
        {
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }

            _stream = stream as SparseStream;
            if (_stream == null)
            {
                _stream = SparseStream.FromStream(stream, ownership);
                _ownership = Ownership.Dispose;
            }
            else
            {
                _ownership = ownership;
            }
        }
        /// <summary>
        /// Opens the specified file.
        /// </summary>
        /// <param name="path">The full path of the file to open.</param>
        /// <param name="mode">The file mode for the created stream.</param>
        /// <param name="access">The access permissions for the created stream.</param>
        /// <returns>The new stream.</returns>
        public override SparseStream OpenFile(string path, FileMode mode, FileAccess access)
        {
            if (_readOnly && access != FileAccess.Read)
            {
                throw new UnauthorizedAccessException();
            }

            if (path.StartsWith(@"\", StringComparison.OrdinalIgnoreCase))
            {
                path = path.Substring(1);
            }

            FileShare fileShare = FileShare.None;

            if (access == FileAccess.Read)
            {
                fileShare = FileShare.Read;
            }

            return(SparseStream.FromStream(File.Open(Path.Combine(_basePath, path), mode, access, fileShare), Ownership.Dispose));
        }
        public void Dispose_StopsView()
        {
            SparseMemoryStream memStream = new SparseMemoryStream(new SparseMemoryBuffer(1), FileAccess.ReadWrite);

            memStream.SetLength(1024);

            ThreadSafeStream tss = new ThreadSafeStream(memStream);

            SparseStream altView = tss.OpenView();

            tss.Dispose();

            try
            {
                altView.ReadByte();
                Assert.Fail("Disposed stream didn't stop view");
            }
            catch (ObjectDisposedException)
            {
            }
        }
        public void Bug5203_IncreaseSize()
        {
            MemoryStream       ms       = new MemoryStream();
            BlockCacheSettings settings = new BlockCacheSettings {
                BlockSize = 64, LargeReadSize = 128, OptimumReadSize = 64, ReadCacheSize = 1024
            };
            BlockCacheStream bcs = new BlockCacheStream(SparseStream.FromStream(ms, Ownership.Dispose), Ownership.Dispose, settings);

            // Pre-load read cache with a 'short' block
            bcs.Write(new byte[11], 0, 11);
            bcs.Position = 0;
            bcs.Read(new byte[11], 0, 11);

            // Extend stream
            for (int i = 0; i < 20; ++i)
            {
                bcs.Write(new byte[11], 0, 11);
            }

            // Try to read from first block beyond length of original cached short length
            // Bug was throwing exception here
            bcs.Position = 60;
            bcs.Read(new byte[20], 0, 20);
        }
        public void Extents()
        {
            SparseMemoryStream memStream = new SparseMemoryStream(new SparseMemoryBuffer(1), FileAccess.ReadWrite);

            memStream.SetLength(1024);

            ThreadSafeStream tss = new ThreadSafeStream(memStream);

            SparseStream altView = tss.OpenView();

            tss.Position = 100;
            tss.WriteByte(99);

            List <StreamExtent> extents = new List <StreamExtent>(altView.Extents);

            Assert.AreEqual(1, extents.Count);
            Assert.AreEqual(100, extents[0].Start);
            Assert.AreEqual(1, extents[0].Length);

            extents = new List <StreamExtent>(altView.GetExtentsInRange(10, 300));
            Assert.AreEqual(1, extents.Count);
            Assert.AreEqual(100, extents[0].Start);
            Assert.AreEqual(1, extents[0].Length);
        }
            GC.SuppressFinalize(this);
        }

        /// <summary>
        /// Disposes of underlying resources.
        /// </summary>
        /// <param name="disposing"><c>true</c> if running inside Dispose(), indicating
Beispiel #18
0
 public BuilderSparseStreamExtent(long start, SparseStream stream)
     : base(start, stream.Length)
 {
     _stream = stream;
 }
 /// <summary>
 /// Wraps a sparse stream in a read-only wrapper, preventing modification.
 /// </summary>
 /// <param name="toWrap">The stream to make read-only</param>
 /// <param name="ownership">Whether to transfer responsibility for calling Dispose on <c>toWrap</c></param>
 /// <returns>The read-only stream.</returns>
 public static SparseStream ReadOnly(SparseStream toWrap, Ownership ownership)
 {
     return new SparseReadOnlyWrapperStream(toWrap, ownership);
 }
 public BuilderSparseStreamExtent(long start, SparseStream stream, Ownership ownership)
     : base(start, stream.Length)
 {
     _stream = stream;
     _ownership = ownership;
 }
 public void Dispose()
 {
     WrappedStream = null;
 }
        /// <summary>
        /// Disposes of this instance, freeing up associated resources.
        /// </summary>
        /// <param name="disposing"><c>true</c> if invoked from <c>Dispose</c>, else <c>false</c>.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (_wrappedStream != null && _ownWrapped == Ownership.Dispose)
                {
                    _wrappedStream.Dispose();
                }

                _wrappedStream = null;
            }

            base.Dispose(disposing);
        }
 public BuilderSparseStreamExtent(long start, SparseStream stream)
     : this(start, stream, Ownership.None)
 {
 }
Beispiel #24
0
 /// <summary>
 /// Efficiently pumps data from a sparse stream to another stream.
 /// </summary>
 /// <param name="inStream">The sparse stream to pump from.</param>
 /// <param name="outStream">The stream to pump to.</param>
 /// <remarks><paramref name="outStream"/> must support seeking.</remarks>
 public static void Pump(SparseStream inStream, Stream outStream)
 {
     Pump(inStream, outStream, Sizes.Sector);
 }
Beispiel #25
0
        private static void UpdateBiosGeometry(SparseStream contentStream, Geometry oldGeometry, Geometry newGeometry)
        {
            BiosPartitionTable partTable = new BiosPartitionTable(contentStream, oldGeometry);
            partTable.UpdateBiosGeometry(newGeometry);

            VolumeManager volMgr = new VolumeManager(contentStream);
            foreach (var volume in volMgr.GetLogicalVolumes())
            {
                foreach (var fsInfo in FileSystemManager.DetectDefaultFileSystems(volume.Open()))
                {
                    if (fsInfo.Name == "NTFS")
                    {
                        using (NtfsFileSystem fs = new NtfsFileSystem(volume.Open()))
                        {
                            fs.UpdateBiosGeometry(newGeometry);
                        }
                    }
                }
            }
        }
Beispiel #26
0
 /// <summary>
 /// Efficiently pumps data from a sparse stream to another stream.
 /// </summary>
 /// <param name="inStream">The sparse stream to pump from.</param>
 /// <param name="outStream">The stream to pump to.</param>
 /// <param name="chunkSize">The smallest sequence of zero bytes that will be skipped when writing to <paramref name="outStream"/></param>
 /// <remarks><paramref name="outStream"/> must support seeking.</remarks>
 public static void Pump(SparseStream inStream, Stream outStream, int chunkSize)
 {
     StreamPump pump = new StreamPump(inStream, outStream, chunkSize);
     pump.Run();
 }
 public CircularStream(SparseStream toWrap, Ownership ownership)
     : base(toWrap, ownership)
 {
 }
 /// <summary>
 /// Initializes a new instance of the ThreadSafeStream class.
 /// </summary>
 /// <param name="toWrap">The stream to wrap.</param>
 /// <remarks>Do not directly modify <c>toWrap</c> after wrapping it, unless the thread-safe views
 /// will no longer be used.</remarks>
 public ThreadSafeStream(SparseStream toWrap)
     : this(toWrap, Ownership.None)
 {
 }
Beispiel #29
0
 public WrappingStream(SparseStream toWrap, Ownership ownership)
 {
     _wrapped = toWrap;
     _ownership = ownership;
 }
Beispiel #30
0
 /// <summary>
 /// Wraps a sparse stream in a read-only wrapper, preventing modification.
 /// </summary>
 /// <param name="toWrap">The stream to make read-only.</param>
 /// <param name="ownership">Whether to transfer responsibility for calling Dispose on <c>toWrap</c>.</param>
 /// <returns>The read-only stream.</returns>
 public static SparseStream ReadOnly(SparseStream toWrap, Ownership ownership)
 {
     return(new SparseReadOnlyWrapperStream(toWrap, ownership));
 }
 public BuilderSparseStreamExtent(long start, SparseStream stream)
     : base(start, stream.Length)
 {
     _stream = stream;
 }
 public void OpenView()
 {
     ThreadSafeStream tss  = new ThreadSafeStream(SparseStream.FromStream(Stream.Null, Ownership.None));
     SparseStream     view = tss.OpenView();
 }
 /// <summary>
 /// Initializes a new instance of the BlockCacheStream class.
 /// </summary>
 /// <param name="toWrap">The stream to wrap.</param>
 /// <param name="ownership">Whether to assume ownership of <c>toWrap</c>.</param>
 public BlockCacheStream(SparseStream toWrap, Ownership ownership)
     : this(toWrap, ownership, new BlockCacheSettings())
 {
 }
 /// <summary>
 /// Initializes a new instance of the BlockCacheStream class.
 /// </summary>
 /// <param name="toWrap">The stream to wrap.</param>
 /// <param name="ownership">Whether to assume ownership of <c>toWrap</c>.</param>
 public BlockCacheStream(SparseStream toWrap, Ownership ownership)
     : this(toWrap, ownership, new BlockCacheSettings())
 {
 }
 protected override void Dispose(bool disposing)
 {
     try
     {
         if (disposing && _ownsWrapped == Ownership.Dispose && _wrapped != null)
         {
             _wrapped.Dispose();
             _wrapped = null;
         }
     }
     finally
     {
         base.Dispose(disposing);
     }
 }
Beispiel #36
0
        private void RunSparse()
        {
            SparseStream inStream = InputStream as SparseStream;

            if (inStream == null)
            {
                inStream = SparseStream.FromStream(InputStream, Ownership.None);
            }

            if (BufferSize > SparseChunkSize && BufferSize % SparseChunkSize != 0)
            {
                throw new InvalidOperationException("Buffer size is not a multiple of the sparse chunk size");
            }

            byte[] copyBuffer = new byte[Math.Max(BufferSize, SparseChunkSize)];

            BytesRead    = 0;
            BytesWritten = 0;

            foreach (StreamExtent extent in inStream.Extents)
            {
                inStream.Position = extent.Start;

                long extentOffset = 0;
                while (extentOffset < extent.Length)
                {
                    int toRead  = (int)Math.Min(copyBuffer.Length, extent.Length - extentOffset);
                    int numRead = Utilities.ReadFully(inStream, copyBuffer, 0, toRead);
                    BytesRead += numRead;

                    int copyBufferOffset = 0;
                    for (int i = 0; i < numRead; i += SparseChunkSize)
                    {
                        if (IsAllZeros(copyBuffer, i, Math.Min(SparseChunkSize, numRead - i)))
                        {
                            if (copyBufferOffset < i)
                            {
                                OutputStream.Position = extent.Start + extentOffset + copyBufferOffset;
                                OutputStream.Write(copyBuffer, copyBufferOffset, i - copyBufferOffset);
                                BytesWritten += i - copyBufferOffset;
                            }

                            copyBufferOffset = i + SparseChunkSize;
                        }
                    }

                    if (copyBufferOffset < numRead)
                    {
                        OutputStream.Position = extent.Start + extentOffset + copyBufferOffset;
                        OutputStream.Write(copyBuffer, copyBufferOffset, numRead - copyBufferOffset);
                        BytesWritten += numRead - copyBufferOffset;
                    }

                    extentOffset += numRead;

                    RaiseProgressEvent();
                }
            }

            // Ensure the output stream is at least as long as the input stream.  This uses
            // read/write, rather than SetLength, to avoid failing on streams that can't be
            // explicitly resized.  Side-effect of this, is that if outStream is an NTFS
            // file stream, then actual clusters will be allocated out to at least the
            // length of the input stream.
            if (OutputStream.Length < inStream.Length)
            {
                inStream.Position = inStream.Length - 1;
                int b = inStream.ReadByte();
                if (b >= 0)
                {
                    OutputStream.Position = inStream.Length - 1;
                    OutputStream.WriteByte((byte)b);
                }
            }
        }
Beispiel #37
0
 public SparseReadOnlyWrapperStream(SparseStream wrapped, Ownership ownsWrapped)
 {
     _wrapped     = wrapped;
     _ownsWrapped = ownsWrapped;
 }
Beispiel #38
0
        /// <summary>
        /// Efficiently pumps data from a sparse stream to another stream.
        /// </summary>
        /// <param name="inStream">The sparse stream to pump from.</param>
        /// <param name="outStream">The stream to pump to.</param>
        /// <param name="chunkSize">The smallest sequence of zero bytes that will be skipped when writing to <paramref name="outStream"/></param>
        /// <remarks><paramref name="outStream"/> must support seeking.</remarks>
        public static void Pump(SparseStream inStream, Stream outStream, int chunkSize)
        {
            StreamPump pump = new StreamPump(inStream, outStream, chunkSize);

            pump.Run();
        }
 /// <summary>
 /// Initializes a new instance of the ThreadSafeStream class.
 /// </summary>
 /// <param name="toWrap">The stream to wrap.</param>
 /// <remarks>Do not directly modify <c>toWrap</c> after wrapping it, unless the thread-safe views
 /// will no longer be used.</remarks>
 public ThreadSafeStream(SparseStream toWrap)
     : this(toWrap, Ownership.None)
 {
 }
 public CircularStream(SparseStream toWrap, Ownership ownership)
     : base(toWrap, ownership)
 {
 }
 public BuilderSparseStreamExtent(long start, SparseStream stream)
     : this(start, stream, Ownership.None)
 {
 }
Beispiel #42
0
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (_stream != null)
                {
                    _stream.Dispose();
                    _stream = null;
                }
            }

            if (!_handle.IsClosed)
            {
                _handle.Dispose();
            }

            base.Dispose(disposing);
        }
Beispiel #43
0
 /// <summary>
 /// Efficiently pumps data from a sparse stream to another stream.
 /// </summary>
 /// <param name="inStream">The sparse stream to pump from.</param>
 /// <param name="outStream">The stream to pump to.</param>
 /// <remarks><paramref name="outStream"/> must support seeking.</remarks>
 public static void Pump(SparseStream inStream, Stream outStream)
 {
     Pump(inStream, outStream, Sizes.Sector);
 }
Beispiel #44
0
 /// <summary>
 /// Gets the content of this extent.
 /// </summary>
 /// <param name="parent">The parent stream (if any)</param>
 /// <param name="ownsParent">Controls ownership of the parent stream</param>
 /// <returns>The content as a stream</returns>
 public abstract MappedStream OpenContent(SparseStream parent, Ownership ownsParent);
 public SparseReadOnlyWrapperStream(SparseStream wrapped, Ownership ownsWrapped)
 {
     _wrapped = wrapped;
     _ownsWrapped = ownsWrapped;
 }
 public BuilderSparseStreamExtent(long start, SparseStream stream, Ownership ownership)
     : base(start, stream.Length)
 {
     _stream    = stream;
     _ownership = ownership;
 }
 public void Dispose()
 {
     WrappedStream = null;
 }
 public WrappingStream(SparseStream toWrap, Ownership ownership)
 {
     _wrapped   = toWrap;
     _ownership = ownership;
 }