/*******************************************************************************
* 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;
}
}
}
}