CompressEmulationStream.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / wpf / src / Base / MS / Internal / IO / Packaging / CompressEmulationStream.cs / 1 / CompressEmulationStream.cs

                            //------------------------------------------------------------------------------ 
//
// 
//    Copyright (C) Microsoft Corporation.  All rights reserved.
//  
//
// Description: 
//  Abstract base class that provides a fully functional Stream on top of different 
//  various compression implementations.
// 
// History:
//  07/14/2004: BruceMac: Initial implementation.
//  12/06/2005: BruceMac: Split into abstract base class and move DeflateStream
//              specific implementation into ManagedEmulationStream 
//  12/16/2005: BruceMac: Reworked to move functionality into IDeflateTransform
//              interface to avoid calling virtuals from constructor (FxCop rule) 
//----------------------------------------------------------------------------- 

using System; 
using System.IO;
using System.IO.Compression;                // for DeflateStream
using System.Diagnostics;
 
using System.IO.Packaging;
using System.Windows; 
 
namespace MS.Internal.IO.Packaging
{ 
    //-----------------------------------------------------
    //
    //  Internal Members
    // 
    //-----------------------------------------------------
    ///  
    /// Interface for Deflate transform object that we use to decompress and compress the actual bytes 
    /// 
    interface IDeflateTransform 
    {
        void Decompress(Stream source, Stream sink);
        void Compress(Stream source, Stream sink);
    } 

    ///  
    /// Emulates a fully functional stream using restricted functionality DeflateStream and a temp file 
    /// 
    internal class CompressEmulationStream : Stream 
    {
        //------------------------------------------------------
        //
        //  Public Methods 
        //
        //----------------------------------------------------- 
        #region Stream Methods 
        /// 
        /// Return the bytes requested from the container 
        /// 
        /// destination buffer
        /// offset to write into that buffer
        /// how many bytes requested 
        /// how many bytes were written into .
        ///  
        /// The underlying stream, expected to be an IsolatedStorageFileStream, 
        /// is trusted to leave the IO position unchanged in case of an exception.
        ///  
        public override int Read(byte[] buffer, int offset, int count)
        {
            CheckDisposed();
 
            PackagingUtilities.VerifyStreamReadArgs(this, buffer, offset, count);
 
            return _tempStream.Read(buffer, offset, count); 
        }
 
        /// 
        /// Seek
        /// 
        /// offset 
        /// origin
        /// zero 
        public override long Seek(long offset, SeekOrigin origin) 
        {
            CheckDisposed(); 

            long temp = 0;
            switch (origin)
            { 
                case SeekOrigin.Begin:
                    { 
                        temp = offset; 
                        break;
                    } 
                case SeekOrigin.Current:
                    {
                        checked { temp = _tempStream.Position + offset; }
                        break; 
                    }
                case SeekOrigin.End: 
                    { 
                        checked { temp = _tempStream.Length + offset; }
                        break; 
                    }
                default:
                    {
                        throw new ArgumentOutOfRangeException("origin", SR.Get(SRID.SeekOriginInvalid)); 
                    }
            } 
 
            if (temp < 0)
            { 
                throw new ArgumentException(SR.Get(SRID.SeekNegative));
            }

            return _tempStream.Seek(offset, origin); 
        }
 
        ///  
        /// SetLength
        ///  
        public override void SetLength(long newLength)
        {
            CheckDisposed();
 
            _tempStream.SetLength(newLength);
 
            // truncation always involves change of stream pointer 
            if (newLength < _tempStream.Position)
                _tempStream.Position = newLength; 

            _dirty = true;
        }
 
        /// 
        /// Write 
        ///  
        public override void Write(byte[] buffer, int offset, int count)
        { 
            CheckDisposed();

            PackagingUtilities.VerifyStreamWriteArgs(this, buffer, offset, count);
 
            // no-op
            if (count == 0) 
                return; 

            _tempStream.Write(buffer, offset, count); 
            _dirty = true;
        }

        ///  
        /// Flush
        ///  
        /// Flushes to stream (if necessary) 
        public override void Flush()
        { 
            CheckDisposed();

            if (_dirty)
            { 
                // don't disturb our current position
                long tempPosition = _tempStream.Position; 
 
                // compress
                _tempStream.Position = 0; 
                _baseStream.Position = 0;
                _transformer.Compress(_tempStream, _baseStream);

                // restore 
                _tempStream.Position = tempPosition;
 
                _baseStream.Flush(); 
                _dirty = false;
            } 
        }
        #endregion Stream Methods

        #region Stream Properties 
        /// 
        /// Current logical position within the stream 
        ///  
        public override long Position
        { 
            get
            {
                CheckDisposed();
                return _tempStream.Position; 
            }
            set 
            { 
                CheckDisposed();
 
                if (value < 0)
                    throw new ArgumentException(SR.Get(SRID.SeekNegative));

                _tempStream.Position = value; 
            }
        } 
 
        /// 
        /// Length 
        /// 
        public override long Length
        {
            get 
            {
                CheckDisposed(); 
                return _tempStream.Length; 
            }
        } 

        /// 
        /// Is stream readable?
        ///  
        /// returns false when called on disposed stream
        public override bool CanRead 
        { 
            get
            { 
                return (!_disposed && _baseStream.CanRead);
            }
        }
 
        /// 
        /// Is stream seekable - should be handled by our owner 
        ///  
        /// returns false when called on disposed stream
        public override bool CanSeek 
        {
            get
            {
                return (!_disposed &&  _baseStream.CanSeek); 
            }
        } 
 
        /// 
        /// Is stream writeable? 
        /// 
        /// returns false when called on disposed stream
        public override bool CanWrite
        { 
            get
            { 
                return (!_disposed && _baseStream.CanWrite); 
            }
        } 
        #endregion

        #region Internal
        //------------------------------------------------------ 
        //
        //  Internal Methods 
        // 
        //------------------------------------------------------
        ///  
        /// Constructor
        /// 
        /// part stream - not closed - caller determines lifetime
        /// current logical stream position 
        /// should be an IsolatedStorageFileStream - not closed - caller determines lifetime
        /// class that does the compression/decompression 
        /// This class should only invoked when emulation is required. 
        /// Does not close any given stream, even when Close is called. This means that it requires
        /// another wrapper Stream class. 
        internal CompressEmulationStream(Stream baseStream, Stream tempStream, long position, IDeflateTransform transformer)
        {
            if (position < 0)
                throw new ArgumentOutOfRangeException("position"); 

            if (baseStream == null) 
                throw new ArgumentNullException("baseStream"); 

            // seek and read required for emulation 
            if (!baseStream.CanSeek)
                throw new InvalidOperationException(SR.Get(SRID.SeekNotSupported));

            if (!baseStream.CanRead) 
                throw new InvalidOperationException(SR.Get(SRID.ReadNotSupported));
 
            if (tempStream == null) 
                throw new ArgumentNullException("tempStream");
 
            if (transformer == null)
                throw new ArgumentNullException("transfomer");

            _baseStream = baseStream; 
            _tempStream = tempStream;
            _transformer = transformer; 
 
            // extract to temporary stream
            _baseStream.Position = 0; 
            _tempStream.Position = 0;
            _transformer.Decompress(baseStream, tempStream);

            // seek to the current logical position 
            _tempStream.Position = position;
        } 
        #endregion 

        //----------------------------------------------------- 
        //
        //  Protected Methods
        //
        //------------------------------------------------------ 
        /// 
        /// Dispose(bool) 
        ///  
        /// 
        /// We implement this because we want a consistent experience (essentially Flush our data) if the user chooses to 
        /// call Dispose() instead of Close().
        protected override void Dispose(bool disposing)
        {
            try 
            {
                if (disposing) 
                { 
                    if (!_disposed)
                    { 
                        Flush();

                        _tempStream.Close();
                        _tempStream = null; 

                        // never close base stream - we don't own it 
//                        _baseStream.Close(); 
                        _baseStream = null;
 
                        _disposed = true;
                    }
                }
            } 
            finally
            { 
                base.Dispose(disposing); 
            }
        } 

        /// 
        /// Call this before accepting any public API call (except some Stream calls that
        /// are allowed to respond even when Closed 
        /// 
        protected void CheckDisposed() 
        { 
            if (_disposed)
                throw new ObjectDisposedException(null, SR.Get(SRID.StreamObjectDisposed)); 
        }

        #region Private
        //----------------------------------------------------- 
        //
        //  Private Variables 
        // 
        //-----------------------------------------------------
        private bool    _disposed;          // disposed? 
        private bool    _dirty;             // do we need to recompress?
        protected Stream  _baseStream;      // stream we ultimately decompress from and to in the container
        protected Stream _tempStream;       // temporary storage for the uncompressed stream
        IDeflateTransform _transformer;   // does the actual compress/decompress for us 
        #endregion
    } 
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------ 
//
// 
//    Copyright (C) Microsoft Corporation.  All rights reserved.
//  
//
// Description: 
//  Abstract base class that provides a fully functional Stream on top of different 
//  various compression implementations.
// 
// History:
//  07/14/2004: BruceMac: Initial implementation.
//  12/06/2005: BruceMac: Split into abstract base class and move DeflateStream
//              specific implementation into ManagedEmulationStream 
//  12/16/2005: BruceMac: Reworked to move functionality into IDeflateTransform
//              interface to avoid calling virtuals from constructor (FxCop rule) 
//----------------------------------------------------------------------------- 

using System; 
using System.IO;
using System.IO.Compression;                // for DeflateStream
using System.Diagnostics;
 
using System.IO.Packaging;
using System.Windows; 
 
namespace MS.Internal.IO.Packaging
{ 
    //-----------------------------------------------------
    //
    //  Internal Members
    // 
    //-----------------------------------------------------
    ///  
    /// Interface for Deflate transform object that we use to decompress and compress the actual bytes 
    /// 
    interface IDeflateTransform 
    {
        void Decompress(Stream source, Stream sink);
        void Compress(Stream source, Stream sink);
    } 

    ///  
    /// Emulates a fully functional stream using restricted functionality DeflateStream and a temp file 
    /// 
    internal class CompressEmulationStream : Stream 
    {
        //------------------------------------------------------
        //
        //  Public Methods 
        //
        //----------------------------------------------------- 
        #region Stream Methods 
        /// 
        /// Return the bytes requested from the container 
        /// 
        /// destination buffer
        /// offset to write into that buffer
        /// how many bytes requested 
        /// how many bytes were written into .
        ///  
        /// The underlying stream, expected to be an IsolatedStorageFileStream, 
        /// is trusted to leave the IO position unchanged in case of an exception.
        ///  
        public override int Read(byte[] buffer, int offset, int count)
        {
            CheckDisposed();
 
            PackagingUtilities.VerifyStreamReadArgs(this, buffer, offset, count);
 
            return _tempStream.Read(buffer, offset, count); 
        }
 
        /// 
        /// Seek
        /// 
        /// offset 
        /// origin
        /// zero 
        public override long Seek(long offset, SeekOrigin origin) 
        {
            CheckDisposed(); 

            long temp = 0;
            switch (origin)
            { 
                case SeekOrigin.Begin:
                    { 
                        temp = offset; 
                        break;
                    } 
                case SeekOrigin.Current:
                    {
                        checked { temp = _tempStream.Position + offset; }
                        break; 
                    }
                case SeekOrigin.End: 
                    { 
                        checked { temp = _tempStream.Length + offset; }
                        break; 
                    }
                default:
                    {
                        throw new ArgumentOutOfRangeException("origin", SR.Get(SRID.SeekOriginInvalid)); 
                    }
            } 
 
            if (temp < 0)
            { 
                throw new ArgumentException(SR.Get(SRID.SeekNegative));
            }

            return _tempStream.Seek(offset, origin); 
        }
 
        ///  
        /// SetLength
        ///  
        public override void SetLength(long newLength)
        {
            CheckDisposed();
 
            _tempStream.SetLength(newLength);
 
            // truncation always involves change of stream pointer 
            if (newLength < _tempStream.Position)
                _tempStream.Position = newLength; 

            _dirty = true;
        }
 
        /// 
        /// Write 
        ///  
        public override void Write(byte[] buffer, int offset, int count)
        { 
            CheckDisposed();

            PackagingUtilities.VerifyStreamWriteArgs(this, buffer, offset, count);
 
            // no-op
            if (count == 0) 
                return; 

            _tempStream.Write(buffer, offset, count); 
            _dirty = true;
        }

        ///  
        /// Flush
        ///  
        /// Flushes to stream (if necessary) 
        public override void Flush()
        { 
            CheckDisposed();

            if (_dirty)
            { 
                // don't disturb our current position
                long tempPosition = _tempStream.Position; 
 
                // compress
                _tempStream.Position = 0; 
                _baseStream.Position = 0;
                _transformer.Compress(_tempStream, _baseStream);

                // restore 
                _tempStream.Position = tempPosition;
 
                _baseStream.Flush(); 
                _dirty = false;
            } 
        }
        #endregion Stream Methods

        #region Stream Properties 
        /// 
        /// Current logical position within the stream 
        ///  
        public override long Position
        { 
            get
            {
                CheckDisposed();
                return _tempStream.Position; 
            }
            set 
            { 
                CheckDisposed();
 
                if (value < 0)
                    throw new ArgumentException(SR.Get(SRID.SeekNegative));

                _tempStream.Position = value; 
            }
        } 
 
        /// 
        /// Length 
        /// 
        public override long Length
        {
            get 
            {
                CheckDisposed(); 
                return _tempStream.Length; 
            }
        } 

        /// 
        /// Is stream readable?
        ///  
        /// returns false when called on disposed stream
        public override bool CanRead 
        { 
            get
            { 
                return (!_disposed && _baseStream.CanRead);
            }
        }
 
        /// 
        /// Is stream seekable - should be handled by our owner 
        ///  
        /// returns false when called on disposed stream
        public override bool CanSeek 
        {
            get
            {
                return (!_disposed &&  _baseStream.CanSeek); 
            }
        } 
 
        /// 
        /// Is stream writeable? 
        /// 
        /// returns false when called on disposed stream
        public override bool CanWrite
        { 
            get
            { 
                return (!_disposed && _baseStream.CanWrite); 
            }
        } 
        #endregion

        #region Internal
        //------------------------------------------------------ 
        //
        //  Internal Methods 
        // 
        //------------------------------------------------------
        ///  
        /// Constructor
        /// 
        /// part stream - not closed - caller determines lifetime
        /// current logical stream position 
        /// should be an IsolatedStorageFileStream - not closed - caller determines lifetime
        /// class that does the compression/decompression 
        /// This class should only invoked when emulation is required. 
        /// Does not close any given stream, even when Close is called. This means that it requires
        /// another wrapper Stream class. 
        internal CompressEmulationStream(Stream baseStream, Stream tempStream, long position, IDeflateTransform transformer)
        {
            if (position < 0)
                throw new ArgumentOutOfRangeException("position"); 

            if (baseStream == null) 
                throw new ArgumentNullException("baseStream"); 

            // seek and read required for emulation 
            if (!baseStream.CanSeek)
                throw new InvalidOperationException(SR.Get(SRID.SeekNotSupported));

            if (!baseStream.CanRead) 
                throw new InvalidOperationException(SR.Get(SRID.ReadNotSupported));
 
            if (tempStream == null) 
                throw new ArgumentNullException("tempStream");
 
            if (transformer == null)
                throw new ArgumentNullException("transfomer");

            _baseStream = baseStream; 
            _tempStream = tempStream;
            _transformer = transformer; 
 
            // extract to temporary stream
            _baseStream.Position = 0; 
            _tempStream.Position = 0;
            _transformer.Decompress(baseStream, tempStream);

            // seek to the current logical position 
            _tempStream.Position = position;
        } 
        #endregion 

        //----------------------------------------------------- 
        //
        //  Protected Methods
        //
        //------------------------------------------------------ 
        /// 
        /// Dispose(bool) 
        ///  
        /// 
        /// We implement this because we want a consistent experience (essentially Flush our data) if the user chooses to 
        /// call Dispose() instead of Close().
        protected override void Dispose(bool disposing)
        {
            try 
            {
                if (disposing) 
                { 
                    if (!_disposed)
                    { 
                        Flush();

                        _tempStream.Close();
                        _tempStream = null; 

                        // never close base stream - we don't own it 
//                        _baseStream.Close(); 
                        _baseStream = null;
 
                        _disposed = true;
                    }
                }
            } 
            finally
            { 
                base.Dispose(disposing); 
            }
        } 

        /// 
        /// Call this before accepting any public API call (except some Stream calls that
        /// are allowed to respond even when Closed 
        /// 
        protected void CheckDisposed() 
        { 
            if (_disposed)
                throw new ObjectDisposedException(null, SR.Get(SRID.StreamObjectDisposed)); 
        }

        #region Private
        //----------------------------------------------------- 
        //
        //  Private Variables 
        // 
        //-----------------------------------------------------
        private bool    _disposed;          // disposed? 
        private bool    _dirty;             // do we need to recompress?
        protected Stream  _baseStream;      // stream we ultimately decompress from and to in the container
        protected Stream _tempStream;       // temporary storage for the uncompressed stream
        IDeflateTransform _transformer;   // does the actual compress/decompress for us 
        #endregion
    } 
} 

// 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