Code:
/ 4.0 / 4.0 / 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. // ==++== // // 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
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- TransformGroup.cs
- ChtmlLinkAdapter.cs
- DataExpression.cs
- TemplateBindingExtension.cs
- SelectedDatesCollection.cs
- Registry.cs
- Style.cs
- IndexedWhereQueryOperator.cs
- ApplicationBuildProvider.cs
- GeometryConverter.cs
- DaylightTime.cs
- CurrentChangingEventManager.cs
- Main.cs
- DynamicDiscoSearcher.cs
- ReflectionPermission.cs
- FieldToken.cs
- ValidationEventArgs.cs
- NameValuePermission.cs
- PrintingPermissionAttribute.cs
- SuppressMergeCheckAttribute.cs
- InlineCollection.cs
- InstanceHandleConflictException.cs
- DoubleAnimationUsingPath.cs
- EntityConnectionStringBuilder.cs
- DesignerSerializationVisibilityAttribute.cs
- X509RawDataKeyIdentifierClause.cs
- ImageMapEventArgs.cs
- ByteStreamMessageEncoderFactory.cs
- XmlReaderDelegator.cs
- Trustee.cs
- HtmlInputFile.cs
- ConsumerConnectionPoint.cs
- BinHexEncoder.cs
- IdentityReference.cs
- EventHandlerList.cs
- DBNull.cs
- ImageCodecInfoPrivate.cs
- DataGridViewColumnCollection.cs
- InstanceDescriptor.cs
- BitmapEffectrendercontext.cs
- DragDropManager.cs
- SafeFindHandle.cs
- EntityModelBuildProvider.cs
- XPathDocumentBuilder.cs
- PngBitmapDecoder.cs
- ApplicationTrust.cs
- ItemsControlAutomationPeer.cs
- Helpers.cs
- DataGridViewRowHeightInfoNeededEventArgs.cs
- ProviderBase.cs
- DataRowView.cs
- DataGridViewCellContextMenuStripNeededEventArgs.cs
- METAHEADER.cs
- ArglessEventHandlerProxy.cs
- SoapObjectInfo.cs
- SvcMapFile.cs
- IdnMapping.cs
- WorkflowServiceHost.cs
- WinFormsComponentEditor.cs
- SqlConnectionHelper.cs
- SafeRegistryKey.cs
- AssemblyCollection.cs
- AssertHelper.cs
- DetailsView.cs
- SingleAnimationUsingKeyFrames.cs
- PropertyChangedEventArgs.cs
- DoubleLinkList.cs
- LogStream.cs
- DataGridViewHitTestInfo.cs
- CodeRemoveEventStatement.cs
- WebPartMenuStyle.cs
- CompositeCollectionView.cs
- EdmSchemaError.cs
- PointCollection.cs
- DataContract.cs
- InsufficientMemoryException.cs
- FormViewModeEventArgs.cs
- SecurityTokenValidationException.cs
- ContextStaticAttribute.cs
- StyleHelper.cs
- TemplateBindingExtensionConverter.cs
- XmlObjectSerializerWriteContext.cs
- SQLBoolean.cs
- HelloMessage11.cs
- BitmapEffectGroup.cs
- FileCodeGroup.cs
- TypeDelegator.cs
- XmlAttribute.cs
- CreateUserWizard.cs
- WinInet.cs
- GifBitmapEncoder.cs
- TextServicesDisplayAttribute.cs
- WebZone.cs
- RC2.cs
- Frame.cs
- UnicodeEncoding.cs
- PackUriHelper.cs
- ReliableChannelFactory.cs
- Composition.cs
- OverrideMode.cs