CFStream.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 / Base / MS / Internal / IO / Packaging / CompoundFile / CFStream.cs / 1305600 / 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 MS.Internal.WindowsBase;

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