3 // Copyright (c) Microsoft Corporation. All rights reserved.
6 /*============================================================
8 ** Class: PinnedBufferMemoryStream
10 ** <OWNER>Microsoft</OWNER>
13 ** Purpose: Pins a byte[], exposing it as an unmanaged memory
14 ** stream. Used in ResourceReader for corner cases.
17 ===========================================================*/
19 using System.Runtime.InteropServices;
20 using System.Diagnostics.Contracts;
23 internal sealed unsafe class PinnedBufferMemoryStream : UnmanagedMemoryStream
25 private byte[] _array;
26 private GCHandle _pinningHandle;
28 // The new inheritance model requires a Critical default ctor since base (UnmanagedMemoryStream) has one
29 [System.Security.SecurityCritical]
30 private PinnedBufferMemoryStream():base(){}
32 [System.Security.SecurityCritical] // auto-generated
33 internal PinnedBufferMemoryStream(byte[] array)
35 Contract.Assert(array != null, "Array can't be null");
37 int len = array.Length;
38 // Handle 0 length byte arrays specially.
45 _pinningHandle = new GCHandle(array, GCHandleType.Pinned);
46 // Now the byte[] is pinned for the lifetime of this instance.
47 // But I also need to get a pointer to that block of memory...
48 fixed(byte* ptr = _array)
49 Initialize(ptr, len, len, FileAccess.Read, true);
52 ~PinnedBufferMemoryStream()
57 [System.Security.SecuritySafeCritical] // auto-generated
58 protected override void Dispose(bool disposing)
61 _pinningHandle.Free();
65 // To help track down lifetime issues on checked builds, force
69 GC.WaitForPendingFinalizers();
72 base.Dispose(disposing);