CFStream.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 / CompoundFile / CFStream.cs / 1 / CFStream.cs

                            //------------------------------------------------------------------------------ 
//
// 
//    Copyright (C) Microsoft Corporation.  All rights reserved.
//  
//
// Description: 
//   Stream interface for manipulating data within a container stream. 
//
// History: 
//  05/13/2002: RogerCh: Initial implementation.
//  07/31/2002: RogerCh: Make obvious that we are using security suppressed interfaces.
//  05/20/2003: RogerCh: Ported to WCP tree.
// 
//-----------------------------------------------------------------------------
 
using System; 
using System.IO;
using System.Runtime.InteropServices; 
using System.IO.Packaging;

using System.Windows;
 
namespace MS.Internal.IO.Packaging.CompoundFile
{ 
///  
/// Class for manipulating data within container streams
///  
internal class CFStream : Stream
{
    //-----------------------------------------------------
    // 
    //  Public Properties
    // 
    //----------------------------------------------------- 

    ///  
    /// See .NET Framework SDK under System.IO.Stream
    /// 
    public override bool CanRead
    { 
        get
        { 
            return (!StreamDisposed && (FileAccess.Read == (access & FileAccess.Read) || 
                    FileAccess.ReadWrite == (access & FileAccess.ReadWrite)));
        } 
    }

    /// 
    /// See .NET Framework SDK under System.IO.Stream 
    /// 
    public override bool CanSeek 
    { 
        get
        { 
            // OLE32 DocFiles on local disk always seekable
            return (!StreamDisposed);       // unless it's disposed
        }
    } 

    ///  
    /// See .NET Framework SDK under System.IO.Stream 
    /// 
    public override bool CanWrite 
    {
        get
        {
            return (!StreamDisposed && (FileAccess.Write     == (access & FileAccess.Write) || 
                    FileAccess.ReadWrite == (access & FileAccess.ReadWrite)));
        } 
    } 

    ///  
    /// See .NET Framework SDK under System.IO.Stream
    /// 
    public override long Length
    { 
        get
        { 
            CheckDisposedStatus(); 

            System.Runtime.InteropServices.ComTypes.STATSTG streamStat; 

            // STATFLAG_NONAME required on IStream::Stat
            _safeIStream.Stat( out streamStat, SafeNativeCompoundFileConstants.STATFLAG_NONAME );
 
            return streamStat.cbSize;
        } 
    } 

    ///  
    /// See .NET Framework SDK under System.IO.Stream
    /// 
    public override long Position
    { 
        get
        { 
            CheckDisposedStatus(); 

            long seekPos = 0; 

            _safeIStream.Seek(
                0, // Offset of zero
                SafeNativeCompoundFileConstants.STREAM_SEEK_CUR, 
                out seekPos );
 
            return seekPos; 
        }
        set 
        {
            CheckDisposedStatus();

            if (!CanSeek) 
            {
                throw new NotSupportedException(SR.Get(SRID.SetPositionNotSupported)); 
            } 

            long seekPos = 0; 

            _safeIStream.Seek(
                value , // given offset
                SafeNativeCompoundFileConstants.STREAM_SEEK_SET, 
                out seekPos );
 
            if( value != seekPos ) 
            {
                throw new IOException( 
                    SR.Get(SRID.SeekFailed));
            }
        }
    } 

    //------------------------------------------------------ 
    // 
    //  Public Methods
    // 
    //-----------------------------------------------------

    /// 
    /// See .NET Framework SDK under System.IO.Stream 
    /// 
    public override void Flush() 
    { 
        CheckDisposedStatus();
        _safeIStream.Commit(0); 
    }

    /// 
    /// See .NET Framework SDK under System.IO.Stream 
    /// 
    /// Offset byte count 
    /// Offset origin 
    /// 
    public override long Seek( long offset, SeekOrigin origin ) 
    {
        CheckDisposedStatus();

        if (!CanSeek) 
        {
            throw new NotSupportedException(SR.Get(SRID.SeekNotSupported)); 
        } 

        // 
        long seekPos = 0;
        int translatedSeekOrigin = 0;

        switch(origin) 
        {
            case SeekOrigin.Begin: 
                translatedSeekOrigin = SafeNativeCompoundFileConstants.STREAM_SEEK_SET; 
                if( 0 > offset )
                { 
                    throw new ArgumentOutOfRangeException("offset",
                        SR.Get(SRID.SeekNegative));
                }
                break; 
            case SeekOrigin.Current:
                translatedSeekOrigin = SafeNativeCompoundFileConstants.STREAM_SEEK_CUR; 
                // Need to find the current seek pointer to see if we'll end 
                //  up with a negative position.
                break; 
            case SeekOrigin.End:
                translatedSeekOrigin = SafeNativeCompoundFileConstants.STREAM_SEEK_END;
                // Need to find the current seek pointer to see if we'll end
                //  up with a negative position. 
                break;
            default: 
                throw new System.ComponentModel.InvalidEnumArgumentException("origin", (int) origin, typeof(SeekOrigin)); 
        }
 
        _safeIStream.Seek( offset, translatedSeekOrigin, out seekPos );

        return seekPos;
    } 

    ///  
    /// See .NET Framework SDK under System.IO.Stream 
    /// 
    /// New length 
    public override void SetLength( long newLength )
    {
        CheckDisposedStatus();
 
        if (!CanWrite)
        { 
            throw new NotSupportedException(SR.Get(SRID.SetLengthNotSupported)); 
        }
 
        if( 0 > newLength )
        {
            throw new ArgumentOutOfRangeException("newLength",
                SR.Get(SRID.StreamLengthNegative)); 
        }
 
        _safeIStream.SetSize( newLength ); 

        // updating the stream pointer if the stream has been truncated. 
        if (newLength < this.Position)
            this.Position = newLength;
    }
 
    /// 
    /// See .NET Framework SDK under System.IO.Stream 
    ///  
    /// Read data buffer
    /// Buffer start position 
    /// Number of bytes to read
    /// Number of bytes actually read
    public override int Read( byte[] buffer, int offset, int count )
    { 
        CheckDisposedStatus();
 
        PackagingUtilities.VerifyStreamReadArgs(this, buffer, offset, count); 

        int read = 0; 

        if ( 0 == offset ) // Zero offset is typical case
        {
            _safeIStream.Read( buffer, count, out read ); 
        }
        else // Non-zero offset 
        { 
            // Read into local array and then copy it into the given buffer at
            //  the specified offset. 
            byte[] localBuffer = new byte[count];
            _safeIStream.Read( localBuffer, count, out read );

            if (read > 0) 
                Array.Copy(localBuffer, 0, buffer, offset, read);
        } 
 
        return read;
    } 

    /// 
    /// See .NET Framework SDK under System.IO.Stream
    ///  
    /// Data buffer
    /// Buffer write start position 
    /// Number of bytes to write 
    public override void Write( byte[] buffer, int offset, int count )
    { 
        CheckDisposedStatus();

        PackagingUtilities.VerifyStreamWriteArgs(this, buffer, offset, count);
 
        int written = 0; // CLR guys have deemed this uninteresting?
 
        if ( 0 == offset ) // Zero offset is typical case 
        {
            _safeIStream.Write( buffer, count, out written ); 
        }
        else // Non-zero offset
        {
            // Copy from indicated offset to zero-based temp buffer 
            byte[] localBuffer = new byte[count];
            Array.Copy(buffer, offset, localBuffer, 0, count); 
            _safeIStream.Write( localBuffer, count, out written ); 
        }
 
        if( count != written )
            throw new IOException(
                SR.Get(SRID.WriteFailure));
 
    }
 
    //------------------------------------------------------ 
    //
    //  Internal Methods 
    //
    //------------------------------------------------------

    // Check whether this Stream object is still valid.  If not, thrown an 
    //  ObjectDisposedException.
    internal void CheckDisposedStatus() 
    { 
        if( StreamDisposed )
            throw new ObjectDisposedException(null, SR.Get(SRID.StreamObjectDisposed)); 
    }

    // Check whether this Stream object is still valid.
    internal bool StreamDisposed 
    {
        get 
        { 
            return (backReference.StreamInfoDisposed || ( null == _safeIStream ));
        } 
    }

    // Constructors
    internal CFStream( 
        IStream underlyingStream,
        FileAccess openAccess, 
        StreamInfo creator) 
    {
        _safeIStream = underlyingStream; 
        access = openAccess;
        backReference = creator;
    }
 
    //-----------------------------------------------------
    // 
    //  Protected Methods 
    //
    //------------------------------------------------------ 
    /// 
    /// Dispose(bool)
    /// 
    ///  
    protected override void Dispose(bool disposing)
    { 
        try 
        {
            if (disposing) 
            {
                // As per CLR docs for Stream.Close, calls to close on dead stream produces no exceptions.
                if (null != _safeIStream)
                { 
                    // No need to call IStream.Commit, commiting at storage root level
                    //  is sufficient. 
                    // Can't do Marshal.ReleaseComObject() here because there's only 
                    //  one COM ref for each RCW and there may be other users.
                    _safeIStream = null; 
                }
            }
        }
        finally 
        {
            base.Dispose(disposing); 
        } 
    }
 
    //-----------------------------------------------------
    //
    //  Private Members
    // 
    //-----------------------------------------------------
    IStream _safeIStream; 
    FileAccess access; 

    ///  
    /// If only this stream object is held open, and the rest of the container
    /// has not been explicitly closed, we need this to keep the rest of the
    /// tree open because the CLR GC doesn't realize that our IStream has
    /// a dependency on the rest of the container object tree. 
    /// 
    StreamInfo backReference; 
 
}
} 

// 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: 
//   Stream interface for manipulating data within a container stream. 
//
// History: 
//  05/13/2002: RogerCh: Initial implementation.
//  07/31/2002: RogerCh: Make obvious that we are using security suppressed interfaces.
//  05/20/2003: RogerCh: Ported to WCP tree.
// 
//-----------------------------------------------------------------------------
 
using System; 
using System.IO;
using System.Runtime.InteropServices; 
using System.IO.Packaging;

using System.Windows;
 
namespace MS.Internal.IO.Packaging.CompoundFile
{ 
///  
/// Class for manipulating data within container streams
///  
internal class CFStream : Stream
{
    //-----------------------------------------------------
    // 
    //  Public Properties
    // 
    //----------------------------------------------------- 

    ///  
    /// See .NET Framework SDK under System.IO.Stream
    /// 
    public override bool CanRead
    { 
        get
        { 
            return (!StreamDisposed && (FileAccess.Read == (access & FileAccess.Read) || 
                    FileAccess.ReadWrite == (access & FileAccess.ReadWrite)));
        } 
    }

    /// 
    /// See .NET Framework SDK under System.IO.Stream 
    /// 
    public override bool CanSeek 
    { 
        get
        { 
            // OLE32 DocFiles on local disk always seekable
            return (!StreamDisposed);       // unless it's disposed
        }
    } 

    ///  
    /// See .NET Framework SDK under System.IO.Stream 
    /// 
    public override bool CanWrite 
    {
        get
        {
            return (!StreamDisposed && (FileAccess.Write     == (access & FileAccess.Write) || 
                    FileAccess.ReadWrite == (access & FileAccess.ReadWrite)));
        } 
    } 

    ///  
    /// See .NET Framework SDK under System.IO.Stream
    /// 
    public override long Length
    { 
        get
        { 
            CheckDisposedStatus(); 

            System.Runtime.InteropServices.ComTypes.STATSTG streamStat; 

            // STATFLAG_NONAME required on IStream::Stat
            _safeIStream.Stat( out streamStat, SafeNativeCompoundFileConstants.STATFLAG_NONAME );
 
            return streamStat.cbSize;
        } 
    } 

    ///  
    /// See .NET Framework SDK under System.IO.Stream
    /// 
    public override long Position
    { 
        get
        { 
            CheckDisposedStatus(); 

            long seekPos = 0; 

            _safeIStream.Seek(
                0, // Offset of zero
                SafeNativeCompoundFileConstants.STREAM_SEEK_CUR, 
                out seekPos );
 
            return seekPos; 
        }
        set 
        {
            CheckDisposedStatus();

            if (!CanSeek) 
            {
                throw new NotSupportedException(SR.Get(SRID.SetPositionNotSupported)); 
            } 

            long seekPos = 0; 

            _safeIStream.Seek(
                value , // given offset
                SafeNativeCompoundFileConstants.STREAM_SEEK_SET, 
                out seekPos );
 
            if( value != seekPos ) 
            {
                throw new IOException( 
                    SR.Get(SRID.SeekFailed));
            }
        }
    } 

    //------------------------------------------------------ 
    // 
    //  Public Methods
    // 
    //-----------------------------------------------------

    /// 
    /// See .NET Framework SDK under System.IO.Stream 
    /// 
    public override void Flush() 
    { 
        CheckDisposedStatus();
        _safeIStream.Commit(0); 
    }

    /// 
    /// See .NET Framework SDK under System.IO.Stream 
    /// 
    /// Offset byte count 
    /// Offset origin 
    /// 
    public override long Seek( long offset, SeekOrigin origin ) 
    {
        CheckDisposedStatus();

        if (!CanSeek) 
        {
            throw new NotSupportedException(SR.Get(SRID.SeekNotSupported)); 
        } 

        // 
        long seekPos = 0;
        int translatedSeekOrigin = 0;

        switch(origin) 
        {
            case SeekOrigin.Begin: 
                translatedSeekOrigin = SafeNativeCompoundFileConstants.STREAM_SEEK_SET; 
                if( 0 > offset )
                { 
                    throw new ArgumentOutOfRangeException("offset",
                        SR.Get(SRID.SeekNegative));
                }
                break; 
            case SeekOrigin.Current:
                translatedSeekOrigin = SafeNativeCompoundFileConstants.STREAM_SEEK_CUR; 
                // Need to find the current seek pointer to see if we'll end 
                //  up with a negative position.
                break; 
            case SeekOrigin.End:
                translatedSeekOrigin = SafeNativeCompoundFileConstants.STREAM_SEEK_END;
                // Need to find the current seek pointer to see if we'll end
                //  up with a negative position. 
                break;
            default: 
                throw new System.ComponentModel.InvalidEnumArgumentException("origin", (int) origin, typeof(SeekOrigin)); 
        }
 
        _safeIStream.Seek( offset, translatedSeekOrigin, out seekPos );

        return seekPos;
    } 

    ///  
    /// See .NET Framework SDK under System.IO.Stream 
    /// 
    /// New length 
    public override void SetLength( long newLength )
    {
        CheckDisposedStatus();
 
        if (!CanWrite)
        { 
            throw new NotSupportedException(SR.Get(SRID.SetLengthNotSupported)); 
        }
 
        if( 0 > newLength )
        {
            throw new ArgumentOutOfRangeException("newLength",
                SR.Get(SRID.StreamLengthNegative)); 
        }
 
        _safeIStream.SetSize( newLength ); 

        // updating the stream pointer if the stream has been truncated. 
        if (newLength < this.Position)
            this.Position = newLength;
    }
 
    /// 
    /// See .NET Framework SDK under System.IO.Stream 
    ///  
    /// Read data buffer
    /// Buffer start position 
    /// Number of bytes to read
    /// Number of bytes actually read
    public override int Read( byte[] buffer, int offset, int count )
    { 
        CheckDisposedStatus();
 
        PackagingUtilities.VerifyStreamReadArgs(this, buffer, offset, count); 

        int read = 0; 

        if ( 0 == offset ) // Zero offset is typical case
        {
            _safeIStream.Read( buffer, count, out read ); 
        }
        else // Non-zero offset 
        { 
            // Read into local array and then copy it into the given buffer at
            //  the specified offset. 
            byte[] localBuffer = new byte[count];
            _safeIStream.Read( localBuffer, count, out read );

            if (read > 0) 
                Array.Copy(localBuffer, 0, buffer, offset, read);
        } 
 
        return read;
    } 

    /// 
    /// See .NET Framework SDK under System.IO.Stream
    ///  
    /// Data buffer
    /// Buffer write start position 
    /// Number of bytes to write 
    public override void Write( byte[] buffer, int offset, int count )
    { 
        CheckDisposedStatus();

        PackagingUtilities.VerifyStreamWriteArgs(this, buffer, offset, count);
 
        int written = 0; // CLR guys have deemed this uninteresting?
 
        if ( 0 == offset ) // Zero offset is typical case 
        {
            _safeIStream.Write( buffer, count, out written ); 
        }
        else // Non-zero offset
        {
            // Copy from indicated offset to zero-based temp buffer 
            byte[] localBuffer = new byte[count];
            Array.Copy(buffer, offset, localBuffer, 0, count); 
            _safeIStream.Write( localBuffer, count, out written ); 
        }
 
        if( count != written )
            throw new IOException(
                SR.Get(SRID.WriteFailure));
 
    }
 
    //------------------------------------------------------ 
    //
    //  Internal Methods 
    //
    //------------------------------------------------------

    // Check whether this Stream object is still valid.  If not, thrown an 
    //  ObjectDisposedException.
    internal void CheckDisposedStatus() 
    { 
        if( StreamDisposed )
            throw new ObjectDisposedException(null, SR.Get(SRID.StreamObjectDisposed)); 
    }

    // Check whether this Stream object is still valid.
    internal bool StreamDisposed 
    {
        get 
        { 
            return (backReference.StreamInfoDisposed || ( null == _safeIStream ));
        } 
    }

    // Constructors
    internal CFStream( 
        IStream underlyingStream,
        FileAccess openAccess, 
        StreamInfo creator) 
    {
        _safeIStream = underlyingStream; 
        access = openAccess;
        backReference = creator;
    }
 
    //-----------------------------------------------------
    // 
    //  Protected Methods 
    //
    //------------------------------------------------------ 
    /// 
    /// Dispose(bool)
    /// 
    ///  
    protected override void Dispose(bool disposing)
    { 
        try 
        {
            if (disposing) 
            {
                // As per CLR docs for Stream.Close, calls to close on dead stream produces no exceptions.
                if (null != _safeIStream)
                { 
                    // No need to call IStream.Commit, commiting at storage root level
                    //  is sufficient. 
                    // Can't do Marshal.ReleaseComObject() here because there's only 
                    //  one COM ref for each RCW and there may be other users.
                    _safeIStream = null; 
                }
            }
        }
        finally 
        {
            base.Dispose(disposing); 
        } 
    }
 
    //-----------------------------------------------------
    //
    //  Private Members
    // 
    //-----------------------------------------------------
    IStream _safeIStream; 
    FileAccess access; 

    ///  
    /// If only this stream object is held open, and the rest of the container
    /// has not been explicitly closed, we need this to keep the rest of the
    /// tree open because the CLR GC doesn't realize that our IStream has
    /// a dependency on the rest of the container object tree. 
    /// 
    StreamInfo backReference; 
 
}
} 

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