SharedStream.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Framework / System / Windows / Markup / Baml2006 / SharedStream.cs / 1305600 / SharedStream.cs

                            using System; 
using System.IO;
using System.ComponentModel;

namespace System.Windows.Baml2006 
{
    ///  
    /// Reference counted stream 
    /// Allows multiple callers independently coordinate "current position"
    /// for reads and writes on a shared stream. 
    /// Methods on this class are not thread safe.
    /// 
    internal class SharedStream : Stream
    { 
        private Stream _baseStream;
        private long _offset; 
        private long _length; 
        private long _position;
        private RefCount _refCount; 

        public SharedStream(Stream baseStream)
        {
            if (baseStream == null) 
            {
                throw new ArgumentNullException("baseStream"); 
            } 

            Initialize(baseStream, 0, baseStream.Length); 
        }

        /// 
        /// Constructor that limits the bytes that can be written to or read form 
        /// 
        ///  
        ///  
        /// 
        public SharedStream(Stream baseStream, long offset, long length) 
        {
            if (baseStream == null)
            {
                throw new ArgumentNullException("baseStream"); 
            }
 
            Initialize(baseStream, offset, length); 
        }
 
        private void Initialize(Stream baseStream, long offset, long length)
        {
            if (baseStream.CanSeek == false)
            { 
                throw new ArgumentException("can’t seek on baseStream");
            } 
 
            if (offset < 0)
            { 
                throw new ArgumentOutOfRangeException("offset");
            }

            if (length < 0) 
            {
                throw new ArgumentOutOfRangeException("length"); 
            } 

            SharedStream subStream = baseStream as SharedStream; 
            if (subStream != null)
            {
                _baseStream = subStream.BaseStream;
                _offset = offset + subStream._offset; 
                _length = length;
                _refCount = subStream._refCount; 
                _refCount.Value++; 
            }
            else 
            {
                _baseStream = baseStream;
                _offset = offset;
                _length = length; 
                _refCount = new RefCount();
                _refCount.Value++; 
            } 
        }
 
        /// 
        /// Number of clients sharing the base stream
        /// 
        public virtual int SharedCount 
        {
            get { return _refCount.Value; } 
        } 

        public override bool CanRead 
        {
            get
            {
                CheckDisposed(); 
                return _baseStream.CanRead;
            } 
        } 

        public override bool CanSeek 
        {
            get
            {
                return true; 
            }
        } 
 
        public override bool CanWrite
        { 
            get
            {
#if true
                return false; 
#else
                CheckDisposed(); 
                return _baseStream.CanWrite; 
#endif
            } 
        }

        public override void Flush()
        { 
            CheckDisposed();
            _baseStream.Flush(); 
        } 

        public override long Length 
        {
            get
            {
                return _length; 
            }
        } 
 
        public override long Position
        { 
            get
            {
                return _position;
            } 
            set
            { 
                if (value < 0 || value >= _length) 
                {
                    throw new ArgumentOutOfRangeException("value", value, string.Empty); 
                }

                _position = value;
            } 
        }
 
        public virtual bool IsDisposed { get { return _baseStream == null; } } 

        public override int ReadByte() 
        {
            CheckDisposed();

            long end = Math.Min(_position + 1, _length); 

            int b; 
            if ([....]()) 
            {
                b = _baseStream.ReadByte(); 
                _position = _baseStream.Position - _offset;
            }
            else
            { 
                b = -1;
            } 
            return b; 
        }
 
        public override int Read(byte[] buffer, int offset, int count)
        {
            if (buffer == null)
            { 
                throw new ArgumentNullException("buffer");
            } 
 
            if (offset < 0 || offset >= buffer.Length)
            { 
                throw new ArgumentOutOfRangeException("offset");
            }

            if ((offset + count) > buffer.Length) 
            {
                throw new ArgumentOutOfRangeException("count"); 
            } 

            CheckDisposed(); 

            long end = Math.Min(_position + count, _length);

            int bytesRead = 0; 

            if ([....]()) 
            { 
                bytesRead = _baseStream.Read(buffer, offset, (int)(end - _position));
                _position = _baseStream.Position - _offset; 
            }

            return bytesRead;
        } 

        public override void Write(byte[] buffer, int offset, int count) 
        { 
#if true
            throw new NotSupportedException(); 
#else
            if(buffer == null)
            {
                throw new ArgumentNullException("buffer"); 
            }
 
            if(offset < 0 || offset >= buffer.Length) { 
                throw new ArgumentOutOfRangeException("offset");
            } 

            if((offset + count) > buffer.Length) {
                throw new ArgumentOutOfRangeException("count");
            } 

            CheckDisposed(); 
 
            long end = Math.Min(_position + count, _length);
 
            if ([....]())
            {
                _baseStream.Write(buffer, offset, (int)(end - _position));
                _position = _baseStream.Position - _offset; 
            }
#endif 
        } 

        public override long Seek(long offset, SeekOrigin origin) 
        {
            long newPosition;
            switch (origin)
            { 
                case SeekOrigin.Begin:
                    newPosition = offset; 
                    break; 

                case SeekOrigin.Current: 
                    newPosition = _position + offset;
                    break;

                case SeekOrigin.End: 
                    newPosition = _length + offset;
                    break; 
 
                default:
                    throw new InvalidEnumArgumentException("origin", (int)origin, typeof(SeekOrigin)); 
            }

            if (newPosition < 0 || newPosition >= _length)
            { 
                throw new ArgumentOutOfRangeException("offset", offset, string.Empty);
            } 
 
            CheckDisposed();
 
            _position = newPosition;

            return _position;
        } 

        public override void SetLength(long value) 
        { 
            throw new NotSupportedException();
        } 

        protected override void Dispose(bool disposing)
        {
            if (disposing) 
            {
                if (_baseStream != null) 
                { 
                    _refCount.Value--;
                    if (_refCount.Value < 1) 
                    {
                        _baseStream.Close();
                    }
                    _refCount = null; 
                    _baseStream = null;
                } 
            } 

            base.Dispose(disposing); 
        }

        public Stream BaseStream
        { 
            get { return _baseStream; }
        } 
 
        private void CheckDisposed()
        { 
            if (IsDisposed)
            {
                throw new ObjectDisposedException("BaseStream");
            } 
        }
 
        private bool [....]() 
        {
            System.Diagnostics.Debug.Assert(_baseStream != null, "Stream has already been disposed"); 

            if (_position >= 0 && _position < _length)
            {
                if (_position + _offset != _baseStream.Position) 
                    _baseStream.Seek(_offset + _position, SeekOrigin.Begin);
                return true; 
            } 

            return false; 
        }

        class RefCount
        { 
            public int Value;
        } 
    } 

} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK