예제 #1
0
        /// <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;
        }
예제 #2
0
        /// <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);
        }
예제 #3
0
 protected override void Dispose(bool disposing)
 {
     try
     {
         if (disposing && _ownsWrapped == Ownership.Dispose && _wrapped != null)
         {
             _wrapped.Dispose();
             _wrapped = null;
         }
     }
     finally
     {
         base.Dispose(disposing);
     }
 }
예제 #4
0
        /// <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;
            }
        }
예제 #5
0
        /// <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;
            }
        }
예제 #6
0
        /// <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));
        }
예제 #7
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);
예제 #8
0
 public SparseReadOnlyWrapperStream(SparseStream wrapped, Ownership ownsWrapped)
 {
     _wrapped     = wrapped;
     _ownsWrapped = ownsWrapped;
 }
예제 #9
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));
 }
예제 #10
0
 /// <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)
 {
 }
예제 #11
0
 public void Dispose()
 {
     WrappedStream = null;
 }
예제 #12
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 (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);
                }
            }
        }
예제 #13
0
 /// <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())
 {
 }
예제 #14
0
 public BuilderSparseStreamExtent(long start, SparseStream stream)
     : base(start, stream.Length)
 {
     _stream = stream;
 }