/******************************************************************************* * Copyright 2008-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"). You may not use * this file except in compliance with the License. A copy of the License is located at * * http://aws.amazon.com/apache2.0 * * or in the "license" file accompanying this file. * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR * CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. * ***************************************************************************** * __ _ _ ___ * ( )( \/\/ )/ __) * /__\ \ / \__ \ * (_)(_) \/\/ (___/ * * AWS SDK for .NET * API Version: 2006-03-01 * */ using System; using System.IO; namespace Amazon.Runtime.Internal.Util { /// /// A wrapper stream. /// public class WrapperStream : Stream { /// /// Base stream. /// protected Stream BaseStream { get; private set; } /// /// Initializes WrapperStream with a base stream. /// /// public WrapperStream(Stream baseStream) { if (baseStream == null) throw new ArgumentNullException("baseStream"); BaseStream = baseStream; } /// /// Returns the first base non-WrapperStream. /// /// First base stream that is non-WrapperStream. public Stream GetNonWrapperBaseStream() { Stream baseStream = this; do { var partialStream = baseStream as PartialWrapperStream; if (partialStream != null) return partialStream; baseStream = (baseStream as WrapperStream).BaseStream; } while (baseStream is WrapperStream); return baseStream; } /// /// Returns the first base non-WrapperStream. /// /// First base stream that is non-WrapperStream. public Stream GetSeekableBaseStream() { Stream baseStream = this; do { if (baseStream.CanSeek) return baseStream; baseStream = (baseStream as WrapperStream).BaseStream; } while (baseStream is WrapperStream); if (!baseStream.CanSeek) throw new InvalidOperationException("Unable to find seekable stream"); return baseStream; } /// /// Returns the first base non-WrapperStream. /// /// Potential WrapperStream /// Base non-WrapperStream. public static Stream GetNonWrapperBaseStream(Stream stream) { WrapperStream wrapperStream = stream as WrapperStream; if (wrapperStream == null) return stream; return wrapperStream.GetNonWrapperBaseStream(); } public Stream SearchWrappedStream(Func condition) { Stream baseStream = this; do { if (condition(baseStream)) return baseStream; if (!(baseStream is WrapperStream)) return null; baseStream = (baseStream as WrapperStream).BaseStream; } while (baseStream != null); return baseStream; } public static Stream SearchWrappedStream(Stream stream, Func condition) { WrapperStream wrapperStream = stream as WrapperStream; if (wrapperStream == null) return condition(stream) ? stream : null; return wrapperStream.SearchWrappedStream(condition); } #region Stream overrides /// /// Gets a value indicating whether the current stream supports reading. /// True if the stream supports reading; otherwise, false. /// public override bool CanRead { get { return BaseStream.CanRead; } } /// /// Gets a value indicating whether the current stream supports seeking. /// True if the stream supports seeking; otherwise, false. /// public override bool CanSeek { get { return BaseStream.CanSeek; } } /// /// Gets a value indicating whether the current stream supports writing. /// True if the stream supports writing; otherwise, false. /// public override bool CanWrite { get { return BaseStream.CanWrite; } } /// /// Closes the current stream and releases any resources (such as sockets and /// file handles) associated with the current stream. /// #if !PCL && !NETSTANDARD public override void Close() { BaseStream.Close(); } #else protected override void Dispose(bool disposing) { base.Dispose(disposing); BaseStream.Dispose(); } #endif /// /// Gets the length in bytes of the stream. /// public override long Length { get { return BaseStream.Length; } } /// /// Gets or sets the position within the current stream. /// public override long Position { get { return BaseStream.Position; } set { BaseStream.Position = value; } } /// /// Gets or sets a value, in miliseconds, that determines how long the stream /// will attempt to read before timing out. /// public override int ReadTimeout { get { return BaseStream.ReadTimeout; } set { BaseStream.ReadTimeout = value; } } /// /// Gets or sets a value, in miliseconds, that determines how long the stream /// will attempt to write before timing out. /// public override int WriteTimeout { get { return BaseStream.WriteTimeout; } set { BaseStream.WriteTimeout = value; } } /// /// Clears all buffers for this stream and causes any buffered data to be written /// to the underlying device. /// public override void Flush() { BaseStream.Flush(); } /// /// Reads a sequence of bytes from the current stream and advances the position /// within the stream by the number of bytes read. /// /// /// An array of bytes. When this method returns, the buffer contains the specified /// byte array with the values between offset and (offset + count - 1) replaced /// by the bytes read from the current source. /// /// /// The zero-based byte offset in buffer at which to begin storing the data read /// from the current stream. /// /// /// The maximum number of bytes to be read from the current stream. /// /// /// The total number of bytes read into the buffer. This can be less than the /// number of bytes requested if that many bytes are not currently available, /// or zero (0) if the end of the stream has been reached. /// public override int Read(byte[] buffer, int offset, int count) { return BaseStream.Read(buffer, offset, count); } /// /// Sets the position within the current stream. /// /// A byte offset relative to the origin parameter. /// /// A value of type System.IO.SeekOrigin indicating the reference point used /// to obtain the new position. /// The new position within the current stream. public override long Seek(long offset, SeekOrigin origin) { return BaseStream.Seek(offset, origin); } /// /// Sets the length of the current stream. /// /// The desired length of the current stream in bytes. public override void SetLength(long value) { BaseStream.SetLength(value); } /// /// Writes a sequence of bytes to the current stream and advances the current /// position within this stream by the number of bytes written. /// /// /// An array of bytes. This method copies count bytes from buffer to the current stream. /// /// /// The zero-based byte offset in buffer at which to begin copying bytes to the /// current stream. /// /// The number of bytes to be written to the current stream. public override void Write(byte[] buffer, int offset, int count) { BaseStream.Write(buffer, offset, count); } #endregion internal virtual bool HasLength { get { return true; } } } }