From 76fc958c10e920cfd3cdafcff82bd37e1dd62e19 Mon Sep 17 00:00:00 2001 From: dahall Date: Tue, 22 Dec 2020 16:26:27 -0700 Subject: [PATCH] Abstracted out read-only methods from SafeAllocatedMemoryHandl into SafeAllocatedMemoryHandleBase --- Core/InteropServices/SafeMemoryHandle.cs | 72 +++++++++++++++++++------------- 1 file changed, 42 insertions(+), 30 deletions(-) diff --git a/Core/InteropServices/SafeMemoryHandle.cs b/Core/InteropServices/SafeMemoryHandle.cs index d07ba356..0dae6fed 100644 --- a/Core/InteropServices/SafeMemoryHandle.cs +++ b/Core/InteropServices/SafeMemoryHandle.cs @@ -235,14 +235,16 @@ namespace Vanara.InteropServices public virtual void UnlockMem(IntPtr hMem) { } } - /// Abstract base class for all SafeHandle derivatives that encapsulate handling unmanaged memory. + /// + /// Abstract base class for all SafeHandle derivatives that encapsulate handling unmanaged memory. This class assumes read-only memory. + /// /// - public abstract class SafeAllocatedMemoryHandle : SafeHandle + public abstract class SafeAllocatedMemoryHandleBase : SafeHandle { - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// The handle. /// if set to true if this class is responsible for freeing the memory on disposal. - protected SafeAllocatedMemoryHandle(IntPtr handle, bool ownsHandle) : base(IntPtr.Zero, ownsHandle) => SetHandle(handle); + protected SafeAllocatedMemoryHandleBase(IntPtr handle, bool ownsHandle) : base(IntPtr.Zero, ownsHandle) => SetHandle(handle); #if DEBUG /// Dumps memory to byte string. @@ -254,20 +256,20 @@ namespace Vanara.InteropServices /// The size in bytes of the allocated memory block. public abstract SizeT Size { get; set; } - /// Performs an explicit conversion from to pointer. - /// The instance. + /// Performs an explicit conversion from to pointer. + /// The instance. /// The result of the conversion. - public static unsafe explicit operator byte*(SafeAllocatedMemoryHandle hMem) => (byte*)hMem.handle; + public static unsafe explicit operator byte*(SafeAllocatedMemoryHandleBase hMem) => (byte*)hMem.handle; - /// Performs an explicit conversion from to . - /// The instance. + /// Performs an explicit conversion from to . + /// The instance. /// The result of the conversion. - public static explicit operator SafeBuffer(SafeAllocatedMemoryHandle hMem) => new SafeBufferImpl(hMem); + public static explicit operator SafeBuffer(SafeAllocatedMemoryHandleBase hMem) => new SafeBufferImpl(hMem); - /// Performs an implicit conversion from to . - /// The instance. + /// Performs an implicit conversion from to . + /// The instance. /// The result of the conversion. - public static implicit operator IntPtr(SafeAllocatedMemoryHandle hMem) => hMem.handle; + public static implicit operator IntPtr(SafeAllocatedMemoryHandleBase hMem) => hMem.handle; #if ALLOWSPAN /// Creates a new span over this allocated memory. @@ -283,19 +285,6 @@ namespace Vanara.InteropServices public virtual Span AsBytes() => AsSpan(Size); #endif - /// Fills the allocated memory with a specific byte value. - /// The byte value. - public virtual void Fill(byte value) => Fill(value, Size); - - /// Fills the allocated memory with a specific byte value. - /// The byte value. - /// The number of bytes in the block of memory to be filled. - public virtual void Fill(byte value, int length) - { - if (length > Size) throw new ArgumentOutOfRangeException(nameof(length)); - handle.FillMemory(value, length); - } - /// Releases the owned handle without releasing the allocated memory and returns a pointer to the current memory. /// A pointer to the currently allocated memory. The caller now has the responsibility to free this memory. public virtual IntPtr TakeOwnership() @@ -307,9 +296,6 @@ namespace Vanara.InteropServices return h; } - /// Zero out all allocated memory. - public virtual void Zero() => Fill(0, Size); - /// Gets a copy of bytes from the allocated memory block. /// The start index. /// The number of bytes to retrieve. @@ -324,12 +310,38 @@ namespace Vanara.InteropServices private class SafeBufferImpl : SafeBuffer { - public SafeBufferImpl(SafeAllocatedMemoryHandle hMem) : base(false) => Initialize((ulong)hMem.Size); + public SafeBufferImpl(SafeAllocatedMemoryHandleBase hMem) : base(false) => Initialize((ulong)hMem.Size); protected override bool ReleaseHandle() => true; } } + /// Abstract base class for all SafeHandle derivatives that encapsulate handling unmanaged memory. + /// + public abstract class SafeAllocatedMemoryHandle : SafeAllocatedMemoryHandleBase + { + /// Initializes a new instance of the class. + /// The handle. + /// if set to true if this class is responsible for freeing the memory on disposal. + protected SafeAllocatedMemoryHandle(IntPtr handle, bool ownsHandle) : base(handle, ownsHandle) { } + + /// Fills the allocated memory with a specific byte value. + /// The byte value. + public virtual void Fill(byte value) => Fill(value, Size); + + /// Fills the allocated memory with a specific byte value. + /// The byte value. + /// The number of bytes in the block of memory to be filled. + public virtual void Fill(byte value, int length) + { + if (length > Size) throw new ArgumentOutOfRangeException(nameof(length)); + handle.FillMemory(value, length); + } + + /// Zero out all allocated memory. + public virtual void Zero() => Fill(0, Size); + } + /// Abstract base class for all SafeAllocatedMemoryHandle derivatives that apply a specific memory handling routine set. /// The implementation. public abstract class SafeMemoryHandle : SafeAllocatedMemoryHandle where TMem : IMemoryMethods, new()