/// <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; }
/// <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", "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); }
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; } }
/// <summary> /// Initializes a new instance of the StreamBuffer class. /// </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 SparseReadOnlyWrapperStream(SparseStream wrapped, Ownership ownsWrapped) { _wrapped = wrapped; _ownsWrapped = ownsWrapped; }
/// <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)); }
/// <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 Dispose() { WrappedStream = null; }
/// <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) { }
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 (var 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); } } }
/// <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> /// 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);
/// <summary> /// Gets the content of this layer. /// </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 SparseStream OpenContent(SparseStream parent, Ownership ownsParent);
/// <summary> /// Disposes of this instance. /// </summary> public void Dispose() { if (_ownership == Ownership.Dispose) { if (_stream != null) { _stream.Dispose(); _stream = null; } } }