UnmanagedMemoryAccessor.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 / ndp / clr / src / BCL / System / IO / UnmanagedMemoryAccessor.cs / 1305376 / UnmanagedMemoryAccessor.cs

                            // ==++== 
//
//   Copyright (c) Microsoft Corporation.  All rights reserved.
//
// ==--== 
/*============================================================
** 
** Class:  UnmanagedMemoryAccessor 
**
** [....] 
**
** Purpose: Provides a fast, AV free, cross-language way of
**          accessing unmanaged memory in a random fashion.
** 
** Date:  February 7, 2007
** 
===========================================================*/ 

using System; 
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using System.Runtime.ConstrainedExecution;
using System.Runtime.Versioning; 
using System.Security.Permissions;
using Microsoft.Win32.SafeHandles; 
using System.Diagnostics.Contracts; 

namespace System.IO { 

    /// Perf notes: ReadXXX, WriteXXX (for basic types) acquire and release the
    /// SafeBuffer pointer rather than relying on generic Read(T) from SafeBuffer because
    /// this gives better throughput; benchmarks showed about 12-15% better. 
    public class UnmanagedMemoryAccessor : IDisposable {
 
        [System.Security.SecurityCritical /*auto-generated*/] 
        private SafeBuffer _buffer;
        private Int64 _offset; 
        [ContractPublicPropertyName("Capacity")]
        private Int64 _capacity;
        private FileAccess _access;
        private bool _isOpen; 
        private bool _canRead;
        private bool _canWrite; 
 
        protected UnmanagedMemoryAccessor() {
            _isOpen = false; 
        }

        #region SafeBuffer ctors and initializers
        //  
        // 
        //  
        [System.Security.SecuritySafeCritical] 
        public UnmanagedMemoryAccessor(SafeBuffer buffer, Int64 offset, Int64 capacity) {
            Initialize(buffer, offset, capacity, FileAccess.Read); 
        }

        [System.Security.SecuritySafeCritical]  // auto-generated
        public UnmanagedMemoryAccessor(SafeBuffer buffer, Int64 offset, Int64 capacity, FileAccess access) { 
            Initialize(buffer, offset, capacity, access);
        } 
 
        [System.Security.SecuritySafeCritical]  // auto-generated
        [SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)] 
        protected void Initialize(SafeBuffer buffer, Int64 offset, Int64 capacity, FileAccess access) {
            if (buffer == null) {
                throw new ArgumentNullException("buffer");
            } 
            if (offset < 0) {
                throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); 
            } 
            if (capacity < 0) {
                throw new ArgumentOutOfRangeException("capacity", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); 
            }
            if (buffer.ByteLength < (UInt64)(offset + capacity)) {
                throw new ArgumentException(Environment.GetResourceString("Argument_OffsetAndCapacityOutOfBounds"));
            } 
            if (access < FileAccess.Read || access > FileAccess.ReadWrite) {
                throw new ArgumentOutOfRangeException("access"); 
            } 
            Contract.EndContractBlock();
 
            if (_isOpen) {
                throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CalledTwice"));
            }
 
            unsafe {
                byte* pointer = null; 
                RuntimeHelpers.PrepareConstrainedRegions(); 
                try {
                    buffer.AcquirePointer(ref pointer); 
                    if (((byte*)((Int64)pointer + offset + capacity)) < pointer) {
                        throw new ArgumentException(Environment.GetResourceString("Argument_UnmanagedMemAccessorWrapAround"));
                    }
                } 
                finally {
                    if (pointer != null) { 
                        buffer.ReleasePointer(); 
                    }
                } 
            }

            _offset = offset;
            _buffer = buffer; 
            _capacity = capacity;
            _access = access; 
            _isOpen = true; 
            _canRead = (_access & FileAccess.Read) != 0;
            _canWrite = (_access & FileAccess.Write) != 0; 
        }

        #endregion
 
        public Int64 Capacity {
            get { 
                return _capacity; 
            }
        } 

        public bool CanRead {
            get {
                return _isOpen && _canRead; 
            }
        } 
 
        public bool CanWrite {
            get { 
                return _isOpen && _canWrite;
            }
        }
 
        protected virtual void Dispose(bool disposing) {
            _isOpen = false; 
        } 

        public void Dispose() { 
            Dispose(true);
            GC.SuppressFinalize(this);
        }
 
        protected bool IsOpen {
            get { return _isOpen; } 
        } 

        public bool ReadBoolean(Int64 position) { 
            int sizeOfType = sizeof(bool);
            EnsureSafeToRead(position, sizeOfType);

            byte b = InternalReadByte(position); 
            return b != 0;
        } 
 
        public byte ReadByte(Int64 position) {
            int sizeOfType = sizeof(byte); 
            EnsureSafeToRead(position, sizeOfType);

            return InternalReadByte(position);
        } 

        [System.Security.SecuritySafeCritical]  // auto-generated 
        public char ReadChar(Int64 position) { 
            int sizeOfType = sizeof(char);
            EnsureSafeToRead(position, sizeOfType); 

            char result;

            unsafe { 
                byte* pointer = null;
                RuntimeHelpers.PrepareConstrainedRegions(); 
                try { 
                    _buffer.AcquirePointer(ref pointer);
                    pointer += (_offset + position); 

#if IA64
                    // check if pointer is aligned
                    if (((int)pointer & (sizeOfType - 1)) == 0) { 
#endif
                        result = *((char*)(pointer)); 
#if IA64 
                    }
                    else { 
                        result = (char)( *pointer | *(pointer + 1) << 8 ) ;
                    }
#endif
                } 
                finally {
                    if (pointer != null) { 
                        _buffer.ReleasePointer(); 
                    }
                } 
            }

            return result;
        } 

        // See comment above. 
        [System.Security.SecuritySafeCritical] 
        public Int16 ReadInt16(Int64 position) {
            int sizeOfType = sizeof(Int16); 
            EnsureSafeToRead(position, sizeOfType);

            Int16 result;
 
            unsafe {
                byte* pointer = null; 
                RuntimeHelpers.PrepareConstrainedRegions(); 
                try {
                    _buffer.AcquirePointer(ref pointer); 
                    pointer += (_offset + position);

#if IA64
                    // check if pointer is aligned 
                    if (((int)pointer & (sizeOfType - 1)) == 0) {
#endif 
                        result = *((Int16*)(pointer)); 
#if IA64
                    } 
                    else {
                        result = (Int16)( *pointer | *(pointer + 1) << 8 );
                    }
#endif 
                }
                finally { 
                    if (pointer != null) { 
                        _buffer.ReleasePointer();
                    } 
                }
            }

            return result; 
        }
 
 
        [System.Security.SecuritySafeCritical]  // auto-generated
        public Int32 ReadInt32(Int64 position) { 
            int sizeOfType = sizeof(Int32);
            EnsureSafeToRead(position, sizeOfType);

            Int32 result; 
            unsafe {
                byte* pointer = null; 
                RuntimeHelpers.PrepareConstrainedRegions(); 
                try {
                    _buffer.AcquirePointer(ref pointer); 
                    pointer += (_offset + position);

#if IA64
                    // check if pointer is aligned 
                    if (((int)pointer & (sizeOfType - 1)) == 0) {
#endif 
                        result = *((Int32*)(pointer)); 
#if IA64
                    } 
                    else {
                        result = (Int32)( *pointer | *(pointer + 1) << 8 | *(pointer + 2) << 16 | *(pointer + 3) << 24 );
                    }
#endif 
                }
                finally { 
                    if (pointer != null) { 
                        _buffer.ReleasePointer();
                    } 
                }
            }

            return result; 
        }
 
        [System.Security.SecuritySafeCritical]  // auto-generated 
        public Int64 ReadInt64(Int64 position) {
            int sizeOfType = sizeof(Int64); 
            EnsureSafeToRead(position, sizeOfType);

            Int64 result;
            unsafe { 
                byte* pointer = null;
                RuntimeHelpers.PrepareConstrainedRegions(); 
                try { 
                    _buffer.AcquirePointer(ref pointer);
                    pointer += (_offset + position); 

#if IA64
                    // check if pointer is aligned
                    if (((int)pointer & (sizeOfType - 1)) == 0) { 
#endif
                        result = *((Int64*)(pointer)); 
#if IA64 
                    }
                    else { 
                        int lo = *pointer | *(pointer + 1) << 8 | *(pointer + 2) << 16 | *(pointer + 3) << 24;
                        int hi = *(pointer + 4) | *(pointer + 5) << 8 | *(pointer + 6) << 16 | *(pointer + 7) << 24;
                        result = (Int64)(((Int64)hi << 32) | (UInt32)lo);
                    } 
#endif
                    } 
                finally { 
                    if (pointer != null) {
                        _buffer.ReleasePointer(); 
                    }
                }
            }
 
            return result;
        } 
 
        [System.Security.SecuritySafeCritical]  // auto-generated
        public Decimal ReadDecimal(Int64 position) { 
            int sizeOfType = sizeof(Decimal);
            EnsureSafeToRead(position, sizeOfType);

            int[] decimalArray = new int[4]; 
            ReadArray(position, decimalArray, 0, decimalArray.Length);
 
            return new Decimal(decimalArray); 
        }
 
        [System.Security.SecuritySafeCritical]  // auto-generated
        public Single ReadSingle(Int64 position) {
            int sizeOfType = sizeof(Single);
            EnsureSafeToRead(position, sizeOfType); 

            Single result; 
            unsafe { 
                byte* pointer = null;
                RuntimeHelpers.PrepareConstrainedRegions(); 
                try {
                    _buffer.AcquirePointer(ref pointer);
                    pointer += (_offset + position);
 
#if IA64
                    // check if pointer is aligned 
                    if (((int)pointer & (sizeOfType - 1)) == 0) { 
#endif
                    result = *((Single*)(pointer)); 
#if IA64
                    }
                    else {
                    UInt32 tempResult = (UInt32)( *pointer | *(pointer + 1) << 8 | *(pointer + 2) << 16 | *(pointer + 3) << 24 ); 
                    result = *((float*)&tempResult);
                    } 
#endif 
                }
                finally { 
                    if (pointer != null) {
                        _buffer.ReleasePointer();
                    }
                } 
            }
 
            return result; 
        }
 
        [System.Security.SecuritySafeCritical]  // auto-generated
        public Double ReadDouble(Int64 position) {
            int sizeOfType = sizeof(Double);
            EnsureSafeToRead(position, sizeOfType); 

            Double result; 
            unsafe { 
                byte* pointer = null;
                RuntimeHelpers.PrepareConstrainedRegions(); 
                try {
                    _buffer.AcquirePointer(ref pointer);
                    pointer += (_offset + position);
 
#if IA64
                    // check if pointer is aligned 
                    if (((int)pointer & (sizeOfType - 1)) == 0) { 
#endif
                    result = *((Double*)(pointer)); 
#if IA64
                    }
                    else {
 
                    UInt32 lo = (UInt32)( *pointer | *(pointer + 1) << 8  | *(pointer + 2) << 16 | *(pointer + 3) << 24 );
                    UInt32 hi = (UInt32)( *(pointer + 4) | *(pointer + 5) << 8 | *(pointer + 6) << 16 | *(pointer + 7) << 24 ); 
                    UInt64 tempResult = ((UInt64)hi) << 32 | lo; 
                    result = *((double*)&tempResult);
 
                    }
#endif
                }
                finally { 
                    if (pointer != null) {
                        _buffer.ReleasePointer(); 
                    } 
                }
            } 

            return result;
        }
 
        [System.Security.SecuritySafeCritical]  // auto-generated
        [CLSCompliant(false)] 
        public SByte ReadSByte(Int64 position) { 
            int sizeOfType = sizeof(SByte);
            EnsureSafeToRead(position, sizeOfType); 

            SByte result;
            unsafe {
                byte* pointer = null; 
                RuntimeHelpers.PrepareConstrainedRegions();
                try { 
                    _buffer.AcquirePointer(ref pointer); 
                    pointer += (_offset + position);
                    result = *((SByte*)pointer); 
                }
                finally {
                    if (pointer != null) {
                        _buffer.ReleasePointer(); 
                    }
                } 
            } 

            return result; 
        }

        [System.Security.SecuritySafeCritical]  // auto-generated
        [CLSCompliant(false)] 
        public UInt16 ReadUInt16(Int64 position) {
            int sizeOfType = sizeof(UInt16); 
            EnsureSafeToRead(position, sizeOfType); 

            UInt16 result; 
            unsafe {
                byte* pointer = null;
                RuntimeHelpers.PrepareConstrainedRegions();
                try { 
                    _buffer.AcquirePointer(ref pointer);
                    pointer += (_offset + position); 
 
#if IA64
                    // check if pointer is aligned 
                    if (((int)pointer & (sizeOfType - 1)) == 0) {
#endif
                    result = *((UInt16*)(pointer));
#if IA64 
                    }
                    else { 
                        result = (UInt16)( *pointer | *(pointer + 1) << 8 ); 
                    }
#endif 

                }
                finally {
                    if (pointer != null) { 
                        _buffer.ReleasePointer();
                    } 
                } 
            }
 
            return result;
        }

        [System.Security.SecuritySafeCritical]  // auto-generated 
        [CLSCompliant(false)]
        public UInt32 ReadUInt32(Int64 position) { 
            int sizeOfType = sizeof(UInt32); 
            EnsureSafeToRead(position, sizeOfType);
 
            UInt32 result;
            unsafe {
                byte* pointer = null;
                RuntimeHelpers.PrepareConstrainedRegions(); 
                try {
                    _buffer.AcquirePointer(ref pointer); 
                    pointer += (_offset + position); 

#if IA64 
                    // check if pointer is aligned
                    if (((int)pointer & (sizeOfType - 1)) == 0) {
#endif
                    result = *((UInt32*)(pointer)); 
#if IA64
                    } 
                    else { 
                        result = (UInt32)( *pointer | *(pointer + 1) << 8  | *(pointer + 2) << 16 | *(pointer + 3) << 24 );
                    } 
#endif

                }
                finally { 
                    if (pointer != null) {
                        _buffer.ReleasePointer(); 
                    } 
                }
            } 

            return result;
        }
 
        [System.Security.SecuritySafeCritical]  // auto-generated
        [CLSCompliant(false)] 
        public UInt64 ReadUInt64(Int64 position) { 
            int sizeOfType = sizeof(UInt64);
            EnsureSafeToRead(position, sizeOfType); 

            UInt64 result;
            unsafe {
                byte* pointer = null; 
                RuntimeHelpers.PrepareConstrainedRegions();
                try { 
                    _buffer.AcquirePointer(ref pointer); 
                    pointer += (_offset + position);
 
#if IA64
                    // check if pointer is aligned
                    if (((int)pointer & (sizeOfType - 1)) == 0) {
#endif 
                    result = *((UInt64*)(pointer));
#if IA64 
                    } 
                    else {
                        UInt32 lo = (UInt32)( *pointer | *(pointer + 1) << 8 | *(pointer + 2) << 16 | *(pointer + 3) << 24 ); 
                        UInt32 hi = (UInt32)( *(pointer + 4) | *(pointer + 5) << 8 | *(pointer + 6) << 16 | *(pointer + 7) << 24 );
                        result = (UInt64)(((UInt64)hi << 32) | lo );
                    }
#endif 

                } 
                finally { 
                    if (pointer != null) {
                        _buffer.ReleasePointer(); 
                    }
                }
            }
 
            return result;
        } 
 
        // Reads a struct of type T from unmanaged memory, into the reference pointed to by ref value.
        // Note: this method is not safe, since it overwrites the contents of a structure, it can be 
        // used to modify the private members of a struct.  Furthermore, using this with a struct that
        // contains reference members will most likely cause the runtime to AV.  Note, that despite
        // various checks made by the C++ code used by Marshal.PtrToStructure, Marshal.PtrToStructure
        // will still overwrite privates and will also crash the runtime when used with structs 
        // containing reference members.  For this reason, I am sticking an UnmanagedCode requirement
        // on this method to match Marshal.PtrToStructure. 
 
        // Alos note that this method is most performant when used with medium to large sized structs
        // (larger than 8 bytes -- though this is number is JIT and architecture dependent).   As 
        // such, it is best to use the ReadXXX methods for small standard types such as ints, longs,
        // bools, etc.

        [System.Security.SecurityCritical]  // auto-generated_required 
        public void Read(Int64 position, out T structure) where T : struct {
            if (position < 0) { 
                throw new ArgumentOutOfRangeException("position", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); 
            }
            Contract.EndContractBlock(); 

            if (!_isOpen) {
                throw new ObjectDisposedException("UnmanagedMemoryAccessor", Environment.GetResourceString("ObjectDisposed_ViewAccessorClosed"));
            } 
            if (!CanRead) {
                throw new NotSupportedException(Environment.GetResourceString("NotSupported_Reading")); 
            } 

            UInt32 sizeOfT = Marshal.SizeOf(); 
            if (position > _capacity - sizeOfT) {
                if (position >= _capacity) {
                    throw new ArgumentOutOfRangeException("position", Environment.GetResourceString("ArgumentOutOfRange_PositionLessThanCapacityRequired"));
                } 
                else {
                    throw new ArgumentException(Environment.GetResourceString("Argument_NotEnoughBytesToRead", typeof(T).FullName), "position"); 
                } 
            }
 
            structure = _buffer.Read((UInt64)(_offset + position));
        }

        // Reads 'count' structs of type T from unmanaged memory, into 'array' starting at 'offset'. 
        // Note: this method is not safe, since it overwrites the contents of structures, it can
        // be used to modify the private members of a struct.  Furthermore, using this with a 
        // struct that contains reference members will most likely cause the runtime to AV. This 
        // is consistent with Marshal.PtrToStructure.
 
        [System.Security.SecurityCritical]  // auto-generated_required
        public int ReadArray(Int64 position, T[] array, Int32 offset, Int32 count) where T : struct {
            if (array == null) {
                throw new ArgumentNullException("array", "Buffer cannot be null."); 
            }
            if (offset < 0) { 
                throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); 
            }
            if (count < 0) { 
                throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
            }
            if (array.Length - offset < count) {
                throw new ArgumentException(Environment.GetResourceString("Argument_OffsetAndLengthOutOfBounds")); 
            }
            Contract.EndContractBlock(); 
            if (!CanRead) { 
                if (!_isOpen) {
                    throw new ObjectDisposedException("UnmanagedMemoryAccessor", Environment.GetResourceString("ObjectDisposed_ViewAccessorClosed")); 
                }
                else {
                    throw new NotSupportedException(Environment.GetResourceString("NotSupported_Reading"));
                } 
            }
            if (position < 0) { 
                throw new ArgumentOutOfRangeException("position", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); 
            }
 
            UInt32 sizeOfT = Marshal.AlignedSizeOf();

            // only check position and ask for fewer Ts if count is too big
            if (position >= _capacity) { 
                throw new ArgumentOutOfRangeException("position", Environment.GetResourceString("ArgumentOutOfRange_PositionLessThanCapacityRequired"));
            } 
 
            int n = count;
            long spaceLeft = _capacity - position; 
            if (spaceLeft < 0) {
                n = 0;
            }
            else { 
                ulong spaceNeeded = (ulong)(sizeOfT * count);
                if ((ulong)spaceLeft < spaceNeeded) { 
                    n = (int)(spaceLeft / sizeOfT); 
                }
            } 

            _buffer.ReadArray((UInt64)(_offset + position), array, offset, n);

            return n; 
        }
 
        // ************** Write Methods ****************/ 

        // The following 13 WriteXXX methods write a value of type XXX into unmanaged memory at 'positon'. 
        // The bounds of the unmanaged memory are checked against to ensure that there is enough
        // space after 'position' to write a value of type XXX.  XXX can be a bool, byte, char, decimal,
        // double, short, int, long, sbyte, float, ushort, uint, or ulong.
 

        public void Write(Int64 position, bool value) { 
            int sizeOfType = sizeof(bool); 
            EnsureSafeToWrite(position, sizeOfType);
 
            byte b = (byte)(value ? 1 : 0);
            InternalWrite(position, b);
        }
 
        public void Write(Int64 position, byte value) {
            int sizeOfType = sizeof(byte); 
            EnsureSafeToWrite(position, sizeOfType); 

            InternalWrite(position, value); 
        }

        [System.Security.SecuritySafeCritical]  // auto-generated
        public void Write(Int64 position, char value) { 
            int sizeOfType = sizeof(char);
            EnsureSafeToWrite(position, sizeOfType); 
 
            unsafe {
                byte* pointer = null; 
                RuntimeHelpers.PrepareConstrainedRegions();
                try {
                    _buffer.AcquirePointer(ref pointer);
                    pointer += (_offset + position); 

#if IA64 
                    // check if pointer is aligned 
                    if (((int)pointer & (sizeOfType - 1)) == 0) {
#endif 
                        *((char*)pointer) = value;
#if IA64
                    }
                    else { 
                        *(pointer) = (byte)value;
                        *(pointer+1) = (byte)(value >> 8); 
                    } 
#endif
                } 
                finally {
                    if (pointer != null) {
                        _buffer.ReleasePointer();
                    } 
                }
            } 
 
        }
 

        [System.Security.SecuritySafeCritical]  // auto-generated
        public void Write(Int64 position, Int16 value) {
            int sizeOfType = sizeof(Int16); 
            EnsureSafeToWrite(position, sizeOfType);
 
            unsafe { 
                byte* pointer = null;
                RuntimeHelpers.PrepareConstrainedRegions(); 
                try {
                    _buffer.AcquirePointer(ref pointer);
                    pointer += (_offset + position);
 
#if IA64
                    // check if pointer is aligned 
                    if (((int)pointer & (sizeOfType - 1)) == 0) { 
#endif
                        *((Int16*)pointer) = value; 
#if IA64
                    }
                    else {
                        *(pointer) = (byte)value; 
                        *(pointer + 1) = (byte)(value >> 8);
                    } 
#endif 
                }
                finally { 
                    if (pointer != null) {
                        _buffer.ReleasePointer();
                    }
                } 
            }
        } 
 

        [System.Security.SecuritySafeCritical]  // auto-generated 
        public void Write(Int64 position, Int32 value) {
            int sizeOfType = sizeof(Int32);
            EnsureSafeToWrite(position, sizeOfType);
 
            unsafe {
                byte* pointer = null; 
                RuntimeHelpers.PrepareConstrainedRegions(); 
                try {
                    _buffer.AcquirePointer(ref pointer); 
                    pointer += (_offset + position);

#if IA64
                    // check if pointer is aligned 
                    if (((int)pointer & (sizeOfType - 1)) == 0) {
#endif 
                        *((Int32*)pointer) = value; 
#if IA64
                    } 
                    else {
                        *(pointer) = (byte)value;
                        *(pointer + 1) = (byte)(value >> 8);
                        *(pointer + 2) = (byte)(value >> 16); 
                        *(pointer + 3) = (byte)(value >> 24);
                    } 
#endif 
                }
                finally { 
                    if (pointer != null) {
                        _buffer.ReleasePointer();
                    }
                } 
            }
        } 
 
        [System.Security.SecuritySafeCritical]  // auto-generated
        public void Write(Int64 position, Int64 value) { 
            int sizeOfType = sizeof(Int64);
            EnsureSafeToWrite(position, sizeOfType);

            unsafe { 
                byte* pointer = null;
                RuntimeHelpers.PrepareConstrainedRegions(); 
                try { 
                    _buffer.AcquirePointer(ref pointer);
                    pointer += (_offset + position); 
#if IA64
                    // check if pointer is aligned
                    if (((int)pointer & (sizeOfType - 1)) == 0) {
#endif 
                        *((Int64*)pointer) = value;
#if IA64 
                    } 
                    else {
                        *(pointer) = (byte)value; 
                        *(pointer + 1) = (byte)(value >> 8);
                        *(pointer + 2) = (byte)(value >> 16);
                        *(pointer + 3) = (byte)(value >> 24);
                        *(pointer + 4) = (byte)(value >> 32); 
                        *(pointer + 5) = (byte)(value >> 40);
                        *(pointer + 6) = (byte)(value >> 48); 
                        *(pointer + 7) = (byte)(value >> 56); 
                    }
#endif 
                }
                finally {
                    if (pointer != null) {
                        _buffer.ReleasePointer(); 
                    }
                } 
            } 
        }
 
        [System.Security.SecuritySafeCritical]  // auto-generated
        public void Write(Int64 position, Decimal value) {
            int sizeOfType = sizeof(Decimal);
            EnsureSafeToWrite(position, sizeOfType); 

            byte[] decimalArray = new byte[16]; 
            Decimal.GetBytes(value, decimalArray); 

            int[] bits = new int[4]; 
            int flags = ((int)decimalArray[12]) | ((int)decimalArray[13] << 8) | ((int)decimalArray[14] << 16) | ((int)decimalArray[15] << 24);
            int lo = ((int)decimalArray[0]) | ((int)decimalArray[1] << 8) | ((int)decimalArray[2] << 16) | ((int)decimalArray[3] << 24);
            int mid = ((int)decimalArray[4]) | ((int)decimalArray[5] << 8) | ((int)decimalArray[6] << 16) | ((int)decimalArray[7] << 24);
            int hi = ((int)decimalArray[8]) | ((int)decimalArray[9] << 8) | ((int)decimalArray[10] << 16) | ((int)decimalArray[11] << 24); 
            bits[0] = lo;
            bits[1] = mid; 
            bits[2] = hi; 
            bits[3] = flags;
 
            WriteArray(position, bits, 0, bits.Length);
        }

        [System.Security.SecuritySafeCritical]  // auto-generated 
        public void Write(Int64 position, Single value) {
            int sizeOfType = sizeof(Single); 
            EnsureSafeToWrite(position, sizeOfType); 

            unsafe { 
                byte* pointer = null;
                RuntimeHelpers.PrepareConstrainedRegions();
                try {
                    _buffer.AcquirePointer(ref pointer); 
                    pointer += (_offset + position);
#if IA64 
                    // check if pointer is aligned 
                    if (((int)pointer & (sizeOfType - 1)) == 0) {
#endif 
                    *((Single*)pointer) = value;
#if IA64
                    }
                    else { 
                    UInt32 tmpValue = *(UInt32*)&value;
                    *(pointer) = (byte)tmpValue; 
                    *(pointer + 1) = (byte)(tmpValue >> 8); 
                    *(pointer + 2) = (byte)(tmpValue >> 16);
                    *(pointer + 3) = (byte)(tmpValue >> 24); 

                    }
#endif
                } 
                finally {
                    if (pointer != null) { 
                        _buffer.ReleasePointer(); 
                    }
                } 
            }
        }

        [System.Security.SecuritySafeCritical]  // auto-generated 
        public void Write(Int64 position, Double value) {
            int sizeOfType = sizeof(Double); 
            EnsureSafeToWrite(position, sizeOfType); 

            unsafe { 
                byte* pointer = null;
                RuntimeHelpers.PrepareConstrainedRegions();
                try {
                    _buffer.AcquirePointer(ref pointer); 
                    pointer += (_offset + position);
#if IA64 
                    // check if pointer is aligned 
                    if (((int)pointer & (sizeOfType - 1)) == 0) {
#endif 
                    *((Double*)pointer) = value;
#if IA64
                    }
                    else { 
                    UInt64 tmpValue = *(UInt64 *)&value;
                    *(pointer) = (byte) tmpValue; 
                    *(pointer + 1) = (byte) (tmpValue >> 8); 
                    *(pointer + 2) = (byte) (tmpValue >> 16);
                    *(pointer + 3) = (byte) (tmpValue >> 24); 
                    *(pointer + 4) = (byte) (tmpValue >> 32);
                    *(pointer + 5) = (byte) (tmpValue >> 40);
                    *(pointer + 6) = (byte) (tmpValue >> 48);
                    *(pointer + 7) = (byte) (tmpValue >> 56); 

                    } 
#endif 
                }
                finally { 
                    if (pointer != null) {
                        _buffer.ReleasePointer();
                    }
                } 
            }
        } 
 
        [System.Security.SecuritySafeCritical]  // auto-generated
        [CLSCompliant(false)] 
        public void Write(Int64 position, SByte value) {
            int sizeOfType = sizeof(SByte);
            EnsureSafeToWrite(position, sizeOfType);
 
            unsafe {
                byte* pointer = null; 
                RuntimeHelpers.PrepareConstrainedRegions(); 
                try {
                    _buffer.AcquirePointer(ref pointer); 
                    pointer += (_offset + position);
                    *((SByte*)pointer) = value;
                }
                finally { 
                    if (pointer != null) {
                        _buffer.ReleasePointer(); 
                    } 
                }
            } 
        }

        [System.Security.SecuritySafeCritical]  // auto-generated
        [CLSCompliant(false)] 
        public void Write(Int64 position, UInt16 value) {
            int sizeOfType = sizeof(UInt16); 
            EnsureSafeToWrite(position, sizeOfType); 

            unsafe { 
                byte* pointer = null;
                RuntimeHelpers.PrepareConstrainedRegions();
                try {
                    _buffer.AcquirePointer(ref pointer); 
                    pointer += (_offset + position);
 
#if IA64 
                    // check if pointer is aligned
                    if (((int)pointer & (sizeOfType - 1)) == 0) { 
#endif
                    *((UInt16*)pointer) = value;
#if IA64
                    } 
                    else {
                        *(pointer) = (byte)value; 
                        *(pointer + 1) = (byte)(value >> 8); 
                    }
#endif 
                }
                finally {
                    if (pointer != null) {
                        _buffer.ReleasePointer(); 
                    }
                } 
            } 
        }
 
        [System.Security.SecuritySafeCritical]  // auto-generated
        [CLSCompliant(false)]
        public void Write(Int64 position, UInt32 value) {
            int sizeOfType = sizeof(UInt32); 
            EnsureSafeToWrite(position, sizeOfType);
 
            unsafe { 
                byte* pointer = null;
                RuntimeHelpers.PrepareConstrainedRegions(); 
                try {
                    _buffer.AcquirePointer(ref pointer);
                    pointer += (_offset + position);
 
#if IA64
                    // check if pointer is aligned 
                    if (((int)pointer & (sizeOfType - 1)) == 0) { 
#endif
                    *((UInt32*)pointer) = value; 
#if IA64
                    }
                    else {
                        *(pointer) = (byte)value; 
                        *(pointer + 1) = (byte)(value >> 8);
                        *(pointer + 2) = (byte)(value >> 16); 
                        *(pointer + 3) = (byte)(value >> 24); 
                    }
#endif 

                }
                finally {
                    if (pointer != null) { 
                        _buffer.ReleasePointer();
                    } 
                } 
            }
        } 

        [System.Security.SecuritySafeCritical]  // auto-generated
        [CLSCompliant(false)]
        public void Write(Int64 position, UInt64 value) { 
            int sizeOfType = sizeof(UInt64);
            EnsureSafeToWrite(position, sizeOfType); 
 
            unsafe {
                byte* pointer = null; 
                RuntimeHelpers.PrepareConstrainedRegions();
                try {
                    _buffer.AcquirePointer(ref pointer);
                    pointer += (_offset + position); 
#if IA64
                    // check if pointer is aligned 
                    if (((int)pointer & (sizeOfType - 1)) == 0) { 
#endif
                    *((UInt64*)pointer) = value; 
#if IA64
                    }
                    else {
                        *(pointer) = (byte)value; 
                        *(pointer + 1) = (byte)(value >> 8);
                        *(pointer + 2) = (byte)(value >> 16); 
                        *(pointer + 3) = (byte)(value >> 24); 
                        *(pointer + 4) = (byte)(value >> 32);
                        *(pointer + 5) = (byte)(value >> 40); 
                        *(pointer + 6) = (byte)(value >> 48);
                        *(pointer + 7) = (byte)(value >> 56);
                    }
#endif 

                } 
                finally { 
                    if (pointer != null) {
                        _buffer.ReleasePointer(); 
                    }
                }
            }
        } 

        // Writes the struct pointed to by ref value into unmanaged memory.  Note that this method 
        // is most performant when used with medium to large sized structs (larger than 8 bytes 
        // though this is number is JIT and architecture dependent).   As such, it is best to use
        // the WriteX methods for small standard types such as ints, longs, bools, etc. 

        [System.Security.SecurityCritical]  // auto-generated_required
        public void Write(Int64 position, ref T structure) where T : struct {
            if (position < 0) { 
                throw new ArgumentOutOfRangeException("position", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
            } 
            Contract.EndContractBlock(); 

            if (!_isOpen) { 
                throw new ObjectDisposedException("UnmanagedMemoryAccessor", Environment.GetResourceString("ObjectDisposed_ViewAccessorClosed"));
            }
            if (!CanWrite) {
                throw new NotSupportedException(Environment.GetResourceString("NotSupported_Writing")); 
            }
 
            UInt32 sizeOfT = Marshal.SizeOf(); 
            if (position > _capacity - sizeOfT) {
                if (position >= _capacity) { 
                    throw new ArgumentOutOfRangeException("position", Environment.GetResourceString("ArgumentOutOfRange_PositionLessThanCapacityRequired"));
                }
                else {
                    throw new ArgumentException(Environment.GetResourceString("Argument_NotEnoughBytesToWrite", typeof(T).FullName), "position"); 
                }
            } 
 
            _buffer.Write((UInt64)(_offset + position), structure);
        } 

        // Writes 'count' structs of type T from 'array' (starting at 'offset') into unmanaged memory.

 
        [System.Security.SecurityCritical]  // auto-generated_required
        public void WriteArray(Int64 position, T[] array, Int32 offset, Int32 count) where T : struct { 
            if (array == null) { 
                throw new ArgumentNullException("array", "Buffer cannot be null.");
            } 
            if (offset < 0) {
                throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
            }
            if (count < 0) { 
                throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
            } 
            if (array.Length - offset < count) { 
                throw new ArgumentException(Environment.GetResourceString("Argument_OffsetAndLengthOutOfBounds"));
            } 
            if (position < 0) {
                throw new ArgumentOutOfRangeException("position", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
            }
            if (position >= Capacity) { 
                throw new ArgumentOutOfRangeException("position", Environment.GetResourceString("ArgumentOutOfRange_PositionLessThanCapacityRequired"));
            } 
            Contract.EndContractBlock(); 

            if (!_isOpen) { 
                throw new ObjectDisposedException("UnmanagedMemoryAccessor", Environment.GetResourceString("ObjectDisposed_ViewAccessorClosed"));
            }
            if (!CanWrite) {
                throw new NotSupportedException(Environment.GetResourceString("NotSupported_Writing")); 
            }
 
            _buffer.WriteArray((UInt64)(_offset + position), array, offset, count); 
        }
 
        [System.Security.SecuritySafeCritical]  // auto-generated
        private byte InternalReadByte(Int64 position) {
            Contract.Assert(CanRead, "UMA not readable");
            Contract.Assert(position >= 0, "position less than 0"); 
            Contract.Assert(position <= _capacity - sizeof(byte), "position is greater than capacity - sizeof(byte)");
 
            byte result; 
            unsafe {
                byte* pointer = null; 
                RuntimeHelpers.PrepareConstrainedRegions();
                try {
                    _buffer.AcquirePointer(ref pointer);
                    result = *((byte*)(pointer + _offset + position)); 
                }
                finally { 
                    if (pointer != null) { 
                        _buffer.ReleasePointer();
                    } 
                }
            }
            return result;
        } 

        [System.Security.SecuritySafeCritical]  // auto-generated 
        private void InternalWrite(Int64 position, byte value) { 
            Contract.Assert(CanWrite, "UMA not writeable");
            Contract.Assert(position >= 0, "position less than 0"); 
            Contract.Assert(position <= _capacity - sizeof(byte), "position is greater than capacity - sizeof(byte)");

            unsafe {
                byte* pointer = null; 
                RuntimeHelpers.PrepareConstrainedRegions();
                try { 
                    _buffer.AcquirePointer(ref pointer); 
                    *((byte*)(pointer + _offset + position)) = value;
                } 
                finally {
                    if (pointer != null) {
                        _buffer.ReleasePointer();
                    } 
                }
            } 
        } 

        private void EnsureSafeToRead(Int64 position, int sizeOfType) { 
            if (!_isOpen) {
                throw new ObjectDisposedException("UnmanagedMemoryAccessor", Environment.GetResourceString("ObjectDisposed_ViewAccessorClosed"));
            }
            if (!CanRead) { 
                throw new NotSupportedException(Environment.GetResourceString("NotSupported_Reading"));
            } 
            if (position < 0) { 
                throw new ArgumentOutOfRangeException("position", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
            } 
            Contract.EndContractBlock();
            if (position > _capacity - sizeOfType) {
                if (position >= _capacity) {
                    throw new ArgumentOutOfRangeException("position", Environment.GetResourceString("ArgumentOutOfRange_PositionLessThanCapacityRequired")); 
                }
                else { 
                    throw new ArgumentException(Environment.GetResourceString("Argument_NotEnoughBytesToRead"), "position"); 
                }
            } 
        }

        private void EnsureSafeToWrite(Int64 position, int sizeOfType) {
            if (!_isOpen) { 
                throw new ObjectDisposedException("UnmanagedMemoryAccessor", Environment.GetResourceString("ObjectDisposed_ViewAccessorClosed"));
            } 
            if (!CanWrite) { 
                throw new NotSupportedException(Environment.GetResourceString("NotSupported_Writing"));
            } 
            if (position < 0) {
                throw new ArgumentOutOfRangeException("position", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
            }
            Contract.EndContractBlock(); 
            if (position > _capacity - sizeOfType) {
                if (position >= _capacity) { 
                    throw new ArgumentOutOfRangeException("position", Environment.GetResourceString("ArgumentOutOfRange_PositionLessThanCapacityRequired")); 
                }
                else { 
                    throw new ArgumentException(Environment.GetResourceString("Argument_NotEnoughBytesToWrite", "Byte"), "position");
                }
            }
        } 

    } 
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.


                        

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