diff options
Diffstat (limited to 'src/mscorlib/src/System/IO/UnmanagedMemoryAccessor.cs')
-rw-r--r-- | src/mscorlib/src/System/IO/UnmanagedMemoryAccessor.cs | 1132 |
1 files changed, 500 insertions, 632 deletions
diff --git a/src/mscorlib/src/System/IO/UnmanagedMemoryAccessor.cs b/src/mscorlib/src/System/IO/UnmanagedMemoryAccessor.cs index f3fd71833c..5f6f588cbe 100644 --- a/src/mscorlib/src/System/IO/UnmanagedMemoryAccessor.cs +++ b/src/mscorlib/src/System/IO/UnmanagedMemoryAccessor.cs @@ -12,6 +12,7 @@ ** ** ===========================================================*/ + using System; using System.Runtime.InteropServices; using System.Runtime.CompilerServices; @@ -21,13 +22,13 @@ using Microsoft.Win32.SafeHandles; using System.Diagnostics; using System.Diagnostics.Contracts; -namespace System.IO { - +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 { - + public class UnmanagedMemoryAccessor : IDisposable + { private SafeBuffer _buffer; private Int64 _offset; [ContractPublicPropertyName("Capacity")] @@ -37,7 +38,8 @@ namespace System.IO { private bool _canRead; private bool _canWrite; - protected UnmanagedMemoryAccessor() { + protected UnmanagedMemoryAccessor() + { _isOpen = false; } @@ -45,47 +47,61 @@ namespace System.IO { // <SecurityKernel Critical="True" Ring="1"> // <ReferencesCritical Name="Method: Initialize(SafeBuffer, Int64, Int64, FileAccess):Void" Ring="1" /> // </SecurityKernel> - public UnmanagedMemoryAccessor(SafeBuffer buffer, Int64 offset, Int64 capacity) { + public UnmanagedMemoryAccessor(SafeBuffer buffer, Int64 offset, Int64 capacity) + { Initialize(buffer, offset, capacity, FileAccess.Read); } - public UnmanagedMemoryAccessor(SafeBuffer buffer, Int64 offset, Int64 capacity, FileAccess access) { + public UnmanagedMemoryAccessor(SafeBuffer buffer, Int64 offset, Int64 capacity, FileAccess access) + { Initialize(buffer, offset, capacity, access); } - protected void Initialize(SafeBuffer buffer, Int64 offset, Int64 capacity, FileAccess access) { - if (buffer == null) { + protected void Initialize(SafeBuffer buffer, Int64 offset, Int64 capacity, FileAccess access) + { + if (buffer == null) + { throw new ArgumentNullException(nameof(buffer)); } - if (offset < 0) { - throw new ArgumentOutOfRangeException(nameof(offset), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + if (offset < 0) + { + throw new ArgumentOutOfRangeException(nameof(offset), SR.ArgumentOutOfRange_NeedNonNegNum); } - if (capacity < 0) { - throw new ArgumentOutOfRangeException(nameof(capacity), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + if (capacity < 0) + { + throw new ArgumentOutOfRangeException(nameof(capacity), SR.ArgumentOutOfRange_NeedNonNegNum); } - if (buffer.ByteLength < (UInt64)(offset + capacity)) { - throw new ArgumentException(Environment.GetResourceString("Argument_OffsetAndCapacityOutOfBounds")); + if (buffer.ByteLength < (UInt64)(offset + capacity)) + { + throw new ArgumentException(SR.Argument_OffsetAndCapacityOutOfBounds); } - if (access < FileAccess.Read || access > FileAccess.ReadWrite) { + if (access < FileAccess.Read || access > FileAccess.ReadWrite) + { throw new ArgumentOutOfRangeException(nameof(access)); } Contract.EndContractBlock(); - if (_isOpen) { - throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CalledTwice")); + if (_isOpen) + { + throw new InvalidOperationException(SR.InvalidOperation_CalledTwice); } - unsafe { + unsafe + { byte* pointer = null; RuntimeHelpers.PrepareConstrainedRegions(); - try { + try + { buffer.AcquirePointer(ref pointer); - if (((byte*)((Int64)pointer + offset + capacity)) < pointer) { - throw new ArgumentException(Environment.GetResourceString("Argument_UnmanagedMemAccessorWrapAround")); + if (((byte*)((Int64)pointer + offset + capacity)) < pointer) + { + throw new ArgumentException(SR.Argument_UnmanagedMemAccessorWrapAround); } } - finally { - if (pointer != null) { + finally + { + if (pointer != null) + { buffer.ReleasePointer(); } } @@ -102,38 +118,48 @@ namespace System.IO { #endregion - public Int64 Capacity { - get { - return _capacity; + public Int64 Capacity + { + get + { + return _capacity; } } - public bool CanRead { - get { - return _isOpen && _canRead; + public bool CanRead + { + get + { + return _isOpen && _canRead; } } - public bool CanWrite { - get { - return _isOpen && _canWrite; + public bool CanWrite + { + get + { + return _isOpen && _canWrite; } } - protected virtual void Dispose(bool disposing) { + protected virtual void Dispose(bool disposing) + { _isOpen = false; } - public void Dispose() { + public void Dispose() + { Dispose(true); GC.SuppressFinalize(this); } - protected bool IsOpen { + protected bool IsOpen + { get { return _isOpen; } } - public bool ReadBoolean(Int64 position) { + public bool ReadBoolean(Int64 position) + { int sizeOfType = sizeof(bool); EnsureSafeToRead(position, sizeOfType); @@ -141,40 +167,32 @@ namespace System.IO { return b != 0; } - public byte ReadByte(Int64 position) { + public byte ReadByte(Int64 position) + { int sizeOfType = sizeof(byte); EnsureSafeToRead(position, sizeOfType); return InternalReadByte(position); } - public char ReadChar(Int64 position) { - int sizeOfType = sizeof(char); - EnsureSafeToRead(position, sizeOfType); - - char result; + public char ReadChar(Int64 position) + { + EnsureSafeToRead(position, sizeof(char)); - unsafe { + char result; + unsafe + { byte* pointer = null; RuntimeHelpers.PrepareConstrainedRegions(); - try { + try + { _buffer.AcquirePointer(ref pointer); - pointer += (_offset + position); - -#if ALIGN_ACCESS - // check if pointer is aligned - if (((int)pointer & (sizeOfType - 1)) == 0) { -#endif - result = *((char*)(pointer)); -#if ALIGN_ACCESS - } - else { - result = (char)( *pointer | *(pointer + 1) << 8 ) ; - } -#endif + result = Unsafe.ReadUnaligned<char>(pointer + _offset + position); } - finally { - if (pointer != null) { + finally + { + if (pointer != null) + { _buffer.ReleasePointer(); } } @@ -184,33 +202,24 @@ namespace System.IO { } // See comment above. - public Int16 ReadInt16(Int64 position) { - int sizeOfType = sizeof(Int16); - EnsureSafeToRead(position, sizeOfType); + public Int16 ReadInt16(Int64 position) + { + EnsureSafeToRead(position, sizeof(Int16)); Int16 result; - - unsafe { + unsafe + { byte* pointer = null; RuntimeHelpers.PrepareConstrainedRegions(); - try { + try + { _buffer.AcquirePointer(ref pointer); - pointer += (_offset + position); - -#if ALIGN_ACCESS - // check if pointer is aligned - if (((int)pointer & (sizeOfType - 1)) == 0) { -#endif - result = *((Int16*)(pointer)); -#if ALIGN_ACCESS - } - else { - result = (Int16)( *pointer | *(pointer + 1) << 8 ); - } -#endif + result = Unsafe.ReadUnaligned<Int16>(pointer + _offset + position); } - finally { - if (pointer != null) { + finally + { + if (pointer != null) + { _buffer.ReleasePointer(); } } @@ -220,32 +229,24 @@ namespace System.IO { } - public Int32 ReadInt32(Int64 position) { - int sizeOfType = sizeof(Int32); - EnsureSafeToRead(position, sizeOfType); + public Int32 ReadInt32(Int64 position) + { + EnsureSafeToRead(position, sizeof(Int32)); Int32 result; - unsafe { + unsafe + { byte* pointer = null; RuntimeHelpers.PrepareConstrainedRegions(); - try { + try + { _buffer.AcquirePointer(ref pointer); - pointer += (_offset + position); - -#if ALIGN_ACCESS - // check if pointer is aligned - if (((int)pointer & (sizeOfType - 1)) == 0) { -#endif - result = *((Int32*)(pointer)); -#if ALIGN_ACCESS - } - else { - result = (Int32)( *pointer | *(pointer + 1) << 8 | *(pointer + 2) << 16 | *(pointer + 3) << 24 ); - } -#endif + result = Unsafe.ReadUnaligned<Int32>(pointer + _offset + position); } - finally { - if (pointer != null) { + finally + { + if (pointer != null) + { _buffer.ReleasePointer(); } } @@ -254,34 +255,24 @@ namespace System.IO { return result; } - public Int64 ReadInt64(Int64 position) { - int sizeOfType = sizeof(Int64); - EnsureSafeToRead(position, sizeOfType); + public Int64 ReadInt64(Int64 position) + { + EnsureSafeToRead(position, sizeof(Int64)); Int64 result; - unsafe { + unsafe + { byte* pointer = null; RuntimeHelpers.PrepareConstrainedRegions(); - try { + try + { _buffer.AcquirePointer(ref pointer); - pointer += (_offset + position); - -#if ALIGN_ACCESS - // check if pointer is aligned - if (((int)pointer & (sizeOfType - 1)) == 0) { -#endif - result = *((Int64*)(pointer)); -#if ALIGN_ACCESS - } - 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) { + result = Unsafe.ReadUnaligned<Int64>(pointer + _offset + position); + } + finally + { + if (pointer != null) + { _buffer.ReleasePointer(); } } @@ -290,28 +281,14 @@ namespace System.IO { return result; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private unsafe Int32 UnsafeReadInt32(byte* pointer) + public Decimal ReadDecimal(Int64 position) { - Int32 result; - // check if pointer is aligned - if (((int)pointer & (sizeof(Int32) - 1)) == 0) - { - result = *((Int32*)pointer); - } - else - { - result = (Int32)(*(pointer) | *(pointer + 1) << 8 | *(pointer + 2) << 16 | *(pointer + 3) << 24); - } - - return result; - } - public Decimal ReadDecimal(Int64 position) { const int ScaleMask = 0x00FF0000; const int SignMask = unchecked((int)0x80000000); - int sizeOfType = sizeof(Decimal); - EnsureSafeToRead(position, sizeOfType); + EnsureSafeToRead(position, sizeof(Decimal)); + + int lo, mid, hi, flags; unsafe { @@ -319,23 +296,11 @@ namespace System.IO { try { _buffer.AcquirePointer(ref pointer); - pointer += (_offset + position); - - int lo = UnsafeReadInt32(pointer); - int mid = UnsafeReadInt32(pointer + 4); - int hi = UnsafeReadInt32(pointer + 8); - int flags = UnsafeReadInt32(pointer + 12); - - // Check for invalid Decimal values - if (!((flags & ~(SignMask | ScaleMask)) == 0 && (flags & ScaleMask) <= (28 << 16))) - { - throw new ArgumentException(Environment.GetResourceString("Arg_BadDecimal")); // Throw same Exception type as Decimal(int[]) ctor for compat - } - - bool isNegative = (flags & SignMask) != 0; - byte scale = (byte)(flags >> 16); - - return new decimal(lo, mid, hi, isNegative, scale); + + lo = Unsafe.ReadUnaligned<Int32>(pointer + _offset + position); + mid = Unsafe.ReadUnaligned<Int32>(pointer + _offset + position + 4); + hi = Unsafe.ReadUnaligned<Int32>(pointer + _offset + position + 8); + flags = Unsafe.ReadUnaligned<Int32>(pointer + _offset + position + 12); } finally { @@ -345,35 +310,37 @@ namespace System.IO { } } } + + // Check for invalid Decimal values + if (!((flags & ~(SignMask | ScaleMask)) == 0 && (flags & ScaleMask) <= (28 << 16))) + { + throw new ArgumentException(SR.Arg_BadDecimal); // Throw same Exception type as Decimal(int[]) ctor for compat + } + + bool isNegative = (flags & SignMask) != 0; + byte scale = (byte)(flags >> 16); + + return new decimal(lo, mid, hi, isNegative, scale); } - public Single ReadSingle(Int64 position) { - int sizeOfType = sizeof(Single); - EnsureSafeToRead(position, sizeOfType); + public Single ReadSingle(Int64 position) + { + EnsureSafeToRead(position, sizeof(Single)); Single result; - unsafe { + unsafe + { byte* pointer = null; RuntimeHelpers.PrepareConstrainedRegions(); - try { + try + { _buffer.AcquirePointer(ref pointer); - pointer += (_offset + position); - -#if ALIGN_ACCESS - // check if pointer is aligned - if (((int)pointer & (sizeOfType - 1)) == 0) { -#endif - result = BitConverter.Int32BitsToSingle(*((int*)(pointer))); -#if ALIGN_ACCESS - } - else { - UInt32 tempResult = (UInt32)( *pointer | *(pointer + 1) << 8 | *(pointer + 2) << 16 | *(pointer + 3) << 24 ); - result = *((float*)&tempResult); - } -#endif + result = Unsafe.ReadUnaligned<Single>(pointer + _offset + position); } - finally { - if (pointer != null) { + finally + { + if (pointer != null) + { _buffer.ReleasePointer(); } } @@ -382,37 +349,24 @@ namespace System.IO { return result; } - public Double ReadDouble(Int64 position) { - int sizeOfType = sizeof(Double); - EnsureSafeToRead(position, sizeOfType); + public Double ReadDouble(Int64 position) + { + EnsureSafeToRead(position, sizeof(Double)); Double result; - unsafe { + unsafe + { byte* pointer = null; RuntimeHelpers.PrepareConstrainedRegions(); - try { + try + { _buffer.AcquirePointer(ref pointer); - pointer += (_offset + position); - -#if ALIGN_ACCESS - // check if pointer is aligned - if (((int)pointer & (sizeOfType - 1)) == 0) { -#endif - result = BitConverter.Int64BitsToDouble(*((long*)(pointer))); -#if ALIGN_ACCESS - } - 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 + result = Unsafe.ReadUnaligned<Double>(pointer + _offset + position); } - finally { - if (pointer != null) { + finally + { + if (pointer != null) + { _buffer.ReleasePointer(); } } @@ -422,21 +376,25 @@ namespace System.IO { } [CLSCompliant(false)] - public SByte ReadSByte(Int64 position) { + public SByte ReadSByte(Int64 position) + { int sizeOfType = sizeof(SByte); EnsureSafeToRead(position, sizeOfType); SByte result; - unsafe { + unsafe + { byte* pointer = null; RuntimeHelpers.PrepareConstrainedRegions(); - try { + try + { _buffer.AcquirePointer(ref pointer); - pointer += (_offset + position); - result = *((SByte*)pointer); + result = *((SByte*)(pointer + _offset + position)); } - finally { - if (pointer != null) { + finally + { + if (pointer != null) + { _buffer.ReleasePointer(); } } @@ -444,35 +402,26 @@ namespace System.IO { return result; } - + [CLSCompliant(false)] - public UInt16 ReadUInt16(Int64 position) { - int sizeOfType = sizeof(UInt16); - EnsureSafeToRead(position, sizeOfType); + public UInt16 ReadUInt16(Int64 position) + { + EnsureSafeToRead(position, sizeof(UInt16)); UInt16 result; - unsafe { + unsafe + { byte* pointer = null; RuntimeHelpers.PrepareConstrainedRegions(); - try { + try + { _buffer.AcquirePointer(ref pointer); - pointer += (_offset + position); - -#if ALIGN_ACCESS - // check if pointer is aligned - if (((int)pointer & (sizeOfType - 1)) == 0) { -#endif - result = *((UInt16*)(pointer)); -#if ALIGN_ACCESS - } - else { - result = (UInt16)( *pointer | *(pointer + 1) << 8 ); - } -#endif - + result = Unsafe.ReadUnaligned<UInt16>(pointer + _offset + position); } - finally { - if (pointer != null) { + finally + { + if (pointer != null) + { _buffer.ReleasePointer(); } } @@ -480,35 +429,26 @@ namespace System.IO { return result; } - + [CLSCompliant(false)] - public UInt32 ReadUInt32(Int64 position) { - int sizeOfType = sizeof(UInt32); - EnsureSafeToRead(position, sizeOfType); + public UInt32 ReadUInt32(Int64 position) + { + EnsureSafeToRead(position, sizeof(UInt32)); UInt32 result; - unsafe { + unsafe + { byte* pointer = null; RuntimeHelpers.PrepareConstrainedRegions(); - try { + try + { _buffer.AcquirePointer(ref pointer); - pointer += (_offset + position); - -#if ALIGN_ACCESS - // check if pointer is aligned - if (((int)pointer & (sizeOfType - 1)) == 0) { -#endif - result = *((UInt32*)(pointer)); -#if ALIGN_ACCESS - } - else { - result = (UInt32)( *pointer | *(pointer + 1) << 8 | *(pointer + 2) << 16 | *(pointer + 3) << 24 ); - } -#endif - + result = Unsafe.ReadUnaligned<UInt32>(pointer + _offset + position); } - finally { - if (pointer != null) { + finally + { + if (pointer != null) + { _buffer.ReleasePointer(); } } @@ -518,35 +458,24 @@ namespace System.IO { } [CLSCompliant(false)] - public UInt64 ReadUInt64(Int64 position) { - int sizeOfType = sizeof(UInt64); - EnsureSafeToRead(position, sizeOfType); + public UInt64 ReadUInt64(Int64 position) + { + EnsureSafeToRead(position, sizeof(UInt64)); UInt64 result; - unsafe { + unsafe + { byte* pointer = null; RuntimeHelpers.PrepareConstrainedRegions(); - try { + try + { _buffer.AcquirePointer(ref pointer); - pointer += (_offset + position); - -#if ALIGN_ACCESS - // check if pointer is aligned - if (((int)pointer & (sizeOfType - 1)) == 0) { -#endif - result = *((UInt64*)(pointer)); -#if ALIGN_ACCESS - } - 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 - + result = Unsafe.ReadUnaligned<UInt64>(pointer + _offset + position); } - finally { - if (pointer != null) { + finally + { + if (pointer != null) + { _buffer.ReleasePointer(); } } @@ -569,26 +498,33 @@ namespace System.IO { // such, it is best to use the ReadXXX methods for small standard types such as ints, longs, // bools, etc. - public void Read<T>(Int64 position, out T structure) where T : struct { - if (position < 0) { - throw new ArgumentOutOfRangeException(nameof(position), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + public void Read<T>(Int64 position, out T structure) where T : struct + { + if (position < 0) + { + throw new ArgumentOutOfRangeException(nameof(position), SR.ArgumentOutOfRange_NeedNonNegNum); } Contract.EndContractBlock(); - if (!_isOpen) { - throw new ObjectDisposedException("UnmanagedMemoryAccessor", Environment.GetResourceString("ObjectDisposed_ViewAccessorClosed")); + if (!_isOpen) + { + throw new ObjectDisposedException("UnmanagedMemoryAccessor", SR.ObjectDisposed_ViewAccessorClosed); } - if (!CanRead) { - throw new NotSupportedException(Environment.GetResourceString("NotSupported_Reading")); + if (!CanRead) + { + throw new NotSupportedException(SR.NotSupported_Reading); } UInt32 sizeOfT = Marshal.SizeOfType(typeof(T)); - if (position > _capacity - sizeOfT) { - if (position >= _capacity) { - throw new ArgumentOutOfRangeException(nameof(position), Environment.GetResourceString("ArgumentOutOfRange_PositionLessThanCapacityRequired")); + if (position > _capacity - sizeOfT) + { + if (position >= _capacity) + { + throw new ArgumentOutOfRangeException(nameof(position), SR.ArgumentOutOfRange_PositionLessThanCapacityRequired); } - else { - throw new ArgumentException(Environment.GetResourceString("Argument_NotEnoughBytesToRead", typeof(T).FullName), nameof(position)); + else + { + throw new ArgumentException(SR.Format(SR.Argument_NotEnoughBytesToRead, typeof (T).FullName), nameof(position)); } } @@ -601,47 +537,60 @@ namespace System.IO { // struct that contains reference members will most likely cause the runtime to AV. This // is consistent with Marshal.PtrToStructure. - public int ReadArray<T>(Int64 position, T[] array, Int32 offset, Int32 count) where T : struct { - if (array == null) { + public int ReadArray<T>(Int64 position, T[] array, Int32 offset, Int32 count) where T : struct + { + if (array == null) + { throw new ArgumentNullException(nameof(array), "Buffer cannot be null."); } - if (offset < 0) { - throw new ArgumentOutOfRangeException(nameof(offset), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + if (offset < 0) + { + throw new ArgumentOutOfRangeException(nameof(offset), SR.ArgumentOutOfRange_NeedNonNegNum); } - if (count < 0) { - throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + if (count < 0) + { + throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_NeedNonNegNum); } - if (array.Length - offset < count) { - throw new ArgumentException(Environment.GetResourceString("Argument_OffsetAndLengthOutOfBounds")); + if (array.Length - offset < count) + { + throw new ArgumentException(SR.Argument_OffsetAndLengthOutOfBounds); } Contract.EndContractBlock(); - if (!CanRead) { - if (!_isOpen) { - throw new ObjectDisposedException("UnmanagedMemoryAccessor", Environment.GetResourceString("ObjectDisposed_ViewAccessorClosed")); + if (!CanRead) + { + if (!_isOpen) + { + throw new ObjectDisposedException("UnmanagedMemoryAccessor", SR.ObjectDisposed_ViewAccessorClosed); } - else { - throw new NotSupportedException(Environment.GetResourceString("NotSupported_Reading")); + else + { + throw new NotSupportedException(SR.NotSupported_Reading); } } - if (position < 0) { - throw new ArgumentOutOfRangeException(nameof(position), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + if (position < 0) + { + throw new ArgumentOutOfRangeException(nameof(position), SR.ArgumentOutOfRange_NeedNonNegNum); } UInt32 sizeOfT = Marshal.AlignedSizeOf<T>(); // only check position and ask for fewer Ts if count is too big - if (position >= _capacity) { - throw new ArgumentOutOfRangeException(nameof(position), Environment.GetResourceString("ArgumentOutOfRange_PositionLessThanCapacityRequired")); + if (position >= _capacity) + { + throw new ArgumentOutOfRangeException(nameof(position), SR.ArgumentOutOfRange_PositionLessThanCapacityRequired); } int n = count; long spaceLeft = _capacity - position; - if (spaceLeft < 0) { + if (spaceLeft < 0) + { n = 0; } - else { + else + { ulong spaceNeeded = (ulong)(sizeOfT * count); - if ((ulong)spaceLeft < spaceNeeded) { + if ((ulong)spaceLeft < spaceNeeded) + { n = (int)(spaceLeft / sizeOfT); } } @@ -659,7 +608,8 @@ namespace System.IO { // double, short, int, long, sbyte, float, ushort, uint, or ulong. - public void Write(Int64 position, bool value) { + public void Write(Int64 position, bool value) + { int sizeOfType = sizeof(bool); EnsureSafeToWrite(position, sizeOfType); @@ -667,73 +617,55 @@ namespace System.IO { InternalWrite(position, b); } - public void Write(Int64 position, byte value) { + public void Write(Int64 position, byte value) + { int sizeOfType = sizeof(byte); EnsureSafeToWrite(position, sizeOfType); InternalWrite(position, value); } - public void Write(Int64 position, char value) { - int sizeOfType = sizeof(char); - EnsureSafeToWrite(position, sizeOfType); + public void Write(Int64 position, char value) + { + EnsureSafeToWrite(position, sizeof(char)); - unsafe { + unsafe + { byte* pointer = null; RuntimeHelpers.PrepareConstrainedRegions(); - try { + try + { _buffer.AcquirePointer(ref pointer); - pointer += (_offset + position); - -#if ALIGN_ACCESS - // check if pointer is aligned - if (((int)pointer & (sizeOfType - 1)) == 0) { -#endif - *((char*)pointer) = value; -#if ALIGN_ACCESS - } - else { - *(pointer) = (byte)value; - *(pointer+1) = (byte)(value >> 8); - } -#endif + Unsafe.WriteUnaligned<char>(pointer + _offset + position, value); } - finally { - if (pointer != null) { + finally + { + if (pointer != null) + { _buffer.ReleasePointer(); } } } - } - public void Write(Int64 position, Int16 value) { - int sizeOfType = sizeof(Int16); - EnsureSafeToWrite(position, sizeOfType); + public void Write(Int64 position, Int16 value) + { + EnsureSafeToWrite(position, sizeof(Int16)); - unsafe { + unsafe + { byte* pointer = null; RuntimeHelpers.PrepareConstrainedRegions(); - try { + try + { _buffer.AcquirePointer(ref pointer); - pointer += (_offset + position); - -#if ALIGN_ACCESS - // check if pointer is aligned - if (((int)pointer & (sizeOfType - 1)) == 0) { -#endif - *((Int16*)pointer) = value; -#if ALIGN_ACCESS - } - else { - *(pointer) = (byte)value; - *(pointer + 1) = (byte)(value >> 8); - } -#endif + Unsafe.WriteUnaligned<Int16>(pointer + _offset + position, value); } - finally { - if (pointer != null) { + finally + { + if (pointer != null) + { _buffer.ReleasePointer(); } } @@ -741,116 +673,73 @@ namespace System.IO { } - public void Write(Int64 position, Int32 value) { - int sizeOfType = sizeof(Int32); - EnsureSafeToWrite(position, sizeOfType); + public void Write(Int64 position, Int32 value) + { + EnsureSafeToWrite(position, sizeof(Int32)); - unsafe { + unsafe + { byte* pointer = null; RuntimeHelpers.PrepareConstrainedRegions(); - try { + try + { _buffer.AcquirePointer(ref pointer); - pointer += (_offset + position); - -#if ALIGN_ACCESS - // check if pointer is aligned - if (((int)pointer & (sizeOfType - 1)) == 0) { -#endif - *((Int32*)pointer) = value; -#if ALIGN_ACCESS - } - else { - *(pointer) = (byte)value; - *(pointer + 1) = (byte)(value >> 8); - *(pointer + 2) = (byte)(value >> 16); - *(pointer + 3) = (byte)(value >> 24); - } -#endif + Unsafe.WriteUnaligned<Int32>(pointer + _offset + position, value); } - finally { - if (pointer != null) { + finally + { + if (pointer != null) + { _buffer.ReleasePointer(); } } } } - public void Write(Int64 position, Int64 value) { - int sizeOfType = sizeof(Int64); - EnsureSafeToWrite(position, sizeOfType); + public void Write(Int64 position, Int64 value) + { + EnsureSafeToWrite(position, sizeof(Int64)); - unsafe { + unsafe + { byte* pointer = null; RuntimeHelpers.PrepareConstrainedRegions(); - try { + try + { _buffer.AcquirePointer(ref pointer); - pointer += (_offset + position); -#if ALIGN_ACCESS - // check if pointer is aligned - if (((int)pointer & (sizeOfType - 1)) == 0) { -#endif - *((Int64*)pointer) = value; -#if ALIGN_ACCESS - } - 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 + Unsafe.WriteUnaligned<Int64>(pointer + _offset + position, value); } - finally { - if (pointer != null) { + finally + { + if (pointer != null) + { _buffer.ReleasePointer(); } } } } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private unsafe void UnsafeWriteInt32(byte* pointer, Int32 value) + public void Write(Int64 position, Decimal value) { - // check if pointer is aligned - if (((int)pointer & (sizeof(Int32) - 1)) == 0) - { - *((Int32*)pointer) = value; - } - else - { - *(pointer) = (byte)value; - *(pointer + 1) = (byte)(value >> 8); - *(pointer + 2) = (byte)(value >> 16); - *(pointer + 3) = (byte)(value >> 24); - } - } - - public void Write(Int64 position, Decimal value) { - int sizeOfType = sizeof(Decimal); - EnsureSafeToWrite(position, sizeOfType); + EnsureSafeToWrite(position, sizeof(Decimal)); unsafe { + int* valuePtr = (int*)(&value); + int flags = *valuePtr; + int hi = *(valuePtr + 1); + int lo = *(valuePtr + 2); + int mid = *(valuePtr + 3); + byte* pointer = null; try { _buffer.AcquirePointer(ref pointer); - pointer += (_offset + position); - - int* valuePtr = (int*)(&value); - int flags = *valuePtr; - int hi = *(valuePtr + 1); - int lo = *(valuePtr + 2); - int mid = *(valuePtr + 3); - - UnsafeWriteInt32(pointer, lo); - UnsafeWriteInt32(pointer + 4, mid); - UnsafeWriteInt32(pointer + 8, hi); - UnsafeWriteInt32(pointer + 12, flags); + + Unsafe.WriteUnaligned<Int32>(pointer + _offset + position, lo); + Unsafe.WriteUnaligned<Int32>(pointer + _offset + position + 4, mid); + Unsafe.WriteUnaligned<Int32>(pointer + _offset + position + 8, hi); + Unsafe.WriteUnaligned<Int32>(pointer + _offset + position + 12, flags); } finally { @@ -862,74 +751,46 @@ namespace System.IO { } } - public void Write(Int64 position, Single value) { - int sizeOfType = sizeof(Single); - EnsureSafeToWrite(position, sizeOfType); + public void Write(Int64 position, Single value) + { + EnsureSafeToWrite(position, sizeof(Single)); - unsafe { + unsafe + { byte* pointer = null; RuntimeHelpers.PrepareConstrainedRegions(); - try { + try + { _buffer.AcquirePointer(ref pointer); - pointer += (_offset + position); -#if ALIGN_ACCESS - // check if pointer is aligned - if (((int)pointer & (sizeOfType - 1)) == 0) { -#endif - *((int*)pointer) = BitConverter.SingleToInt32Bits(value); -#if ALIGN_ACCESS - } - else { - UInt32 tmpValue = *(UInt32*)&value; - *(pointer) = (byte)tmpValue; - *(pointer + 1) = (byte)(tmpValue >> 8); - *(pointer + 2) = (byte)(tmpValue >> 16); - *(pointer + 3) = (byte)(tmpValue >> 24); - - } -#endif + Unsafe.WriteUnaligned<Single>(pointer + _offset + position, value); } - finally { - if (pointer != null) { + finally + { + if (pointer != null) + { _buffer.ReleasePointer(); } } } } - public void Write(Int64 position, Double value) { - int sizeOfType = sizeof(Double); - EnsureSafeToWrite(position, sizeOfType); + public void Write(Int64 position, Double value) + { + EnsureSafeToWrite(position, sizeof(Double)); - unsafe { + unsafe + { byte* pointer = null; RuntimeHelpers.PrepareConstrainedRegions(); - try { + try + { _buffer.AcquirePointer(ref pointer); - pointer += (_offset + position); -#if ALIGN_ACCESS - // check if pointer is aligned - if (((int)pointer & (sizeOfType - 1)) == 0) { -#endif - *((long*)pointer) = BitConverter.DoubleToInt64Bits(value); -#if ALIGN_ACCESS - } - 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 + Unsafe.WriteUnaligned<Double>(pointer + _offset + position, value); } - finally { - if (pointer != null) { + finally + { + if (pointer != null) + { _buffer.ReleasePointer(); } } @@ -937,20 +798,23 @@ namespace System.IO { } [CLSCompliant(false)] - public void Write(Int64 position, SByte value) { - int sizeOfType = sizeof(SByte); - EnsureSafeToWrite(position, sizeOfType); + public void Write(Int64 position, SByte value) + { + EnsureSafeToWrite(position, sizeof(SByte)); - unsafe { + unsafe + { byte* pointer = null; RuntimeHelpers.PrepareConstrainedRegions(); - try { + try + { _buffer.AcquirePointer(ref pointer); - pointer += (_offset + position); - *((SByte*)pointer) = value; + *((SByte*)(pointer + _offset + position)) = value; } - finally { - if (pointer != null) { + finally + { + if (pointer != null) + { _buffer.ReleasePointer(); } } @@ -958,32 +822,24 @@ namespace System.IO { } [CLSCompliant(false)] - public void Write(Int64 position, UInt16 value) { + public void Write(Int64 position, UInt16 value) + { int sizeOfType = sizeof(UInt16); EnsureSafeToWrite(position, sizeOfType); - unsafe { + unsafe + { byte* pointer = null; RuntimeHelpers.PrepareConstrainedRegions(); - try { + try + { _buffer.AcquirePointer(ref pointer); - pointer += (_offset + position); - -#if ALIGN_ACCESS - // check if pointer is aligned - if (((int)pointer & (sizeOfType - 1)) == 0) { -#endif - *((UInt16*)pointer) = value; -#if ALIGN_ACCESS - } - else { - *(pointer) = (byte)value; - *(pointer + 1) = (byte)(value >> 8); - } -#endif + Unsafe.WriteUnaligned<UInt16>(pointer + _offset + position, value); } - finally { - if (pointer != null) { + finally + { + if (pointer != null) + { _buffer.ReleasePointer(); } } @@ -991,35 +847,23 @@ namespace System.IO { } [CLSCompliant(false)] - public void Write(Int64 position, UInt32 value) { - int sizeOfType = sizeof(UInt32); - EnsureSafeToWrite(position, sizeOfType); + public void Write(Int64 position, UInt32 value) + { + EnsureSafeToWrite(position, sizeof(UInt32)); - unsafe { + unsafe + { byte* pointer = null; RuntimeHelpers.PrepareConstrainedRegions(); - try { + try + { _buffer.AcquirePointer(ref pointer); - pointer += (_offset + position); - -#if ALIGN_ACCESS - // check if pointer is aligned - if (((int)pointer & (sizeOfType - 1)) == 0) { -#endif - *((UInt32*)pointer) = value; -#if ALIGN_ACCESS - } - else { - *(pointer) = (byte)value; - *(pointer + 1) = (byte)(value >> 8); - *(pointer + 2) = (byte)(value >> 16); - *(pointer + 3) = (byte)(value >> 24); - } -#endif - + Unsafe.WriteUnaligned<UInt32>(pointer + _offset + position, value); } - finally { - if (pointer != null) { + finally + { + if (pointer != null) + { _buffer.ReleasePointer(); } } @@ -1027,38 +871,23 @@ namespace System.IO { } [CLSCompliant(false)] - public void Write(Int64 position, UInt64 value) { - int sizeOfType = sizeof(UInt64); - EnsureSafeToWrite(position, sizeOfType); + public void Write(Int64 position, UInt64 value) + { + EnsureSafeToWrite(position, sizeof(UInt64)); - unsafe { + unsafe + { byte* pointer = null; RuntimeHelpers.PrepareConstrainedRegions(); - try { + try + { _buffer.AcquirePointer(ref pointer); - pointer += (_offset + position); -#if ALIGN_ACCESS - // check if pointer is aligned - if (((int)pointer & (sizeOfType - 1)) == 0) { -#endif - *((UInt64*)pointer) = value; -#if ALIGN_ACCESS - } - 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 - + Unsafe.WriteUnaligned<UInt64>(pointer + _offset + position, value); } - finally { - if (pointer != null) { + finally + { + if (pointer != null) + { _buffer.ReleasePointer(); } } @@ -1070,26 +899,33 @@ namespace System.IO { // 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. - public void Write<T>(Int64 position, ref T structure) where T : struct { - if (position < 0) { - throw new ArgumentOutOfRangeException(nameof(position), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + public void Write<T>(Int64 position, ref T structure) where T : struct + { + if (position < 0) + { + throw new ArgumentOutOfRangeException(nameof(position), SR.ArgumentOutOfRange_NeedNonNegNum); } Contract.EndContractBlock(); - if (!_isOpen) { - throw new ObjectDisposedException("UnmanagedMemoryAccessor", Environment.GetResourceString("ObjectDisposed_ViewAccessorClosed")); + if (!_isOpen) + { + throw new ObjectDisposedException("UnmanagedMemoryAccessor", SR.ObjectDisposed_ViewAccessorClosed); } - if (!CanWrite) { - throw new NotSupportedException(Environment.GetResourceString("NotSupported_Writing")); + if (!CanWrite) + { + throw new NotSupportedException(SR.NotSupported_Writing); } UInt32 sizeOfT = Marshal.SizeOfType(typeof(T)); - if (position > _capacity - sizeOfT) { - if (position >= _capacity) { - throw new ArgumentOutOfRangeException(nameof(position), Environment.GetResourceString("ArgumentOutOfRange_PositionLessThanCapacityRequired")); + if (position > _capacity - sizeOfT) + { + if (position >= _capacity) + { + throw new ArgumentOutOfRangeException(nameof(position), SR.ArgumentOutOfRange_PositionLessThanCapacityRequired); } - else { - throw new ArgumentException(Environment.GetResourceString("Argument_NotEnoughBytesToWrite", typeof(T).FullName), nameof(position)); + else + { + throw new ArgumentException(SR.Format(SR.Argument_NotEnoughBytesToWrite, typeof (T).FullName), nameof(position)); } } @@ -1099,52 +935,66 @@ namespace System.IO { // Writes 'count' structs of type T from 'array' (starting at 'offset') into unmanaged memory. - public void WriteArray<T>(Int64 position, T[] array, Int32 offset, Int32 count) where T : struct { - if (array == null) { + public void WriteArray<T>(Int64 position, T[] array, Int32 offset, Int32 count) where T : struct + { + if (array == null) + { throw new ArgumentNullException(nameof(array), "Buffer cannot be null."); } - if (offset < 0) { - throw new ArgumentOutOfRangeException(nameof(offset), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + if (offset < 0) + { + throw new ArgumentOutOfRangeException(nameof(offset), SR.ArgumentOutOfRange_NeedNonNegNum); } - if (count < 0) { - throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + if (count < 0) + { + throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_NeedNonNegNum); } - if (array.Length - offset < count) { - throw new ArgumentException(Environment.GetResourceString("Argument_OffsetAndLengthOutOfBounds")); + if (array.Length - offset < count) + { + throw new ArgumentException(SR.Argument_OffsetAndLengthOutOfBounds); } - if (position < 0) { - throw new ArgumentOutOfRangeException(nameof(position), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + if (position < 0) + { + throw new ArgumentOutOfRangeException(nameof(position), SR.ArgumentOutOfRange_NeedNonNegNum); } - if (position >= Capacity) { - throw new ArgumentOutOfRangeException(nameof(position), Environment.GetResourceString("ArgumentOutOfRange_PositionLessThanCapacityRequired")); + if (position >= Capacity) + { + throw new ArgumentOutOfRangeException(nameof(position), SR.ArgumentOutOfRange_PositionLessThanCapacityRequired); } Contract.EndContractBlock(); - if (!_isOpen) { - throw new ObjectDisposedException("UnmanagedMemoryAccessor", Environment.GetResourceString("ObjectDisposed_ViewAccessorClosed")); + if (!_isOpen) + { + throw new ObjectDisposedException("UnmanagedMemoryAccessor", SR.ObjectDisposed_ViewAccessorClosed); } - if (!CanWrite) { - throw new NotSupportedException(Environment.GetResourceString("NotSupported_Writing")); + if (!CanWrite) + { + throw new NotSupportedException(SR.NotSupported_Writing); } _buffer.WriteArray<T>((UInt64)(_offset + position), array, offset, count); } - private byte InternalReadByte(Int64 position) { + private byte InternalReadByte(Int64 position) + { Debug.Assert(CanRead, "UMA not readable"); Debug.Assert(position >= 0, "position less than 0"); Debug.Assert(position <= _capacity - sizeof(byte), "position is greater than capacity - sizeof(byte)"); byte result; - unsafe { + unsafe + { byte* pointer = null; RuntimeHelpers.PrepareConstrainedRegions(); - try { + try + { _buffer.AcquirePointer(ref pointer); - result = *((byte*)(pointer + _offset + position)); + result = *(pointer + _offset + position); } - finally { - if (pointer != null) { + finally + { + if (pointer != null) + { _buffer.ReleasePointer(); } } @@ -1152,67 +1002,85 @@ namespace System.IO { return result; } - private void InternalWrite(Int64 position, byte value) { + private void InternalWrite(Int64 position, byte value) + { Debug.Assert(CanWrite, "UMA not writable"); Debug.Assert(position >= 0, "position less than 0"); Debug.Assert(position <= _capacity - sizeof(byte), "position is greater than capacity - sizeof(byte)"); - unsafe { + unsafe + { byte* pointer = null; RuntimeHelpers.PrepareConstrainedRegions(); - try { + try + { _buffer.AcquirePointer(ref pointer); - *((byte*)(pointer + _offset + position)) = value; + *(pointer + _offset + position) = value; } - finally { - if (pointer != null) { + finally + { + if (pointer != null) + { _buffer.ReleasePointer(); } } } } - private void EnsureSafeToRead(Int64 position, int sizeOfType) { - if (!_isOpen) { - throw new ObjectDisposedException("UnmanagedMemoryAccessor", Environment.GetResourceString("ObjectDisposed_ViewAccessorClosed")); + private void EnsureSafeToRead(Int64 position, int sizeOfType) + { + if (!_isOpen) + { + throw new ObjectDisposedException("UnmanagedMemoryAccessor", SR.ObjectDisposed_ViewAccessorClosed); } - if (!CanRead) { - throw new NotSupportedException(Environment.GetResourceString("NotSupported_Reading")); + if (!CanRead) + { + throw new NotSupportedException(SR.NotSupported_Reading); } - if (position < 0) { - throw new ArgumentOutOfRangeException(nameof(position), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + if (position < 0) + { + throw new ArgumentOutOfRangeException(nameof(position), SR.ArgumentOutOfRange_NeedNonNegNum); } Contract.EndContractBlock(); - if (position > _capacity - sizeOfType) { - if (position >= _capacity) { - throw new ArgumentOutOfRangeException(nameof(position), Environment.GetResourceString("ArgumentOutOfRange_PositionLessThanCapacityRequired")); + if (position > _capacity - sizeOfType) + { + if (position >= _capacity) + { + throw new ArgumentOutOfRangeException(nameof(position), SR.ArgumentOutOfRange_PositionLessThanCapacityRequired); } - else { - throw new ArgumentException(Environment.GetResourceString("Argument_NotEnoughBytesToRead"), nameof(position)); + else + { + throw new ArgumentException(SR.Argument_NotEnoughBytesToRead, nameof(position)); } } } - private void EnsureSafeToWrite(Int64 position, int sizeOfType) { - if (!_isOpen) { - throw new ObjectDisposedException("UnmanagedMemoryAccessor", Environment.GetResourceString("ObjectDisposed_ViewAccessorClosed")); + private void EnsureSafeToWrite(Int64 position, int sizeOfType) + { + if (!_isOpen) + { + throw new ObjectDisposedException("UnmanagedMemoryAccessor", SR.ObjectDisposed_ViewAccessorClosed); } - if (!CanWrite) { - throw new NotSupportedException(Environment.GetResourceString("NotSupported_Writing")); + if (!CanWrite) + { + throw new NotSupportedException(SR.NotSupported_Writing); } - if (position < 0) { - throw new ArgumentOutOfRangeException(nameof(position), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + if (position < 0) + { + throw new ArgumentOutOfRangeException(nameof(position), SR.ArgumentOutOfRange_NeedNonNegNum); } Contract.EndContractBlock(); - if (position > _capacity - sizeOfType) { - if (position >= _capacity) { - throw new ArgumentOutOfRangeException(nameof(position), Environment.GetResourceString("ArgumentOutOfRange_PositionLessThanCapacityRequired")); + if (position > _capacity - sizeOfType) + { + if (position >= _capacity) + { + throw new ArgumentOutOfRangeException(nameof(position), SR.ArgumentOutOfRange_PositionLessThanCapacityRequired); } - else { - throw new ArgumentException(Environment.GetResourceString("Argument_NotEnoughBytesToWrite", nameof(Byte)), nameof(position)); + else + { + throw new ArgumentException(SR.Format(SR.Argument_NotEnoughBytesToWrite, nameof(Byte)), nameof(position)); } } } - } } |