From 231ea34f1771307306b5c91cf6029bab88ddc763 Mon Sep 17 00:00:00 2001 From: dahall Date: Tue, 21 Sep 2021 16:11:45 -0600 Subject: [PATCH] Added IsNullOrEmpty property to StrPtrXX structures. --- Core/InteropServices/StrPtr.cs | 370 ++++++++++++++++++++--------------------- 1 file changed, 178 insertions(+), 192 deletions(-) diff --git a/Core/InteropServices/StrPtr.cs b/Core/InteropServices/StrPtr.cs index 5da75913..698267eb 100644 --- a/Core/InteropServices/StrPtr.cs +++ b/Core/InteropServices/StrPtr.cs @@ -5,6 +5,145 @@ using Vanara.Extensions; namespace Vanara.InteropServices { + /// The GuidPtr structure represents a LPGUID. + [StructLayout(LayoutKind.Sequential), DebuggerDisplay("{ptr}, {ToString()}")] + public struct GuidPtr + { + private IntPtr ptr; + + /// Initializes a new instance of the struct by allocating memory with . + /// The guid value. + public GuidPtr(Guid g) => ptr = g.MarshalToPtr(Marshal.AllocCoTaskMem, out _); + + /// Gets a value indicating whether this instance is equivalent to null pointer or void*. + /// true if this instance is null; otherwise, false. + public bool IsNull => ptr == IntPtr.Zero; + + /// Gets the value of the Guid. + /// The value pointed to by this pointer. + public Guid? Value => IsNull ? null : ptr.ToStructure(); + + /// Assigns a new Guid value to the pointer. + /// The guid value. + public void Assign(Guid g) + { + if (IsNull) + ptr = g.MarshalToPtr(Marshal.AllocCoTaskMem, out _); + else + Marshal.StructureToPtr(g, ptr, true); + } + + /// Frees the unmanaged memory. + public void Free() { Marshal.FreeCoTaskMem(ptr); ptr = IntPtr.Zero; } + + /// Performs an implicit conversion from to . + /// The pointer to a Guid. + /// The result of the conversion. + public static implicit operator Guid?(GuidPtr g) => g.Value; + + /// Performs an explicit conversion from to . + /// The pointer to a Guid. + /// The result of the conversion. + public static explicit operator IntPtr(GuidPtr g) => g.ptr; + + /// Performs an implicit conversion from to . + /// The pointer. + /// The result of the conversion. + public static implicit operator GuidPtr(IntPtr p) => new() { ptr = p }; + + /// 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. + public override bool Equals(object obj) => obj switch + { + Guid g => !IsNull && g.Equals(Value.Value), + IntPtr p => ptr.Equals(p), + _ => base.Equals(obj), + }; + + /// 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() => ptr.GetHashCode(); + + /// + public override string ToString() => Value?.ToString("B") ?? ""; + } + + /// The StrPtr structure represents a LPWSTR. + [StructLayout(LayoutKind.Sequential), DebuggerDisplay("{ptr}, {ToString()}")] + public struct StrPtrAnsi + { + private IntPtr ptr; + + /// Initializes a new instance of the struct. + /// The string value. + public StrPtrAnsi(string s) => ptr = StringHelper.AllocString(s, CharSet.Ansi); + + /// Initializes a new instance of the struct. + /// Number of characters to reserve in memory. + public StrPtrAnsi(uint charLen) => ptr = StringHelper.AllocChars(charLen, CharSet.Ansi); + + /// Gets a value indicating whether this instance is equivalent to null pointer or void*. + /// true if this instance is null; otherwise, false. + public bool IsNull => ptr == IntPtr.Zero; + + /// Indicates whether the specified string is or an empty string (""). + /// + /// if the value parameter is or an empty string (""); otherwise, . + /// + public bool IsNullOrEmpty => ptr == IntPtr.Zero || Marshal.ReadByte(ptr) == 0; + + /// Assigns a new string value to the pointer. + /// The string value. + public void Assign(string s) => StringHelper.RefreshString(ref ptr, out var _, s, CharSet.Ansi); + + /// Assigns a new string value to the pointer. + /// The string value. + /// The character count allocated. + /// true if new memory was allocated for the string; false if otherwise. + public bool Assign(string s, out uint charsAllocated) => StringHelper.RefreshString(ref ptr, out charsAllocated, s, CharSet.Ansi); + + /// Assigns an integer to the pointer for uses such as LPSTR_TEXTCALLBACK. + /// The value to assign. + public void AssignConstant(int value) { Free(); ptr = (IntPtr)value; } + + /// Frees the unmanaged string memory. + public void Free() { StringHelper.FreeString(ptr, CharSet.Ansi); ptr = IntPtr.Zero; } + + /// Performs an implicit conversion from to . + /// The instance. + /// The result of the conversion. + public static implicit operator string(StrPtrAnsi p) => p.IsNull ? null : p.ToString(); + + /// Performs an explicit conversion from to . + /// The instance. + /// The result of the conversion. + public static explicit operator IntPtr(StrPtrAnsi p) => p.ptr; + + /// Performs an implicit conversion from to . + /// The pointer. + /// The result of the conversion. + public static implicit operator StrPtrAnsi(IntPtr p) => new() { ptr = p }; + + /// 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. + public override bool Equals(object obj) => obj switch + { + string s => s.Equals(StringHelper.GetString(ptr, CharSet.Ansi)), + IntPtr p => ptr.Equals(p), + _ => base.Equals(obj), + }; + + /// 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() => ptr.GetHashCode(); + + /// Returns a that represents this instance. + /// A that represents this instance. + public override string ToString() => StringHelper.GetString(ptr, CharSet.Ansi) ?? "null"; + } + /// The StrPtr structure represents a LPTSTR. [StructLayout(LayoutKind.Sequential), DebuggerDisplay("{ptr}, {ToString()}")] public struct StrPtrAuto @@ -44,7 +183,13 @@ namespace Vanara.InteropServices /// Frees the unmanaged string memory. public void Free() { StringHelper.FreeString(ptr); ptr = IntPtr.Zero; } - /// Performs an implicit conversion from to . + /// Indicates whether the specified string is or an empty string (""). + /// + /// if the value parameter is or an empty string (""); otherwise, . + /// + public bool IsNullOrEmpty => ptr == IntPtr.Zero || StringHelper.GetString(ptr, CharSet.Auto, 1) == string.Empty; + + /// Performs an implicit conversion from to . /// The instance. /// The result of the conversion. public static implicit operator string(StrPtrAuto p) => p.IsNull ? null : p.ToString(); @@ -57,30 +202,24 @@ namespace Vanara.InteropServices /// Performs an implicit conversion from to . /// The pointer. /// The result of the conversion. - public static implicit operator StrPtrAuto(IntPtr p) => new StrPtrAuto { ptr = p }; + public static implicit operator StrPtrAuto(IntPtr p) => new() { ptr = p }; - /// 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. - public override bool Equals(object obj) + /// 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. + public override bool Equals(object obj) => obj switch { - switch (obj) - { - case string s: - return s.Equals(StringHelper.GetString(ptr, CharSet.Auto)); - case IntPtr p: - return ptr.Equals(p); - default: - return base.Equals(obj); - } - } + string s => s.Equals(StringHelper.GetString(ptr, CharSet.Auto)), + IntPtr p => ptr.Equals(p), + _ => base.Equals(obj), + }; /// 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() => ptr.GetHashCode(); - /// Returns a that represents this instance. - /// A that represents this instance. + /// Returns a that represents this instance. + /// A that represents this instance. public override string ToString() => StringHelper.GetString(ptr) ?? "null"; } @@ -119,7 +258,13 @@ namespace Vanara.InteropServices /// Frees the unmanaged string memory. public void Free() { StringHelper.FreeString(ptr, CharSet.Unicode); ptr = IntPtr.Zero; } - /// Performs an implicit conversion from to . + /// Indicates whether the specified string is or an empty string (""). + /// + /// if the value parameter is or an empty string (""); otherwise, . + /// + public bool IsNullOrEmpty => ptr == IntPtr.Zero || Marshal.ReadInt16(ptr) == 0; + + /// Performs an implicit conversion from to . /// The instance. /// The result of the conversion. public static implicit operator string(StrPtrUni p) => p.IsNull ? null : p.ToString(); @@ -132,192 +277,36 @@ namespace Vanara.InteropServices /// Performs an implicit conversion from to . /// The pointer. /// The result of the conversion. - public static implicit operator StrPtrUni(IntPtr p) => new StrPtrUni { ptr = p }; + public static implicit operator StrPtrUni(IntPtr p) => new() { ptr = p }; - /// 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. - public override bool Equals(object obj) + /// 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. + public override bool Equals(object obj) => obj switch { - switch (obj) - { - case string s: - return s.Equals(StringHelper.GetString(ptr, CharSet.Unicode)); - case IntPtr p: - return ptr.Equals(p); - default: - return base.Equals(obj); - } - } + string s => s.Equals(StringHelper.GetString(ptr, CharSet.Unicode)), + IntPtr p => ptr.Equals(p), + _ => base.Equals(obj), + }; /// 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() => ptr.GetHashCode(); - /// Returns a that represents this instance. - /// A that represents this instance. + /// Returns a that represents this instance. + /// A that represents this instance. public override string ToString() => StringHelper.GetString(ptr, CharSet.Unicode) ?? "null"; } - /// The StrPtr structure represents a LPWSTR. - [StructLayout(LayoutKind.Sequential), DebuggerDisplay("{ptr}, {ToString()}")] - public struct StrPtrAnsi - { - private IntPtr ptr; - - /// Initializes a new instance of the struct. - /// The string value. - public StrPtrAnsi(string s) => ptr = StringHelper.AllocString(s, CharSet.Ansi); - - /// Initializes a new instance of the struct. - /// Number of characters to reserve in memory. - public StrPtrAnsi(uint charLen) => ptr = StringHelper.AllocChars(charLen, CharSet.Ansi); - - /// Gets a value indicating whether this instance is equivalent to null pointer or void*. - /// true if this instance is null; otherwise, false. - public bool IsNull => ptr == IntPtr.Zero; - - /// Assigns a new string value to the pointer. - /// The string value. - public void Assign(string s) => StringHelper.RefreshString(ref ptr, out var _, s, CharSet.Ansi); - - /// Assigns a new string value to the pointer. - /// The string value. - /// The character count allocated. - /// true if new memory was allocated for the string; false if otherwise. - public bool Assign(string s, out uint charsAllocated) => StringHelper.RefreshString(ref ptr, out charsAllocated, s, CharSet.Ansi); - - /// Assigns an integer to the pointer for uses such as LPSTR_TEXTCALLBACK. - /// The value to assign. - public void AssignConstant(int value) { Free(); ptr = (IntPtr)value; } - - /// Frees the unmanaged string memory. - public void Free() { StringHelper.FreeString(ptr, CharSet.Ansi); ptr = IntPtr.Zero; } - - /// Performs an implicit conversion from to . - /// The instance. - /// The result of the conversion. - public static implicit operator string(StrPtrAnsi p) => p.IsNull ? null : p.ToString(); - - /// Performs an explicit conversion from to . - /// The instance. - /// The result of the conversion. - public static explicit operator IntPtr(StrPtrAnsi p) => p.ptr; - - /// Performs an implicit conversion from to . - /// The pointer. - /// The result of the conversion. - public static implicit operator StrPtrAnsi(IntPtr p) => new StrPtrAnsi { ptr = p }; - - /// 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. - public override bool Equals(object obj) - { - switch (obj) - { - case string s: - return s.Equals(StringHelper.GetString(ptr, CharSet.Ansi)); - case IntPtr p: - return ptr.Equals(p); - default: - return base.Equals(obj); - } - } - - /// 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() => ptr.GetHashCode(); - - /// Returns a that represents this instance. - /// A that represents this instance. - public override string ToString() => StringHelper.GetString(ptr, CharSet.Ansi) ?? "null"; - } - - /// The GuidPtr structure represents a LPGUID. - [StructLayout(LayoutKind.Sequential), DebuggerDisplay("{ptr}, {ToString()}")] - public struct GuidPtr - { - private IntPtr ptr; - - /// Initializes a new instance of the struct by allocating memory with . - /// The guid value. - public GuidPtr(Guid g) => ptr = g.MarshalToPtr(Marshal.AllocCoTaskMem, out _); - - /// Gets a value indicating whether this instance is equivalent to null pointer or void*. - /// true if this instance is null; otherwise, false. - public bool IsNull => ptr == IntPtr.Zero; - - /// Gets the value of the Guid. - /// The value pointed to by this pointer. - public Guid? Value => IsNull ? (Guid?)null : ptr.ToStructure(); - - /// Assigns a new Guid value to the pointer. - /// The guid value. - public void Assign(Guid g) - { - if (IsNull) - ptr = g.MarshalToPtr(Marshal.AllocCoTaskMem, out _); - else - Marshal.StructureToPtr(g, ptr, true); - } - - /// Frees the unmanaged memory. - public void Free() { Marshal.FreeCoTaskMem(ptr); ptr = IntPtr.Zero; } - - /// - /// Performs an implicit conversion from to . - /// - /// The pointer to a Guid. - /// - /// The result of the conversion. - /// - public static implicit operator Guid?(GuidPtr g) => g.Value; - - /// - /// Performs an explicit conversion from to . - /// - /// The pointer to a Guid. - /// - /// The result of the conversion. - /// - public static explicit operator IntPtr(GuidPtr g) => g.ptr; - - /// Performs an implicit conversion from to . - /// The pointer. - /// The result of the conversion. - public static implicit operator GuidPtr(IntPtr p) => new GuidPtr { ptr = p }; - - /// 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. - public override bool Equals(object obj) - { - switch (obj) - { - case Guid g: - return IsNull ? false : g.Equals(Value.Value); - case IntPtr p: - return ptr.Equals(p); - default: - return base.Equals(obj); - } - } - - /// 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() => ptr.GetHashCode(); - - /// - public override string ToString() => Value?.ToString("B") ?? ""; - } - /// /// Represents a GUID point, or REFGUID, that will automatically dispose the memory to which it points at the end of scope. /// You must use the value, or the parameter-less constructor to pass the equivalent of . /// public class SafeGuidPtr : SafeMemStruct { + /// The equivalent of a pointer to a GUID value. + public static readonly SafeGuidPtr Null = new(); + /// /// Initializes a new instance of the class. This value is equivalent to a pointer. /// @@ -331,8 +320,5 @@ namespace Vanara.InteropServices /// The unique identifier. /// The resulting instance from the conversion. public static implicit operator SafeGuidPtr(Guid? guid) => guid.HasValue ? new SafeGuidPtr(guid.Value) : Null; - - /// The equivalent of a pointer to a GUID value. - public static readonly SafeGuidPtr Null = new SafeGuidPtr(); } } \ No newline at end of file