ManagedIStream.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 / Framework / MS / Internal / IO / Packaging / ManagedIStream.cs / 1 / ManagedIStream.cs

                            //---------------------------------------------------------------------------- 
//
// 
//    Copyright (C) Microsoft Corporation.  All rights reserved.
//  
//
// Description: 
//              Implements an IStream component initialized from an 
//              object of type System.IO.Stream.
// 
// History:
//  03/28/2004: JohnLarc: Initial implementation
//---------------------------------------------------------------------------
 
using System;
using System.IO; 
using System.Diagnostics;                           // for Assert 
using System.IO.Packaging;                          // for native APIs
using System.Runtime.InteropServices;               // for Marshal, COMException, etc. 
using System.Runtime.InteropServices.ComTypes;      // for IStream
using System.Windows;                               // for ExceptionStringTable
using System.Security;                              // for SecurityCritical
 
using MS.Win32;                                     // for NativeMethods
 
namespace MS.Internal.IO.Packaging 
{
    // The class ManagedIStream is not COM-visible. Its purpose is to be able to invoke COM interfaces 
    // from managed code rather than the contrary.
    internal class ManagedIStream : IStream
    {
        ///  
        /// Constructor
        ///  
        internal ManagedIStream(Stream ioStream) 
        {
            if (ioStream == null) 
            {
                throw new ArgumentNullException("ioStream");
            }
            _ioStream = ioStream; 
        }
 
        ///  
        /// Read at most bufferSize bytes into buffer and return the effective
        /// number of bytes read in bytesReadPtr (unless null). 
        /// 
        /// 
        /// mscorlib disassembly shows the following MarshalAs parameters
        /// void Read([Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)] byte[] pv, int cb, IntPtr pcbRead); 
        /// This means marshaling code will have found the size of the array buffer in the parameter bufferSize.
        ///  
        /// 
        ///     Critical: calls Marshal.WriteInt32 which LinkDemands, takes pointers as input
        /// 
        [SecurityCritical]
        void IStream.Read(Byte[] buffer, Int32 bufferSize, IntPtr bytesReadPtr)
        {
            Int32 bytesRead = _ioStream.Read(buffer, 0, (int) bufferSize); 
            if (bytesReadPtr != IntPtr.Zero)
            { 
                Marshal.WriteInt32(bytesReadPtr, bytesRead); 
            }
        } 

        /// 
        /// Move the stream pointer to the specified position.
        ///  
        /// 
        /// System.IO.stream supports searching past the end of the stream, like 
        /// OLE streams. 
        /// newPositionPtr is not an out parameter because the method is required
        /// to accept NULL pointers. 
        /// 
        ///
        ///     Critical: calls Marshal.WriteInt64 which LinkDemands, takes pointers as input
        /// 
        [SecurityCritical]
        void IStream.Seek(Int64 offset, Int32 origin, IntPtr newPositionPtr) 
        { 
            SeekOrigin  seekOrigin;
 
            // The operation will generally be I/O bound, so there is no point in
            // eliminating the following switch by playing on the fact that
            // System.IO uses the same integer values as IStream for SeekOrigin.
            switch(origin) 
            {
                case NativeMethods.STREAM_SEEK_SET: 
                    seekOrigin = SeekOrigin.Begin; 
                    break;
                case NativeMethods.STREAM_SEEK_CUR: 
                    seekOrigin = SeekOrigin.Current;
                    break;
                case NativeMethods.STREAM_SEEK_END:
                    seekOrigin = SeekOrigin.End; 
                    break;
                default: 
                    throw new ArgumentOutOfRangeException("origin"); 
            }
            long position = _ioStream.Seek(offset, seekOrigin); 

            // Dereference newPositionPtr and assign to the pointed location.
            if (newPositionPtr != IntPtr.Zero)
            { 
                Marshal.WriteInt64(newPositionPtr, position);
            } 
        } 

        ///  
        /// Sets stream's size.
        /// 
        void IStream.SetSize(Int64 libNewSize)
        { 
            _ioStream.SetLength(libNewSize);
        } 
 
        /// 
        /// Obtain stream stats. 
        /// 
        /// 
        /// STATSG has to be qualified because it is defined both in System.Runtime.InteropServices and
        /// System.Runtime.InteropServices.ComTypes. 
        /// The STATSTG structure is shared by streams, storages and byte arrays. Members irrelevant to streams
        /// or not available from System.IO.Stream are not returned, which leaves only cbSize and grfMode as 
        /// meaningful and available pieces of information. 
        /// grfStatFlag is used to indicate whether the stream name should be returned and is ignored because
        /// this information is unavailable. 
        /// 
        void IStream.Stat(out System.Runtime.InteropServices.ComTypes.STATSTG streamStats, int grfStatFlag)
        {
            streamStats = new System.Runtime.InteropServices.ComTypes.STATSTG(); 
            streamStats.type = NativeMethods.STGTY_STREAM;
            streamStats.cbSize = _ioStream.Length; 
 
            // Return access information in grfMode.
            streamStats.grfMode = 0; // default value for each flag will be false 
            if (_ioStream.CanRead && _ioStream.CanWrite)
            {
                streamStats.grfMode |= NativeMethods.STGM_READWRITE;
            } 
            else if (_ioStream.CanRead)
            { 
                streamStats.grfMode |= NativeMethods.STGM_READ; 
            }
            else if (_ioStream.CanWrite) 
            {
                streamStats.grfMode |= NativeMethods.STGM_WRITE;
            }
            else 
            {
                // A stream that is neither readable nor writable is a closed stream. 
                // Note the use of an exception that is known to the interop marshaller 
                // (unlike ObjectDisposedException).
                throw new IOException(SR.Get(SRID.StreamObjectDisposed)); 
            }
        }

        ///  
        /// Write at most bufferSize bytes from buffer.
        ///  
        /// 
        ///     Critical: calls Marshal.WriteInt32 which LinkDemands, takes pointers as input
        /// 
        [SecurityCritical]
        void IStream.Write(Byte[] buffer, Int32 bufferSize, IntPtr bytesWrittenPtr)
        {
            _ioStream.Write(buffer, 0, bufferSize); 
            if (bytesWrittenPtr != IntPtr.Zero)
            { 
                // If fewer than bufferSize bytes had been written, an exception would 
                // have been thrown, so it can be assumed we wrote bufferSize bytes.
                Marshal.WriteInt32(bytesWrittenPtr, bufferSize); 
            }
        }

        #region Unimplemented methods 
        /// 
        /// Create a clone. 
        ///  
        /// 
        /// Not implemented. 
        /// 
        void IStream.Clone(out IStream streamCopy)
        {
            streamCopy = null; 
            throw new NotSupportedException();
        } 
 
        /// 
        /// Read at most bufferSize bytes from the receiver and write them to targetStream. 
        /// 
        /// 
        /// Not implemented.
        ///  
        void IStream.CopyTo(IStream targetStream, Int64 bufferSize, IntPtr buffer, IntPtr bytesWrittenPtr)
        { 
            throw new NotSupportedException(); 
        }
 
        /// 
        /// Commit changes.
        /// 
        ///  
        /// Only relevant to transacted streams.
        ///  
        void IStream.Commit(Int32 flags) 
        {
            throw new NotSupportedException(); 
        }

        /// 
        /// Lock at most byteCount bytes starting at offset. 
        /// 
        ///  
        /// Not supported by System.IO.Stream. 
        /// 
        void IStream.LockRegion(Int64 offset, Int64 byteCount, Int32 lockType) 
        {
            throw new NotSupportedException();
        }
 
        /// 
        /// Undo writes performed since last Commit. 
        ///  
        /// 
        /// Relevant only to transacted streams. 
        /// 
        void IStream.Revert()
        {
            throw new NotSupportedException(); 
        }
 
        ///  
        /// Unlock the specified region.
        ///  
        /// 
        /// Not supported by System.IO.Stream.
        /// 
        void IStream.UnlockRegion(Int64 offset, Int64 byteCount, Int32 lockType) 
        {
            throw new NotSupportedException(); 
        } 
        #endregion Unimplemented methods
 
        #region Fields
        private Stream      _ioStream;
        #endregion Fields
    } 
}

// 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: 
//              Implements an IStream component initialized from an 
//              object of type System.IO.Stream.
// 
// History:
//  03/28/2004: JohnLarc: Initial implementation
//---------------------------------------------------------------------------
 
using System;
using System.IO; 
using System.Diagnostics;                           // for Assert 
using System.IO.Packaging;                          // for native APIs
using System.Runtime.InteropServices;               // for Marshal, COMException, etc. 
using System.Runtime.InteropServices.ComTypes;      // for IStream
using System.Windows;                               // for ExceptionStringTable
using System.Security;                              // for SecurityCritical
 
using MS.Win32;                                     // for NativeMethods
 
namespace MS.Internal.IO.Packaging 
{
    // The class ManagedIStream is not COM-visible. Its purpose is to be able to invoke COM interfaces 
    // from managed code rather than the contrary.
    internal class ManagedIStream : IStream
    {
        ///  
        /// Constructor
        ///  
        internal ManagedIStream(Stream ioStream) 
        {
            if (ioStream == null) 
            {
                throw new ArgumentNullException("ioStream");
            }
            _ioStream = ioStream; 
        }
 
        ///  
        /// Read at most bufferSize bytes into buffer and return the effective
        /// number of bytes read in bytesReadPtr (unless null). 
        /// 
        /// 
        /// mscorlib disassembly shows the following MarshalAs parameters
        /// void Read([Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)] byte[] pv, int cb, IntPtr pcbRead); 
        /// This means marshaling code will have found the size of the array buffer in the parameter bufferSize.
        ///  
        /// 
        ///     Critical: calls Marshal.WriteInt32 which LinkDemands, takes pointers as input
        /// 
        [SecurityCritical]
        void IStream.Read(Byte[] buffer, Int32 bufferSize, IntPtr bytesReadPtr)
        {
            Int32 bytesRead = _ioStream.Read(buffer, 0, (int) bufferSize); 
            if (bytesReadPtr != IntPtr.Zero)
            { 
                Marshal.WriteInt32(bytesReadPtr, bytesRead); 
            }
        } 

        /// 
        /// Move the stream pointer to the specified position.
        ///  
        /// 
        /// System.IO.stream supports searching past the end of the stream, like 
        /// OLE streams. 
        /// newPositionPtr is not an out parameter because the method is required
        /// to accept NULL pointers. 
        /// 
        ///
        ///     Critical: calls Marshal.WriteInt64 which LinkDemands, takes pointers as input
        /// 
        [SecurityCritical]
        void IStream.Seek(Int64 offset, Int32 origin, IntPtr newPositionPtr) 
        { 
            SeekOrigin  seekOrigin;
 
            // The operation will generally be I/O bound, so there is no point in
            // eliminating the following switch by playing on the fact that
            // System.IO uses the same integer values as IStream for SeekOrigin.
            switch(origin) 
            {
                case NativeMethods.STREAM_SEEK_SET: 
                    seekOrigin = SeekOrigin.Begin; 
                    break;
                case NativeMethods.STREAM_SEEK_CUR: 
                    seekOrigin = SeekOrigin.Current;
                    break;
                case NativeMethods.STREAM_SEEK_END:
                    seekOrigin = SeekOrigin.End; 
                    break;
                default: 
                    throw new ArgumentOutOfRangeException("origin"); 
            }
            long position = _ioStream.Seek(offset, seekOrigin); 

            // Dereference newPositionPtr and assign to the pointed location.
            if (newPositionPtr != IntPtr.Zero)
            { 
                Marshal.WriteInt64(newPositionPtr, position);
            } 
        } 

        ///  
        /// Sets stream's size.
        /// 
        void IStream.SetSize(Int64 libNewSize)
        { 
            _ioStream.SetLength(libNewSize);
        } 
 
        /// 
        /// Obtain stream stats. 
        /// 
        /// 
        /// STATSG has to be qualified because it is defined both in System.Runtime.InteropServices and
        /// System.Runtime.InteropServices.ComTypes. 
        /// The STATSTG structure is shared by streams, storages and byte arrays. Members irrelevant to streams
        /// or not available from System.IO.Stream are not returned, which leaves only cbSize and grfMode as 
        /// meaningful and available pieces of information. 
        /// grfStatFlag is used to indicate whether the stream name should be returned and is ignored because
        /// this information is unavailable. 
        /// 
        void IStream.Stat(out System.Runtime.InteropServices.ComTypes.STATSTG streamStats, int grfStatFlag)
        {
            streamStats = new System.Runtime.InteropServices.ComTypes.STATSTG(); 
            streamStats.type = NativeMethods.STGTY_STREAM;
            streamStats.cbSize = _ioStream.Length; 
 
            // Return access information in grfMode.
            streamStats.grfMode = 0; // default value for each flag will be false 
            if (_ioStream.CanRead && _ioStream.CanWrite)
            {
                streamStats.grfMode |= NativeMethods.STGM_READWRITE;
            } 
            else if (_ioStream.CanRead)
            { 
                streamStats.grfMode |= NativeMethods.STGM_READ; 
            }
            else if (_ioStream.CanWrite) 
            {
                streamStats.grfMode |= NativeMethods.STGM_WRITE;
            }
            else 
            {
                // A stream that is neither readable nor writable is a closed stream. 
                // Note the use of an exception that is known to the interop marshaller 
                // (unlike ObjectDisposedException).
                throw new IOException(SR.Get(SRID.StreamObjectDisposed)); 
            }
        }

        ///  
        /// Write at most bufferSize bytes from buffer.
        ///  
        /// 
        ///     Critical: calls Marshal.WriteInt32 which LinkDemands, takes pointers as input
        /// 
        [SecurityCritical]
        void IStream.Write(Byte[] buffer, Int32 bufferSize, IntPtr bytesWrittenPtr)
        {
            _ioStream.Write(buffer, 0, bufferSize); 
            if (bytesWrittenPtr != IntPtr.Zero)
            { 
                // If fewer than bufferSize bytes had been written, an exception would 
                // have been thrown, so it can be assumed we wrote bufferSize bytes.
                Marshal.WriteInt32(bytesWrittenPtr, bufferSize); 
            }
        }

        #region Unimplemented methods 
        /// 
        /// Create a clone. 
        ///  
        /// 
        /// Not implemented. 
        /// 
        void IStream.Clone(out IStream streamCopy)
        {
            streamCopy = null; 
            throw new NotSupportedException();
        } 
 
        /// 
        /// Read at most bufferSize bytes from the receiver and write them to targetStream. 
        /// 
        /// 
        /// Not implemented.
        ///  
        void IStream.CopyTo(IStream targetStream, Int64 bufferSize, IntPtr buffer, IntPtr bytesWrittenPtr)
        { 
            throw new NotSupportedException(); 
        }
 
        /// 
        /// Commit changes.
        /// 
        ///  
        /// Only relevant to transacted streams.
        ///  
        void IStream.Commit(Int32 flags) 
        {
            throw new NotSupportedException(); 
        }

        /// 
        /// Lock at most byteCount bytes starting at offset. 
        /// 
        ///  
        /// Not supported by System.IO.Stream. 
        /// 
        void IStream.LockRegion(Int64 offset, Int64 byteCount, Int32 lockType) 
        {
            throw new NotSupportedException();
        }
 
        /// 
        /// Undo writes performed since last Commit. 
        ///  
        /// 
        /// Relevant only to transacted streams. 
        /// 
        void IStream.Revert()
        {
            throw new NotSupportedException(); 
        }
 
        ///  
        /// Unlock the specified region.
        ///  
        /// 
        /// Not supported by System.IO.Stream.
        /// 
        void IStream.UnlockRegion(Int64 offset, Int64 byteCount, Int32 lockType) 
        {
            throw new NotSupportedException(); 
        } 
        #endregion Unimplemented methods
 
        #region Fields
        private Stream      _ioStream;
        #endregion Fields
    } 
}

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