diff --git a/Core/InteropServices/SafeMemoryHandle.cs b/Core/InteropServices/SafeMemoryHandle.cs
index cabcf84b..bc869a25 100644
--- a/Core/InteropServices/SafeMemoryHandle.cs
+++ b/Core/InteropServices/SafeMemoryHandle.cs
@@ -16,16 +16,17 @@ namespace Vanara.InteropServices
{
/// Each string is separated by a single '\0' character and is terminated by two '\0' characters.
Concatenated,
- /// A contiguous block of memory containing an array of pointers to strings followed by a NULL pointer and then followed by the actual strings.
+
+ ///
+ /// A contiguous block of memory containing an array of pointers to strings followed by a NULL pointer and then followed by the
+ /// actual strings.
+ ///
Packed
}
/// Interface to capture unmanaged memory methods.
- public interface IMemoryMethods
+ public interface IMemoryMethods : ISimpleMemoryMethods
{
- /// Gets the allocation method.
- Func AllocMem { get; }
-
/// Gets the Ansi allocation method.
Func AllocSecureStringAnsi { get; }
@@ -38,9 +39,6 @@ namespace Vanara.InteropServices
/// Gets the Unicode string allocation method.
Func AllocStringUni { get; }
- /// Gets the free method.
- Action FreeMem { get; }
-
/// Gets the Ansi free method.
Action FreeSecureStringAnsi { get; }
@@ -62,8 +60,9 @@ namespace Vanara.InteropServices
SizeT Size { get; set; }
///
- /// Adds reference to other SafeMemoryHandle objects, the pointer to which are referred to by this object. This is to ensure that such objects being
- /// referred to wouldn't be unreferenced until this object is active. For e.g. when this object is an array of pointers to other objects
+ /// Adds reference to other SafeMemoryHandle objects, the pointer to which are referred to by this object. This is to ensure that
+ /// such objects being referred to wouldn't be unreferenced until this object is active. For e.g. when this object is an array of
+ /// pointers to other objects
///
/// Collection of SafeMemoryHandle objects referred to by this object.
void AddSubReference(IEnumerable children);
@@ -73,8 +72,8 @@ namespace Vanara.InteropServices
IntPtr DangerousGetHandle();
///
- /// Extracts an array of structures of containing items. This call can cause memory
- /// exceptions if the pointer does not have sufficient allocated memory to retrieve all the structures.
+ /// Extracts an array of structures of containing items. This
+ /// call can cause memory exceptions if the pointer does not have sufficient allocated memory to retrieve all the structures.
///
/// The type of the structures to retrieve.
/// The number of structures to retrieve.
@@ -83,8 +82,8 @@ namespace Vanara.InteropServices
T[] ToArray(int count, int prefixBytes = 0);
///
- /// Extracts an enumeration of structures of containing items. This call can cause
- /// memory exceptions if the pointer does not have sufficient allocated memory to retrieve all the structures.
+ /// Extracts an enumeration of structures of containing items. This call can cause memory exceptions if the pointer does not have sufficient allocated memory to retrieve all the structures.
///
/// The type of the structures to retrieve.
/// The number of structures to retrieve.
@@ -106,28 +105,80 @@ namespace Vanara.InteropServices
string ToString(int len, int prefixBytes, CharSet charSet = CharSet.Unicode);
///
- /// Gets an enumerated list of strings from a block of unmanaged memory where each string is separated by a single '\0' character and is terminated by
- /// two '\0' characters.
+ /// Gets an enumerated list of strings from a block of unmanaged memory where each string is separated by a single '\0' character
+ /// and is terminated by two '\0' characters.
///
/// The character set of the strings.
/// Number of bytes preceding the array of string pointers.
/// Enumeration of strings.
IEnumerable ToStringEnum(CharSet charSet = CharSet.Auto, int prefixBytes = 0);
- /// Returns an enumeration of strings from memory where each string is pointed to by a preceding list of pointers of length .
+ ///
+ /// Returns an enumeration of strings from memory where each string is pointed to by a preceding list of pointers of length
+ /// .
+ ///
/// The count.
/// The character set of the strings.
/// Number of bytes preceding the array of string pointers.
/// An enumerated list of strings.
IEnumerable ToStringEnum(int count, CharSet charSet = CharSet.Auto, int prefixBytes = 0);
- /// Marshals data from this block of memory to a newly allocated managed object of the type specified by a generic type parameter.
+ ///
+ /// Marshals data from this block of memory to a newly allocated managed object of the type specified by a generic type parameter.
+ ///
/// The type of the object to which the data is to be copied. This must be a structure.
/// Number of bytes preceding the structure.
/// A managed object that contains the data that this holds.
T ToStructure(int prefixBytes = 0);
}
+ /// Interface to capture unmanaged simple (alloc/free) memory methods.
+ public interface ISimpleMemoryMethods
+ {
+ /// Gets the allocation method.
+ Func AllocMem { get; }
+
+ /// Gets the free method.
+ Action FreeMem { get; }
+ }
+
+ /// Implementation of using just the methods from .
+ /// The type of the simple.
+ ///
+ public class MemoryMethodsFromSimple : IMemoryMethods where TSimple : ISimpleMemoryMethods, new()
+ {
+ /// A static instance of TSimple.
+ public static TSimple SimpleInstance = new TSimple();
+
+ /// Gets the Ansi allocation method.
+ public Func AllocSecureStringAnsi => s => StringHelper.AllocSecureString(s, CharSet.Ansi, AllocMem);
+
+ /// Gets the Unicode allocation method.
+ public Func AllocSecureStringUni => s => StringHelper.AllocSecureString(s, CharSet.Unicode, AllocMem);
+
+ /// Gets the Ansi string allocation method.
+ public Func AllocStringAnsi => s => StringHelper.AllocString(s, CharSet.Ansi, AllocMem);
+
+ /// Gets the Unicode string allocation method.
+ public Func AllocStringUni => s => StringHelper.AllocString(s, CharSet.Unicode, AllocMem);
+
+ /// Gets the Ansi free method.
+ public Action FreeSecureStringAnsi => FreeMem;
+
+ /// Gets the Unicode free method.
+ public Action FreeSecureStringUni => FreeMem;
+
+ /// Gets the reallocation method.
+ ///
+ public Func ReAllocMem => throw new NotImplementedException();
+
+ /// Gets the allocation method.
+ public Func AllocMem => SimpleInstance.AllocMem;
+
+ /// Gets the free method.
+ public Action FreeMem => SimpleInstance.FreeMem;
+ }
+
/// Abstract base class for all SafeHandle derivatives that encapsulate handling unmanaged memory.
///
public abstract class SafeAllocatedMemoryHandle : SafeHandle
@@ -137,16 +188,32 @@ namespace Vanara.InteropServices
/// 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);
+ /// Dumps memory to byte string.
+ [ExcludeFromCodeCoverage]
+ public string Dump => Size == 0 ? "" : string.Join(" ", GetBytes(0, Size).Select(b => b.ToString("X2")).ToArray());
+
/// Gets or sets the size in bytes of the allocated memory block.
/// The size in bytes of the allocated memory block.
public abstract SizeT Size { get; set; }
#if DEBUG
- /// Dumps memory to byte string.
- [ExcludeFromCodeCoverage]
- public string Dump => Size == 0 ? "" : string.Join(" ", GetBytes(0, Size).Select(b => b.ToString("X2")).ToArray());
#endif
+ /// 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;
+
+ /// Performs an explicit conversion from to .
+ /// The instance.
+ /// The result of the conversion.
+ public static explicit operator SafeBuffer(SafeAllocatedMemoryHandle hMem) => new SafeBufferImpl(hMem);
+
+ /// Performs an implicit conversion from to .
+ /// The instance.
+ /// The result of the conversion.
+ public static implicit operator IntPtr(SafeAllocatedMemoryHandle hMem) => hMem.handle;
+
/// Fills the allocated memory with a specific byte value.
/// The byte value.
public virtual void Fill(byte value) => Fill(value, Size);
@@ -186,21 +253,6 @@ namespace Vanara.InteropServices
return ret;
}
- /// Performs an explicit conversion from to .
- /// The instance.
- /// The result of the conversion.
- public static explicit operator SafeBuffer(SafeAllocatedMemoryHandle hMem) => new SafeBufferImpl(hMem);
-
- /// 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;
-
- /// Performs an implicit conversion from to .
- /// The instance.
- /// The result of the conversion.
- public static implicit operator IntPtr(SafeAllocatedMemoryHandle hMem) => hMem.handle;
-
private class SafeBufferImpl : SafeBuffer
{
public SafeBufferImpl(SafeAllocatedMemoryHandle hMem) : base(false) => Initialize((ulong)hMem.Size);
@@ -235,7 +287,10 @@ namespace Vanara.InteropServices
/// if set to true if this class is responsible for freeing the memory on disposal.
protected SafeMemoryHandle(IntPtr handle, SizeT size, bool ownsHandle) : base(handle, ownsHandle) => sz = size;
- /// Allocates from unmanaged memory to represent an array of pointers and marshals the unmanaged pointers (IntPtr) to the native array equivalent.
+ ///
+ /// Allocates from unmanaged memory to represent an array of pointers and marshals the unmanaged pointers (IntPtr) to the native
+ /// array equivalent.
+ ///
/// Array of unmanaged pointers
/// SafeHGlobalHandle object to an native (unmanaged) array of pointers
protected SafeMemoryHandle(byte[] bytes) : base(IntPtr.Zero, true)
@@ -284,8 +339,8 @@ namespace Vanara.InteropServices
/// When overridden in a derived class, executes the code required to free the handle.
///
- /// true if the handle is released successfully; otherwise, in the event of a catastrophic failure, false. In this case, it generates a
- /// releaseHandleFailed MDA Managed Debugging Assistant.
+ /// true if the handle is released successfully; otherwise, in the event of a catastrophic failure, false. In this case, it
+ /// generates a releaseHandleFailed MDA Managed Debugging Assistant.
///
protected override bool ReleaseHandle()
{
@@ -307,8 +362,8 @@ namespace Vanara.InteropServices
public abstract class SafeMemoryHandleExt : SafeMemoryHandle, ISafeMemoryHandle where TMem : IMemoryMethods, new()
{
///
- /// Maintains reference to other SafeMemoryHandleExt objects, the pointer to which are referred to by this object. This is to ensure that such objects
- /// being referred to wouldn't be unreferenced until this object is active.
+ /// Maintains reference to other SafeMemoryHandleExt objects, the pointer to which are referred to by this object. This is to ensure
+ /// that such objects being referred to wouldn't be unreferenced until this object is active.
///
private List references;
@@ -323,12 +378,18 @@ namespace Vanara.InteropServices
/// if set to true if this class is responsible for freeing the memory on disposal.
protected SafeMemoryHandleExt(IntPtr handle, SizeT size, bool ownsHandle) : base(handle, size, ownsHandle) { }
- /// Allocates from unmanaged memory to represent an array of pointers and marshals the unmanaged pointers (IntPtr) to the native array equivalent.
+ ///
+ /// Allocates from unmanaged memory to represent an array of pointers and marshals the unmanaged pointers (IntPtr) to the native
+ /// array equivalent.
+ ///
/// Array of unmanaged pointers
/// SafeHGlobalHandle object to an native (unmanaged) array of pointers
protected SafeMemoryHandleExt(byte[] bytes) : base(bytes) { }
- /// Allocates from unmanaged memory to represent an array of pointers and marshals the unmanaged pointers (IntPtr) to the native array equivalent.
+ ///
+ /// Allocates from unmanaged memory to represent an array of pointers and marshals the unmanaged pointers (IntPtr) to the native
+ /// array equivalent.
+ ///
/// Array of unmanaged pointers
/// SafeMemoryHandleExt object to an native (unmanaged) array of pointers
protected SafeMemoryHandleExt(IntPtr[] values) : this(IntPtr.Size * values.Length) => Marshal.Copy(values, 0, handle, values.Length);
@@ -344,8 +405,9 @@ namespace Vanara.InteropServices
}
///
- /// Adds reference to other SafeMemoryHandle objects, the pointer to which are referred to by this object. This is to ensure that such objects being
- /// referred to wouldn't be unreferenced until this object is active. For e.g. when this object is an array of pointers to other objects
+ /// Adds reference to other SafeMemoryHandle objects, the pointer to which are referred to by this object. This is to ensure that
+ /// such objects being referred to wouldn't be unreferenced until this object is active. For e.g. when this object is an array of
+ /// pointers to other objects
///
/// Collection of SafeMemoryHandle objects referred to by this object.
public void AddSubReference(IEnumerable children)
@@ -355,8 +417,9 @@ namespace Vanara.InteropServices
references.AddRange(children);
}
- /// Extracts an array of structures of containing items.
- /// This call can cause memory exceptions if the pointer does not have sufficient allocated memory to retrieve all the structures.
+ ///
+ /// Extracts an array of structures of containing items. This
+ /// call can cause memory exceptions if the pointer does not have sufficient allocated memory to retrieve all the structures.
///
/// The type of the structures to retrieve.
/// The number of structures to retrieve.
@@ -372,8 +435,9 @@ namespace Vanara.InteropServices
return handle.ToArray(count, prefixBytes, sz);
}
- /// Extracts an enumeration of structures of containing items.
- /// This call can cause memory exceptions if the pointer does not have sufficient allocated memory to retrieve all the structures.
+ ///
+ /// Extracts an enumeration of structures of containing items. This call can cause memory exceptions if the pointer does not have sufficient allocated memory to retrieve all the structures.
///
/// The type of the structures to retrieve.
/// The number of structures to retrieve.
@@ -406,7 +470,10 @@ namespace Vanara.InteropServices
return len == -1 ? str : str.Substring(0, len);
}
- /// Returns an enumeration of strings from memory where each string is pointed to by a preceding list of pointers of length .
+ ///
+ /// Returns an enumeration of strings from memory where each string is pointed to by a preceding list of pointers of length
+ /// .
+ ///
/// The count of expected strings.
/// The character set of the strings.
/// Number of bytes preceding the array of string pointers.
@@ -414,15 +481,17 @@ namespace Vanara.InteropServices
public IEnumerable ToStringEnum(int count, CharSet charSet = CharSet.Auto, int prefixBytes = 0) => IsInvalid ? new string[0] : handle.ToStringEnum(count, charSet, prefixBytes, sz);
///
- /// Gets an enumerated list of strings from a block of unmanaged memory where each string is separated by a single '\0' character and is terminated by
- /// two '\0' characters.
+ /// Gets an enumerated list of strings from a block of unmanaged memory where each string is separated by a single '\0' character
+ /// and is terminated by two '\0' characters.
///
/// The character set of the strings.
/// Number of bytes preceding the array of string pointers.
/// An enumerated list of strings.
public IEnumerable ToStringEnum(CharSet charSet = CharSet.Auto, int prefixBytes = 0) => IsInvalid ? new string[0] : handle.ToStringEnum(charSet, prefixBytes, sz);
- /// Marshals data from this block of memory to a newly allocated managed object of the type specified by a generic type parameter.
+ ///
+ /// Marshals data from this block of memory to a newly allocated managed object of the type specified by a generic type parameter.
+ ///
/// The type of the object to which the data is to be copied. This must be a structure.
/// Number of bytes preceding the structure.
/// A managed object that contains the data that this holds.
@@ -432,14 +501,16 @@ namespace Vanara.InteropServices
return handle.ToStructure(sz, prefixBytes);
}
- ///
- /// Marshals data from a managed list of specified type to an offset within this allocated memory.
- ///
- /// A type of the enumerated managed object that holds the data to be marshaled. The object must be a structure or an instance of a
- /// formatted class.
+ /// Marshals data from a managed list of specified type to an offset within this allocated memory.
+ ///
+ /// A type of the enumerated managed object that holds the data to be marshaled. The object must be a structure or an instance of a
+ /// formatted class.
+ ///
/// The enumerated list of items to marshal.
- /// if set to true automatically extend the allocated memory to the size required to hold .
- /// The number of bytes to skip before writing the first element of .
+ ///
+ /// if set to true automatically extend the allocated memory to the size required to hold .
+ ///
+ /// The number of bytes to skip before writing the first element of .
public void Write(IEnumerable items, bool autoExtend = true, int offset = 0)
{
if (IsInvalid) throw new MemberAccessException("Safe memory pointer is not valid.");
@@ -458,7 +529,9 @@ namespace Vanara.InteropServices
/// Writes the specified value to an offset within this allocated memory.
/// The type of the value to write.
/// The value to write.
- /// if set to true automatically extend the allocated memory to the size required to hold .
+ ///
+ /// if set to true automatically extend the allocated memory to the size required to hold .
+ ///
/// The number of bytes to offset from the beginning of this allocated memory before writing.
public void Write(in T value, bool autoExtend = true, int offset = 0) where T : struct
{
@@ -475,7 +548,9 @@ namespace Vanara.InteropServices
/// Writes the specified value to an offset within this allocated memory.
/// The value to write.
- /// if set to true automatically extend the allocated memory to the size required to hold .
+ ///
+ /// if set to true automatically extend the allocated memory to the size required to hold .
+ ///
/// The number of bytes to offset from the beginning of this allocated memory before writing.
public void Write(object value, bool autoExtend = true, int offset = 0)
{
@@ -493,8 +568,8 @@ namespace Vanara.InteropServices
/// When overridden in a derived class, executes the code required to free the handle.
///
- /// true if the handle is released successfully; otherwise, in the event of a catastrophic failure, false. In this case, it generates a
- /// releaseHandleFailed MDA Managed Debugging Assistant.
+ /// true if the handle is released successfully; otherwise, in the event of a catastrophic failure, false. In this case, it
+ /// generates a releaseHandleFailed MDA Managed Debugging Assistant.
///
protected override bool ReleaseHandle()
{