From affe76ff74740bbd3dd6f14505a523aeb4654031 Mon Sep 17 00:00:00 2001 From: dahall Date: Wed, 20 Jan 2021 16:56:09 -0700 Subject: [PATCH] Added Append overloaded methods to SafeMemStruct to extend memory and write in bytes, memory or objects and return a pointer to the newly written element. Also added GetFieldAddress method to get the location of a field in the structure's memory. --- Core/InteropServices/SafeMemStruct.cs | 39 +++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/Core/InteropServices/SafeMemStruct.cs b/Core/InteropServices/SafeMemStruct.cs index 6d93a83c..50e280f7 100644 --- a/Core/InteropServices/SafeMemStruct.cs +++ b/Core/InteropServices/SafeMemStruct.cs @@ -84,6 +84,40 @@ namespace Vanara.InteropServices /// public static implicit operator TStruct(SafeMemStruct s) => !(s is null) ? s.Value : throw new ArgumentNullException(nameof(s)); + /// Appends the specified bytes to the end of the allocated memory for this structure, expanding the allocation to fit the byte array. + /// The bytes. + /// A pointer to the copied bytes in memory. + public virtual IntPtr Append(byte[] bytes) + { + var sz = Size; + Size += bytes.Length; + Marshal.Copy(bytes, 0, handle.Offset(sz), bytes.Length); + return handle.Offset(sz); + } + + /// Appends the specified memory to the end of the allocated memory for this structure, expanding the allocation to fit the added memory. + /// The memory to append. + /// A pointer to the copied memory. + public virtual IntPtr Append(SafeAllocatedMemoryHandleBase mem) + { + var sz = Size; + Size += mem.Size; + ((IntPtr)mem).CopyTo(handle.Offset(sz), mem.Size); + return handle.Offset(sz); + } + + /// Appends the specified object to the end of the allocated memory for this structure, expanding the allocation to fit the added object. + /// The value to append. + /// A pointer to the copied memory. + public virtual IntPtr Append(object value) + { + var sz = Size; + var vSz = InteropExtensions.SizeOf(value); + Size += vSz; + handle.Write(value, sz, Size); + return handle.Offset(sz); + } + /// Determines whether the specified , is equal to this instance. /// The to compare with this instance. /// true if the specified is equal to this instance; otherwise, false. @@ -102,6 +136,11 @@ namespace Vanara.InteropServices /// true if the current object is equal to the parameter; otherwise, false. public bool Equals(TStruct other) => HasValue && EqualityComparer.Default.Equals(handle.ToStructure(Size), other); + /// Gets the memory address of a field within . + /// Name of the field. + /// The pointer to the field in memory. + public virtual IntPtr GetFieldAddress(string fieldName) => handle.Offset(FieldOffset(fieldName)); + /// Returns a hash code for this instance. /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. public override int GetHashCode() => handle.ToInt32();