mscorlib(4.0.0.0) API with additions
SafeBuffer.cs
1 using Microsoft.Win32.SafeHandles;
4 using System.Security;
5 
7 {
9  [SecurityCritical]
10  [__DynamicallyInvokable]
11  public abstract class SafeBuffer : SafeHandleZeroOrMinusOneIsInvalid
12  {
13  private static readonly UIntPtr Uninitialized = (UIntPtr.Size == 4) ? ((UIntPtr)uint.MaxValue) : ((UIntPtr)ulong.MaxValue);
14 
15  private UIntPtr _numBytes;
16 
20  [CLSCompliant(false)]
21  [__DynamicallyInvokable]
22  public ulong ByteLength
23  {
24  [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
25  [__DynamicallyInvokable]
26  get
27  {
28  if (_numBytes == Uninitialized)
29  {
30  throw NotInitialized();
31  }
32  return (ulong)_numBytes;
33  }
34  }
35 
39  [__DynamicallyInvokable]
40  protected SafeBuffer(bool ownsHandle)
41  : base(ownsHandle)
42  {
43  _numBytes = Uninitialized;
44  }
45 
51  [CLSCompliant(false)]
52  [__DynamicallyInvokable]
53  public void Initialize(ulong numBytes)
54  {
55  if (numBytes < 0)
56  {
57  throw new ArgumentOutOfRangeException("numBytes", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
58  }
59  if (IntPtr.Size == 4 && numBytes > uint.MaxValue)
60  {
61  throw new ArgumentOutOfRangeException("numBytes", Environment.GetResourceString("ArgumentOutOfRange_AddressSpace"));
62  }
63  if (numBytes >= (ulong)Uninitialized)
64  {
65  throw new ArgumentOutOfRangeException("numBytes", Environment.GetResourceString("ArgumentOutOfRange_UIntPtrMax-1"));
66  }
67  _numBytes = (UIntPtr)numBytes;
68  }
69 
77  [CLSCompliant(false)]
78  [__DynamicallyInvokable]
79  public void Initialize(uint numElements, uint sizeOfEachElement)
80  {
81  if (numElements < 0)
82  {
83  throw new ArgumentOutOfRangeException("numElements", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
84  }
85  if (sizeOfEachElement < 0)
86  {
87  throw new ArgumentOutOfRangeException("sizeOfEachElement", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
88  }
89  if (IntPtr.Size == 4 && numElements * sizeOfEachElement > uint.MaxValue)
90  {
91  throw new ArgumentOutOfRangeException("numBytes", Environment.GetResourceString("ArgumentOutOfRange_AddressSpace"));
92  }
93  if (numElements * sizeOfEachElement >= (ulong)Uninitialized)
94  {
95  throw new ArgumentOutOfRangeException("numElements", Environment.GetResourceString("ArgumentOutOfRange_UIntPtrMax-1"));
96  }
97  _numBytes = (UIntPtr)checked(numElements * sizeOfEachElement);
98  }
99 
106  [CLSCompliant(false)]
107  [__DynamicallyInvokable]
108  public void Initialize<T>(uint numElements) where T : struct
109  {
110  Initialize(numElements, Marshal.AlignedSizeOf<T>());
111  }
112 
116  [CLSCompliant(false)]
117  [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
118  public unsafe void AcquirePointer(ref byte* pointer)
119  {
120  if (_numBytes == Uninitialized)
121  {
122  throw NotInitialized();
123  }
124  pointer = null;
126  try
127  {
128  }
129  finally
130  {
131  bool success = false;
132  DangerousAddRef(ref success);
133  pointer = (byte*)(void*)handle;
134  }
135  }
136 
139  [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
140  [__DynamicallyInvokable]
141  public void ReleasePointer()
142  {
143  if (_numBytes == Uninitialized)
144  {
145  throw NotInitialized();
146  }
147  DangerousRelease();
148  }
149 
155  [CLSCompliant(false)]
156  [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
157  [__DynamicallyInvokable]
158  public unsafe T Read<T>(ulong byteOffset) where T : struct
159  {
160  if (_numBytes == Uninitialized)
161  {
162  throw NotInitialized();
163  }
164  uint num = Marshal.SizeOfType(typeof(T));
165  byte* ptr = (byte*)(void*)handle + byteOffset;
166  SpaceCheck(ptr, num);
167  bool success = false;
169  try
170  {
171  DangerousAddRef(ref success);
172  GenericPtrToStructure(ptr, out T structure, num);
173  return structure;
174  }
175  finally
176  {
177  if (success)
178  {
179  DangerousRelease();
180  }
181  }
182  }
183 
197  [CLSCompliant(false)]
198  [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
199  [__DynamicallyInvokable]
200  public unsafe void ReadArray<T>(ulong byteOffset, T[] array, int index, int count) where T : struct
201  {
202  if (array == null)
203  {
204  throw new ArgumentNullException("array", Environment.GetResourceString("ArgumentNull_Buffer"));
205  }
206  if (index < 0)
207  {
208  throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
209  }
210  if (count < 0)
211  {
212  throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
213  }
214  if (array.Length - index < count)
215  {
216  throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
217  }
218  if (_numBytes == Uninitialized)
219  {
220  throw NotInitialized();
221  }
222  uint sizeofT = Marshal.SizeOfType(typeof(T));
223  uint num = Marshal.AlignedSizeOf<T>();
224  byte* ptr = (byte*)(void*)handle + byteOffset;
225  bool success;
226  checked
227  {
228  SpaceCheck(ptr, (ulong)(unchecked((long)num) * unchecked((long)count)));
229  success = false;
231  }
232  try
233  {
234  DangerousAddRef(ref success);
235  for (int i = 0; i < count; i++)
236  {
237  GenericPtrToStructure(ptr + num * i, out array[i + index], sizeofT);
238  }
239  }
240  finally
241  {
242  if (success)
243  {
244  DangerousRelease();
245  }
246  }
247  }
248 
254  [CLSCompliant(false)]
255  [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
256  [__DynamicallyInvokable]
257  public unsafe void Write<T>(ulong byteOffset, T value) where T : struct
258  {
259  if (_numBytes == Uninitialized)
260  {
261  throw NotInitialized();
262  }
263  uint num = Marshal.SizeOfType(typeof(T));
264  byte* ptr = (byte*)(void*)handle + byteOffset;
265  SpaceCheck(ptr, num);
266  bool success = false;
268  try
269  {
270  DangerousAddRef(ref success);
271  GenericStructureToPtr(ref value, ptr, num);
272  }
273  finally
274  {
275  if (success)
276  {
277  DangerousRelease();
278  }
279  }
280  }
281 
294  [CLSCompliant(false)]
295  [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
296  [__DynamicallyInvokable]
297  public unsafe void WriteArray<T>(ulong byteOffset, T[] array, int index, int count) where T : struct
298  {
299  if (array == null)
300  {
301  throw new ArgumentNullException("array", Environment.GetResourceString("ArgumentNull_Buffer"));
302  }
303  if (index < 0)
304  {
305  throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
306  }
307  if (count < 0)
308  {
309  throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
310  }
311  if (array.Length - index < count)
312  {
313  throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
314  }
315  if (_numBytes == Uninitialized)
316  {
317  throw NotInitialized();
318  }
319  uint sizeofT = Marshal.SizeOfType(typeof(T));
320  uint num = Marshal.AlignedSizeOf<T>();
321  byte* ptr = (byte*)(void*)handle + byteOffset;
322  bool success;
323  checked
324  {
325  SpaceCheck(ptr, (ulong)(unchecked((long)num) * unchecked((long)count)));
326  success = false;
328  }
329  try
330  {
331  DangerousAddRef(ref success);
332  for (int i = 0; i < count; i++)
333  {
334  GenericStructureToPtr(ref array[i + index], ptr + num * i, sizeofT);
335  }
336  }
337  finally
338  {
339  if (success)
340  {
341  DangerousRelease();
342  }
343  }
344  }
345 
346  [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
347  private unsafe void SpaceCheck(byte* ptr, ulong sizeInBytes)
348  {
349  if ((ulong)_numBytes < sizeInBytes)
350  {
351  NotEnoughRoom();
352  }
353  if ((ulong)(ptr - (byte*)(void*)handle) > (ulong)_numBytes - sizeInBytes)
354  {
355  NotEnoughRoom();
356  }
357  }
358 
359  [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
360  private static void NotEnoughRoom()
361  {
362  throw new ArgumentException(Environment.GetResourceString("Arg_BufferTooSmall"));
363  }
364 
365  [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
366  private static InvalidOperationException NotInitialized()
367  {
368  return new InvalidOperationException(Environment.GetResourceString("InvalidOperation_MustCallInitialize"));
369  }
370 
371  [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
372  internal unsafe static void GenericPtrToStructure<T>(byte* ptr, out T structure, uint sizeofT) where T : struct
373  {
374  structure = default(T);
375  PtrToStructureNative(ptr, __makeref(structure), sizeofT);
376  }
377 
378  [MethodImpl(MethodImplOptions.InternalCall)]
379  [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
380  private unsafe static extern void PtrToStructureNative(byte* ptr, TypedReference structure, uint sizeofT);
381 
382  [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
383  internal unsafe static void GenericStructureToPtr<T>(ref T structure, byte* ptr, uint sizeofT) where T : struct
384  {
385  StructureToPtrNative(__makeref(structure), ptr, sizeofT);
386  }
387 
388  [MethodImpl(MethodImplOptions.InternalCall)]
389  [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
390  private unsafe static extern void StructureToPtrNative(TypedReference structure, byte* ptr, uint sizeofT);
391  }
392 }
unsafe void ReadArray< T >(ulong byteOffset, T[] array, int index, int count)
Reads the specified number of value types from memory starting at the offset, and writes them into an...
Definition: SafeBuffer.cs:200
A platform-specific type that is used to represent a pointer or a handle.
Definition: UIntPtr.cs:14
The exception that is thrown when a null reference (Nothing in Visual Basic) is passed to a method th...
SafeBuffer(bool ownsHandle)
Creates a new instance of the T:System.Runtime.InteropServices.SafeBuffer class, and specifies whethe...
Definition: SafeBuffer.cs:40
Definition: __Canon.cs:3
void ReleasePointer()
Releases a pointer that was obtained by the M:System.Runtime.InteropServices.SafeBuffer....
Definition: SafeBuffer.cs:141
void Initialize(ulong numBytes)
Defines the allocation size of the memory region in bytes. You must call this method before you use t...
Definition: SafeBuffer.cs:53
The exception that is thrown when the value of an argument is outside the allowable range of values a...
unsafe void Write< T >(ulong byteOffset, T value)
Writes a value type to memory at the given location.
Definition: SafeBuffer.cs:257
ulong ByteLength
Gets the size of the buffer, in bytes.
Definition: SafeBuffer.cs:23
Cer
Specifies a method's behavior when called within a constrained execution region.
Definition: Cer.cs:5
void Initialize< T >(uint numElements)
Defines the allocation size of the memory region by specifying the number of value types....
Definition: SafeBuffer.cs:108
Provides information about, and means to manipulate, the current environment and platform....
Definition: Environment.cs:21
static int Size
Gets the size of this instance.
Definition: UIntPtr.cs:26
unsafe void AcquirePointer(ref byte *pointer)
Obtains a pointer from a T:System.Runtime.InteropServices.SafeBuffer object for a block of memory.
Definition: SafeBuffer.cs:118
Provides a controlled memory buffer that can be used for reading and writing. Attempts to access memo...
Definition: SafeBuffer.cs:11
A platform-specific type that is used to represent a pointer or a handle.
Definition: IntPtr.cs:14
static void PrepareConstrainedRegions()
Designates a body of code as a constrained execution region (CER).
Provides a collection of methods for allocating unmanaged memory, copying unmanaged memory blocks,...
Definition: Marshal.cs:15
MethodImplOptions
Defines the details of how a method is implemented.
The exception that is thrown when one of the arguments provided to a method is not valid.
static int Size
Gets the size of this instance.
Definition: IntPtr.cs:27
void Initialize(uint numElements, uint sizeOfEachElement)
Specifies the allocation size of the memory buffer by using the specified number of elements and elem...
Definition: SafeBuffer.cs:79
Consistency
Specifies a reliability contract.
Definition: Consistency.cs:5
unsafe void WriteArray< T >(ulong byteOffset, T[] array, int index, int count)
Writes the specified number of value types to a memory location by reading bytes starting from the sp...
Definition: SafeBuffer.cs:297
unsafe T Read< T >(ulong byteOffset)
Reads a value type from memory at the specified offset.
Definition: SafeBuffer.cs:158
Provides a set of static methods and properties that provide support for compilers....