3 // Copyright (c) Microsoft Corporation. All rights reserved.
6 /*============================================================
8 ** Class: UnmanagedMemoryAccessor
10 ** <OWNER>[....]</OWNER>
12 ** Purpose: Provides a fast, AV free, cross-language way of
13 ** accessing unmanaged memory in a random fashion.
15 ** Date: February 7, 2007
17 ===========================================================*/
20 using System.Runtime.InteropServices;
21 using System.Runtime.CompilerServices;
22 using System.Runtime.ConstrainedExecution;
23 using System.Runtime.Versioning;
24 using System.Security.Permissions;
25 using Microsoft.Win32.SafeHandles;
26 using System.Diagnostics.Contracts;
30 /// Perf notes: ReadXXX, WriteXXX (for basic types) acquire and release the
31 /// SafeBuffer pointer rather than relying on generic Read(T) from SafeBuffer because
32 /// this gives better throughput; benchmarks showed about 12-15% better.
33 public class UnmanagedMemoryAccessor : IDisposable {
35 [System.Security.SecurityCritical] // auto-generated
36 private SafeBuffer _buffer;
37 private Int64 _offset;
38 [ContractPublicPropertyName("Capacity")]
39 private Int64 _capacity;
40 private FileAccess _access;
42 private bool _canRead;
43 private bool _canWrite;
45 protected UnmanagedMemoryAccessor() {
49 #region SafeBuffer ctors and initializers
50 // <SecurityKernel Critical="True" Ring="1">
51 // <ReferencesCritical Name="Method: Initialize(SafeBuffer, Int64, Int64, FileAccess):Void" Ring="1" />
53 [System.Security.SecuritySafeCritical]
54 public UnmanagedMemoryAccessor(SafeBuffer buffer, Int64 offset, Int64 capacity) {
55 Initialize(buffer, offset, capacity, FileAccess.Read);
58 [System.Security.SecuritySafeCritical] // auto-generated
59 public UnmanagedMemoryAccessor(SafeBuffer buffer, Int64 offset, Int64 capacity, FileAccess access) {
60 Initialize(buffer, offset, capacity, access);
63 [System.Security.SecuritySafeCritical] // auto-generated
64 [SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
65 protected void Initialize(SafeBuffer buffer, Int64 offset, Int64 capacity, FileAccess access) {
67 throw new ArgumentNullException("buffer");
70 throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
73 throw new ArgumentOutOfRangeException("capacity", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
75 if (buffer.ByteLength < (UInt64)(offset + capacity)) {
76 throw new ArgumentException(Environment.GetResourceString("Argument_OffsetAndCapacityOutOfBounds"));
78 if (access < FileAccess.Read || access > FileAccess.ReadWrite) {
79 throw new ArgumentOutOfRangeException("access");
81 Contract.EndContractBlock();
84 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CalledTwice"));
89 RuntimeHelpers.PrepareConstrainedRegions();
91 buffer.AcquirePointer(ref pointer);
92 if (((byte*)((Int64)pointer + offset + capacity)) < pointer) {
93 throw new ArgumentException(Environment.GetResourceString("Argument_UnmanagedMemAccessorWrapAround"));
97 if (pointer != null) {
98 buffer.ReleasePointer();
105 _capacity = capacity;
108 _canRead = (_access & FileAccess.Read) != 0;
109 _canWrite = (_access & FileAccess.Write) != 0;
114 public Int64 Capacity {
120 public bool CanRead {
122 return _isOpen && _canRead;
126 public bool CanWrite {
128 return _isOpen && _canWrite;
132 protected virtual void Dispose(bool disposing) {
136 public void Dispose() {
138 GC.SuppressFinalize(this);
141 protected bool IsOpen {
142 get { return _isOpen; }
145 public bool ReadBoolean(Int64 position) {
146 int sizeOfType = sizeof(bool);
147 EnsureSafeToRead(position, sizeOfType);
149 byte b = InternalReadByte(position);
153 public byte ReadByte(Int64 position) {
154 int sizeOfType = sizeof(byte);
155 EnsureSafeToRead(position, sizeOfType);
157 return InternalReadByte(position);
160 [System.Security.SecuritySafeCritical] // auto-generated
161 public char ReadChar(Int64 position) {
162 int sizeOfType = sizeof(char);
163 EnsureSafeToRead(position, sizeOfType);
168 byte* pointer = null;
169 RuntimeHelpers.PrepareConstrainedRegions();
171 _buffer.AcquirePointer(ref pointer);
172 pointer += (_offset + position);
175 // check if pointer is aligned
176 if (((int)pointer & (sizeOfType - 1)) == 0) {
178 result = *((char*)(pointer));
182 result = (char)( *pointer | *(pointer + 1) << 8 ) ;
187 if (pointer != null) {
188 _buffer.ReleasePointer();
196 // See comment above.
197 [System.Security.SecuritySafeCritical]
198 public Int16 ReadInt16(Int64 position) {
199 int sizeOfType = sizeof(Int16);
200 EnsureSafeToRead(position, sizeOfType);
205 byte* pointer = null;
206 RuntimeHelpers.PrepareConstrainedRegions();
208 _buffer.AcquirePointer(ref pointer);
209 pointer += (_offset + position);
212 // check if pointer is aligned
213 if (((int)pointer & (sizeOfType - 1)) == 0) {
215 result = *((Int16*)(pointer));
219 result = (Int16)( *pointer | *(pointer + 1) << 8 );
224 if (pointer != null) {
225 _buffer.ReleasePointer();
234 [System.Security.SecuritySafeCritical] // auto-generated
235 public Int32 ReadInt32(Int64 position) {
236 int sizeOfType = sizeof(Int32);
237 EnsureSafeToRead(position, sizeOfType);
241 byte* pointer = null;
242 RuntimeHelpers.PrepareConstrainedRegions();
244 _buffer.AcquirePointer(ref pointer);
245 pointer += (_offset + position);
248 // check if pointer is aligned
249 if (((int)pointer & (sizeOfType - 1)) == 0) {
251 result = *((Int32*)(pointer));
255 result = (Int32)( *pointer | *(pointer + 1) << 8 | *(pointer + 2) << 16 | *(pointer + 3) << 24 );
260 if (pointer != null) {
261 _buffer.ReleasePointer();
269 [System.Security.SecuritySafeCritical] // auto-generated
270 public Int64 ReadInt64(Int64 position) {
271 int sizeOfType = sizeof(Int64);
272 EnsureSafeToRead(position, sizeOfType);
276 byte* pointer = null;
277 RuntimeHelpers.PrepareConstrainedRegions();
279 _buffer.AcquirePointer(ref pointer);
280 pointer += (_offset + position);
283 // check if pointer is aligned
284 if (((int)pointer & (sizeOfType - 1)) == 0) {
286 result = *((Int64*)(pointer));
290 int lo = *pointer | *(pointer + 1) << 8 | *(pointer + 2) << 16 | *(pointer + 3) << 24;
291 int hi = *(pointer + 4) | *(pointer + 5) << 8 | *(pointer + 6) << 16 | *(pointer + 7) << 24;
292 result = (Int64)(((Int64)hi << 32) | (UInt32)lo);
297 if (pointer != null) {
298 _buffer.ReleasePointer();
306 [System.Security.SecuritySafeCritical] // auto-generated
307 public Decimal ReadDecimal(Int64 position) {
308 int sizeOfType = sizeof(Decimal);
309 EnsureSafeToRead(position, sizeOfType);
311 int[] decimalArray = new int[4];
312 ReadArray<int>(position, decimalArray, 0, decimalArray.Length);
314 return new Decimal(decimalArray);
317 [System.Security.SecuritySafeCritical] // auto-generated
318 public Single ReadSingle(Int64 position) {
319 int sizeOfType = sizeof(Single);
320 EnsureSafeToRead(position, sizeOfType);
324 byte* pointer = null;
325 RuntimeHelpers.PrepareConstrainedRegions();
327 _buffer.AcquirePointer(ref pointer);
328 pointer += (_offset + position);
331 // check if pointer is aligned
332 if (((int)pointer & (sizeOfType - 1)) == 0) {
334 result = *((Single*)(pointer));
338 UInt32 tempResult = (UInt32)( *pointer | *(pointer + 1) << 8 | *(pointer + 2) << 16 | *(pointer + 3) << 24 );
339 result = *((float*)&tempResult);
344 if (pointer != null) {
345 _buffer.ReleasePointer();
353 [System.Security.SecuritySafeCritical] // auto-generated
354 public Double ReadDouble(Int64 position) {
355 int sizeOfType = sizeof(Double);
356 EnsureSafeToRead(position, sizeOfType);
360 byte* pointer = null;
361 RuntimeHelpers.PrepareConstrainedRegions();
363 _buffer.AcquirePointer(ref pointer);
364 pointer += (_offset + position);
367 // check if pointer is aligned
368 if (((int)pointer & (sizeOfType - 1)) == 0) {
370 result = *((Double*)(pointer));
375 UInt32 lo = (UInt32)( *pointer | *(pointer + 1) << 8 | *(pointer + 2) << 16 | *(pointer + 3) << 24 );
376 UInt32 hi = (UInt32)( *(pointer + 4) | *(pointer + 5) << 8 | *(pointer + 6) << 16 | *(pointer + 7) << 24 );
377 UInt64 tempResult = ((UInt64)hi) << 32 | lo;
378 result = *((double*)&tempResult);
384 if (pointer != null) {
385 _buffer.ReleasePointer();
393 [System.Security.SecuritySafeCritical] // auto-generated
394 [CLSCompliant(false)]
395 public SByte ReadSByte(Int64 position) {
396 int sizeOfType = sizeof(SByte);
397 EnsureSafeToRead(position, sizeOfType);
401 byte* pointer = null;
402 RuntimeHelpers.PrepareConstrainedRegions();
404 _buffer.AcquirePointer(ref pointer);
405 pointer += (_offset + position);
406 result = *((SByte*)pointer);
409 if (pointer != null) {
410 _buffer.ReleasePointer();
418 [System.Security.SecuritySafeCritical] // auto-generated
419 [CLSCompliant(false)]
420 public UInt16 ReadUInt16(Int64 position) {
421 int sizeOfType = sizeof(UInt16);
422 EnsureSafeToRead(position, sizeOfType);
426 byte* pointer = null;
427 RuntimeHelpers.PrepareConstrainedRegions();
429 _buffer.AcquirePointer(ref pointer);
430 pointer += (_offset + position);
433 // check if pointer is aligned
434 if (((int)pointer & (sizeOfType - 1)) == 0) {
436 result = *((UInt16*)(pointer));
440 result = (UInt16)( *pointer | *(pointer + 1) << 8 );
446 if (pointer != null) {
447 _buffer.ReleasePointer();
455 [System.Security.SecuritySafeCritical] // auto-generated
456 [CLSCompliant(false)]
457 public UInt32 ReadUInt32(Int64 position) {
458 int sizeOfType = sizeof(UInt32);
459 EnsureSafeToRead(position, sizeOfType);
463 byte* pointer = null;
464 RuntimeHelpers.PrepareConstrainedRegions();
466 _buffer.AcquirePointer(ref pointer);
467 pointer += (_offset + position);
470 // check if pointer is aligned
471 if (((int)pointer & (sizeOfType - 1)) == 0) {
473 result = *((UInt32*)(pointer));
477 result = (UInt32)( *pointer | *(pointer + 1) << 8 | *(pointer + 2) << 16 | *(pointer + 3) << 24 );
483 if (pointer != null) {
484 _buffer.ReleasePointer();
492 [System.Security.SecuritySafeCritical] // auto-generated
493 [CLSCompliant(false)]
494 public UInt64 ReadUInt64(Int64 position) {
495 int sizeOfType = sizeof(UInt64);
496 EnsureSafeToRead(position, sizeOfType);
500 byte* pointer = null;
501 RuntimeHelpers.PrepareConstrainedRegions();
503 _buffer.AcquirePointer(ref pointer);
504 pointer += (_offset + position);
507 // check if pointer is aligned
508 if (((int)pointer & (sizeOfType - 1)) == 0) {
510 result = *((UInt64*)(pointer));
514 UInt32 lo = (UInt32)( *pointer | *(pointer + 1) << 8 | *(pointer + 2) << 16 | *(pointer + 3) << 24 );
515 UInt32 hi = (UInt32)( *(pointer + 4) | *(pointer + 5) << 8 | *(pointer + 6) << 16 | *(pointer + 7) << 24 );
516 result = (UInt64)(((UInt64)hi << 32) | lo );
522 if (pointer != null) {
523 _buffer.ReleasePointer();
531 // Reads a struct of type T from unmanaged memory, into the reference pointed to by ref value.
532 // Note: this method is not safe, since it overwrites the contents of a structure, it can be
533 // used to modify the private members of a struct. Furthermore, using this with a struct that
534 // contains reference members will most likely cause the runtime to AV. Note, that despite
535 // various checks made by the C++ code used by Marshal.PtrToStructure, Marshal.PtrToStructure
536 // will still overwrite privates and will also crash the runtime when used with structs
537 // containing reference members. For this reason, I am sticking an UnmanagedCode requirement
538 // on this method to match Marshal.PtrToStructure.
540 // Alos note that this method is most performant when used with medium to large sized structs
541 // (larger than 8 bytes -- though this is number is JIT and architecture dependent). As
542 // such, it is best to use the ReadXXX methods for small standard types such as ints, longs,
545 [System.Security.SecurityCritical] // auto-generated_required
546 public void Read<T>(Int64 position, out T structure) where T : struct {
548 throw new ArgumentOutOfRangeException("position", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
550 Contract.EndContractBlock();
553 throw new ObjectDisposedException("UnmanagedMemoryAccessor", Environment.GetResourceString("ObjectDisposed_ViewAccessorClosed"));
556 throw new NotSupportedException(Environment.GetResourceString("NotSupported_Reading"));
559 UInt32 sizeOfT = Marshal.SizeOfType(typeof(T));
560 if (position > _capacity - sizeOfT) {
561 if (position >= _capacity) {
562 throw new ArgumentOutOfRangeException("position", Environment.GetResourceString("ArgumentOutOfRange_PositionLessThanCapacityRequired"));
565 throw new ArgumentException(Environment.GetResourceString("Argument_NotEnoughBytesToRead", typeof(T).FullName), "position");
569 structure = _buffer.Read<T>((UInt64)(_offset + position));
572 // Reads 'count' structs of type T from unmanaged memory, into 'array' starting at 'offset'.
573 // Note: this method is not safe, since it overwrites the contents of structures, it can
574 // be used to modify the private members of a struct. Furthermore, using this with a
575 // struct that contains reference members will most likely cause the runtime to AV. This
576 // is consistent with Marshal.PtrToStructure.
578 [System.Security.SecurityCritical] // auto-generated_required
579 public int ReadArray<T>(Int64 position, T[] array, Int32 offset, Int32 count) where T : struct {
581 throw new ArgumentNullException("array", "Buffer cannot be null.");
584 throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
587 throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
589 if (array.Length - offset < count) {
590 throw new ArgumentException(Environment.GetResourceString("Argument_OffsetAndLengthOutOfBounds"));
592 Contract.EndContractBlock();
595 throw new ObjectDisposedException("UnmanagedMemoryAccessor", Environment.GetResourceString("ObjectDisposed_ViewAccessorClosed"));
598 throw new NotSupportedException(Environment.GetResourceString("NotSupported_Reading"));
602 throw new ArgumentOutOfRangeException("position", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
605 UInt32 sizeOfT = Marshal.AlignedSizeOf<T>();
607 // only check position and ask for fewer Ts if count is too big
608 if (position >= _capacity) {
609 throw new ArgumentOutOfRangeException("position", Environment.GetResourceString("ArgumentOutOfRange_PositionLessThanCapacityRequired"));
613 long spaceLeft = _capacity - position;
618 ulong spaceNeeded = (ulong)(sizeOfT * count);
619 if ((ulong)spaceLeft < spaceNeeded) {
620 n = (int)(spaceLeft / sizeOfT);
624 _buffer.ReadArray<T>((UInt64)(_offset + position), array, offset, n);
629 // ************** Write Methods ****************/
631 // The following 13 WriteXXX methods write a value of type XXX into unmanaged memory at 'positon'.
632 // The bounds of the unmanaged memory are checked against to ensure that there is enough
633 // space after 'position' to write a value of type XXX. XXX can be a bool, byte, char, decimal,
634 // double, short, int, long, sbyte, float, ushort, uint, or ulong.
637 public void Write(Int64 position, bool value) {
638 int sizeOfType = sizeof(bool);
639 EnsureSafeToWrite(position, sizeOfType);
641 byte b = (byte)(value ? 1 : 0);
642 InternalWrite(position, b);
645 public void Write(Int64 position, byte value) {
646 int sizeOfType = sizeof(byte);
647 EnsureSafeToWrite(position, sizeOfType);
649 InternalWrite(position, value);
652 [System.Security.SecuritySafeCritical] // auto-generated
653 public void Write(Int64 position, char value) {
654 int sizeOfType = sizeof(char);
655 EnsureSafeToWrite(position, sizeOfType);
658 byte* pointer = null;
659 RuntimeHelpers.PrepareConstrainedRegions();
661 _buffer.AcquirePointer(ref pointer);
662 pointer += (_offset + position);
665 // check if pointer is aligned
666 if (((int)pointer & (sizeOfType - 1)) == 0) {
668 *((char*)pointer) = value;
672 *(pointer) = (byte)value;
673 *(pointer+1) = (byte)(value >> 8);
678 if (pointer != null) {
679 _buffer.ReleasePointer();
687 [System.Security.SecuritySafeCritical] // auto-generated
688 public void Write(Int64 position, Int16 value) {
689 int sizeOfType = sizeof(Int16);
690 EnsureSafeToWrite(position, sizeOfType);
693 byte* pointer = null;
694 RuntimeHelpers.PrepareConstrainedRegions();
696 _buffer.AcquirePointer(ref pointer);
697 pointer += (_offset + position);
700 // check if pointer is aligned
701 if (((int)pointer & (sizeOfType - 1)) == 0) {
703 *((Int16*)pointer) = value;
707 *(pointer) = (byte)value;
708 *(pointer + 1) = (byte)(value >> 8);
713 if (pointer != null) {
714 _buffer.ReleasePointer();
721 [System.Security.SecuritySafeCritical] // auto-generated
722 public void Write(Int64 position, Int32 value) {
723 int sizeOfType = sizeof(Int32);
724 EnsureSafeToWrite(position, sizeOfType);
727 byte* pointer = null;
728 RuntimeHelpers.PrepareConstrainedRegions();
730 _buffer.AcquirePointer(ref pointer);
731 pointer += (_offset + position);
734 // check if pointer is aligned
735 if (((int)pointer & (sizeOfType - 1)) == 0) {
737 *((Int32*)pointer) = value;
741 *(pointer) = (byte)value;
742 *(pointer + 1) = (byte)(value >> 8);
743 *(pointer + 2) = (byte)(value >> 16);
744 *(pointer + 3) = (byte)(value >> 24);
749 if (pointer != null) {
750 _buffer.ReleasePointer();
756 [System.Security.SecuritySafeCritical] // auto-generated
757 public void Write(Int64 position, Int64 value) {
758 int sizeOfType = sizeof(Int64);
759 EnsureSafeToWrite(position, sizeOfType);
762 byte* pointer = null;
763 RuntimeHelpers.PrepareConstrainedRegions();
765 _buffer.AcquirePointer(ref pointer);
766 pointer += (_offset + position);
768 // check if pointer is aligned
769 if (((int)pointer & (sizeOfType - 1)) == 0) {
771 *((Int64*)pointer) = value;
775 *(pointer) = (byte)value;
776 *(pointer + 1) = (byte)(value >> 8);
777 *(pointer + 2) = (byte)(value >> 16);
778 *(pointer + 3) = (byte)(value >> 24);
779 *(pointer + 4) = (byte)(value >> 32);
780 *(pointer + 5) = (byte)(value >> 40);
781 *(pointer + 6) = (byte)(value >> 48);
782 *(pointer + 7) = (byte)(value >> 56);
787 if (pointer != null) {
788 _buffer.ReleasePointer();
794 [System.Security.SecuritySafeCritical] // auto-generated
795 public void Write(Int64 position, Decimal value) {
796 int sizeOfType = sizeof(Decimal);
797 EnsureSafeToWrite(position, sizeOfType);
799 byte[] decimalArray = new byte[16];
800 Decimal.GetBytes(value, decimalArray);
802 int[] bits = new int[4];
803 int flags = ((int)decimalArray[12]) | ((int)decimalArray[13] << 8) | ((int)decimalArray[14] << 16) | ((int)decimalArray[15] << 24);
804 int lo = ((int)decimalArray[0]) | ((int)decimalArray[1] << 8) | ((int)decimalArray[2] << 16) | ((int)decimalArray[3] << 24);
805 int mid = ((int)decimalArray[4]) | ((int)decimalArray[5] << 8) | ((int)decimalArray[6] << 16) | ((int)decimalArray[7] << 24);
806 int hi = ((int)decimalArray[8]) | ((int)decimalArray[9] << 8) | ((int)decimalArray[10] << 16) | ((int)decimalArray[11] << 24);
812 WriteArray<int>(position, bits, 0, bits.Length);
815 [System.Security.SecuritySafeCritical] // auto-generated
816 public void Write(Int64 position, Single value) {
817 int sizeOfType = sizeof(Single);
818 EnsureSafeToWrite(position, sizeOfType);
821 byte* pointer = null;
822 RuntimeHelpers.PrepareConstrainedRegions();
824 _buffer.AcquirePointer(ref pointer);
825 pointer += (_offset + position);
827 // check if pointer is aligned
828 if (((int)pointer & (sizeOfType - 1)) == 0) {
830 *((Single*)pointer) = value;
834 UInt32 tmpValue = *(UInt32*)&value;
835 *(pointer) = (byte)tmpValue;
836 *(pointer + 1) = (byte)(tmpValue >> 8);
837 *(pointer + 2) = (byte)(tmpValue >> 16);
838 *(pointer + 3) = (byte)(tmpValue >> 24);
844 if (pointer != null) {
845 _buffer.ReleasePointer();
851 [System.Security.SecuritySafeCritical] // auto-generated
852 public void Write(Int64 position, Double value) {
853 int sizeOfType = sizeof(Double);
854 EnsureSafeToWrite(position, sizeOfType);
857 byte* pointer = null;
858 RuntimeHelpers.PrepareConstrainedRegions();
860 _buffer.AcquirePointer(ref pointer);
861 pointer += (_offset + position);
863 // check if pointer is aligned
864 if (((int)pointer & (sizeOfType - 1)) == 0) {
866 *((Double*)pointer) = value;
870 UInt64 tmpValue = *(UInt64 *)&value;
871 *(pointer) = (byte) tmpValue;
872 *(pointer + 1) = (byte) (tmpValue >> 8);
873 *(pointer + 2) = (byte) (tmpValue >> 16);
874 *(pointer + 3) = (byte) (tmpValue >> 24);
875 *(pointer + 4) = (byte) (tmpValue >> 32);
876 *(pointer + 5) = (byte) (tmpValue >> 40);
877 *(pointer + 6) = (byte) (tmpValue >> 48);
878 *(pointer + 7) = (byte) (tmpValue >> 56);
884 if (pointer != null) {
885 _buffer.ReleasePointer();
891 [System.Security.SecuritySafeCritical] // auto-generated
892 [CLSCompliant(false)]
893 public void Write(Int64 position, SByte value) {
894 int sizeOfType = sizeof(SByte);
895 EnsureSafeToWrite(position, sizeOfType);
898 byte* pointer = null;
899 RuntimeHelpers.PrepareConstrainedRegions();
901 _buffer.AcquirePointer(ref pointer);
902 pointer += (_offset + position);
903 *((SByte*)pointer) = value;
906 if (pointer != null) {
907 _buffer.ReleasePointer();
913 [System.Security.SecuritySafeCritical] // auto-generated
914 [CLSCompliant(false)]
915 public void Write(Int64 position, UInt16 value) {
916 int sizeOfType = sizeof(UInt16);
917 EnsureSafeToWrite(position, sizeOfType);
920 byte* pointer = null;
921 RuntimeHelpers.PrepareConstrainedRegions();
923 _buffer.AcquirePointer(ref pointer);
924 pointer += (_offset + position);
927 // check if pointer is aligned
928 if (((int)pointer & (sizeOfType - 1)) == 0) {
930 *((UInt16*)pointer) = value;
934 *(pointer) = (byte)value;
935 *(pointer + 1) = (byte)(value >> 8);
940 if (pointer != null) {
941 _buffer.ReleasePointer();
947 [System.Security.SecuritySafeCritical] // auto-generated
948 [CLSCompliant(false)]
949 public void Write(Int64 position, UInt32 value) {
950 int sizeOfType = sizeof(UInt32);
951 EnsureSafeToWrite(position, sizeOfType);
954 byte* pointer = null;
955 RuntimeHelpers.PrepareConstrainedRegions();
957 _buffer.AcquirePointer(ref pointer);
958 pointer += (_offset + position);
961 // check if pointer is aligned
962 if (((int)pointer & (sizeOfType - 1)) == 0) {
964 *((UInt32*)pointer) = value;
968 *(pointer) = (byte)value;
969 *(pointer + 1) = (byte)(value >> 8);
970 *(pointer + 2) = (byte)(value >> 16);
971 *(pointer + 3) = (byte)(value >> 24);
977 if (pointer != null) {
978 _buffer.ReleasePointer();
984 [System.Security.SecuritySafeCritical] // auto-generated
985 [CLSCompliant(false)]
986 public void Write(Int64 position, UInt64 value) {
987 int sizeOfType = sizeof(UInt64);
988 EnsureSafeToWrite(position, sizeOfType);
991 byte* pointer = null;
992 RuntimeHelpers.PrepareConstrainedRegions();
994 _buffer.AcquirePointer(ref pointer);
995 pointer += (_offset + position);
997 // check if pointer is aligned
998 if (((int)pointer & (sizeOfType - 1)) == 0) {
1000 *((UInt64*)pointer) = value;
1004 *(pointer) = (byte)value;
1005 *(pointer + 1) = (byte)(value >> 8);
1006 *(pointer + 2) = (byte)(value >> 16);
1007 *(pointer + 3) = (byte)(value >> 24);
1008 *(pointer + 4) = (byte)(value >> 32);
1009 *(pointer + 5) = (byte)(value >> 40);
1010 *(pointer + 6) = (byte)(value >> 48);
1011 *(pointer + 7) = (byte)(value >> 56);
1017 if (pointer != null) {
1018 _buffer.ReleasePointer();
1024 // Writes the struct pointed to by ref value into unmanaged memory. Note that this method
1025 // is most performant when used with medium to large sized structs (larger than 8 bytes
1026 // though this is number is JIT and architecture dependent). As such, it is best to use
1027 // the WriteX methods for small standard types such as ints, longs, bools, etc.
1029 [System.Security.SecurityCritical] // auto-generated_required
1030 public void Write<T>(Int64 position, ref T structure) where T : struct {
1032 throw new ArgumentOutOfRangeException("position", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
1034 Contract.EndContractBlock();
1037 throw new ObjectDisposedException("UnmanagedMemoryAccessor", Environment.GetResourceString("ObjectDisposed_ViewAccessorClosed"));
1040 throw new NotSupportedException(Environment.GetResourceString("NotSupported_Writing"));
1043 UInt32 sizeOfT = Marshal.SizeOfType(typeof(T));
1044 if (position > _capacity - sizeOfT) {
1045 if (position >= _capacity) {
1046 throw new ArgumentOutOfRangeException("position", Environment.GetResourceString("ArgumentOutOfRange_PositionLessThanCapacityRequired"));
1049 throw new ArgumentException(Environment.GetResourceString("Argument_NotEnoughBytesToWrite", typeof(T).FullName), "position");
1053 _buffer.Write<T>((UInt64)(_offset + position), structure);
1056 // Writes 'count' structs of type T from 'array' (starting at 'offset') into unmanaged memory.
1059 [System.Security.SecurityCritical] // auto-generated_required
1060 public void WriteArray<T>(Int64 position, T[] array, Int32 offset, Int32 count) where T : struct {
1061 if (array == null) {
1062 throw new ArgumentNullException("array", "Buffer cannot be null.");
1065 throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
1068 throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
1070 if (array.Length - offset < count) {
1071 throw new ArgumentException(Environment.GetResourceString("Argument_OffsetAndLengthOutOfBounds"));
1074 throw new ArgumentOutOfRangeException("position", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
1076 if (position >= Capacity) {
1077 throw new ArgumentOutOfRangeException("position", Environment.GetResourceString("ArgumentOutOfRange_PositionLessThanCapacityRequired"));
1079 Contract.EndContractBlock();
1082 throw new ObjectDisposedException("UnmanagedMemoryAccessor", Environment.GetResourceString("ObjectDisposed_ViewAccessorClosed"));
1085 throw new NotSupportedException(Environment.GetResourceString("NotSupported_Writing"));
1088 _buffer.WriteArray<T>((UInt64)(_offset + position), array, offset, count);
1091 [System.Security.SecuritySafeCritical] // auto-generated
1092 private byte InternalReadByte(Int64 position) {
1093 Contract.Assert(CanRead, "UMA not readable");
1094 Contract.Assert(position >= 0, "position less than 0");
1095 Contract.Assert(position <= _capacity - sizeof(byte), "position is greater than capacity - sizeof(byte)");
1099 byte* pointer = null;
1100 RuntimeHelpers.PrepareConstrainedRegions();
1102 _buffer.AcquirePointer(ref pointer);
1103 result = *((byte*)(pointer + _offset + position));
1106 if (pointer != null) {
1107 _buffer.ReleasePointer();
1114 [System.Security.SecuritySafeCritical] // auto-generated
1115 private void InternalWrite(Int64 position, byte value) {
1116 Contract.Assert(CanWrite, "UMA not writeable");
1117 Contract.Assert(position >= 0, "position less than 0");
1118 Contract.Assert(position <= _capacity - sizeof(byte), "position is greater than capacity - sizeof(byte)");
1121 byte* pointer = null;
1122 RuntimeHelpers.PrepareConstrainedRegions();
1124 _buffer.AcquirePointer(ref pointer);
1125 *((byte*)(pointer + _offset + position)) = value;
1128 if (pointer != null) {
1129 _buffer.ReleasePointer();
1135 private void EnsureSafeToRead(Int64 position, int sizeOfType) {
1137 throw new ObjectDisposedException("UnmanagedMemoryAccessor", Environment.GetResourceString("ObjectDisposed_ViewAccessorClosed"));
1140 throw new NotSupportedException(Environment.GetResourceString("NotSupported_Reading"));
1143 throw new ArgumentOutOfRangeException("position", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
1145 Contract.EndContractBlock();
1146 if (position > _capacity - sizeOfType) {
1147 if (position >= _capacity) {
1148 throw new ArgumentOutOfRangeException("position", Environment.GetResourceString("ArgumentOutOfRange_PositionLessThanCapacityRequired"));
1151 throw new ArgumentException(Environment.GetResourceString("Argument_NotEnoughBytesToRead"), "position");
1156 private void EnsureSafeToWrite(Int64 position, int sizeOfType) {
1158 throw new ObjectDisposedException("UnmanagedMemoryAccessor", Environment.GetResourceString("ObjectDisposed_ViewAccessorClosed"));
1161 throw new NotSupportedException(Environment.GetResourceString("NotSupported_Writing"));
1164 throw new ArgumentOutOfRangeException("position", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
1166 Contract.EndContractBlock();
1167 if (position > _capacity - sizeOfType) {
1168 if (position >= _capacity) {
1169 throw new ArgumentOutOfRangeException("position", Environment.GetResourceString("ArgumentOutOfRange_PositionLessThanCapacityRequired"));
1172 throw new ArgumentException(Environment.GetResourceString("Argument_NotEnoughBytesToWrite", "Byte"), "position");