using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using Vanara.Extensions;
namespace Vanara.InteropServices
{
/// The GuidPtr structure represents a LPGUID.
[StructLayout(LayoutKind.Sequential), DebuggerDisplay("{ptr}, {ToString()}")]
public struct GuidPtr : IEquatable, IEquatable, IEquatable
{
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);
}
/// 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 bool Equals(Guid? other) => EqualityComparer.Default.Equals(Value, other);
/// 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 bool Equals(GuidPtr other) => Equals(other.ptr);
/// 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 bool Equals(IntPtr other) => EqualityComparer.Default.Equals(ptr, other);
///
public override bool Equals(object obj) => obj switch
{
null => IsNull,
IntPtr p => Equals(p),
GuidPtr gp => Equals(gp),
Guid g => Equals(g),
_ => base.Equals(obj),
};
/// Frees the unmanaged memory.
public void Free() { Marshal.FreeCoTaskMem(ptr); ptr = IntPtr.Zero; }
///
public override int GetHashCode() => ptr.GetHashCode();
///
public override string ToString() => Value?.ToString("B") ?? "";
/// 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 two specified instances of are equal.
/// The first pointer or handle to compare.
/// The second pointer or handle to compare.
/// if equals ; otherwise, .
public static bool operator ==(GuidPtr left, GuidPtr right) => left.Equals(right);
/// Determines whether two specified instances of are not equal.
/// The first pointer or handle to compare.
/// The second pointer or handle to compare.
/// if does not equal ; otherwise, .
public static bool operator !=(GuidPtr left, GuidPtr right) => !left.Equals(right);
}
/// The StrPtr structure represents a LPWSTR.
[StructLayout(LayoutKind.Sequential), DebuggerDisplay("{ptr}, {ToString()}")]
public struct StrPtrAnsi : IEquatable, IEquatable, IEquatable
{
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; }
/// 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 bool Equals(IntPtr other) => EqualityComparer.Default.Equals(ptr, other);
/// 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 bool Equals(string other) => EqualityComparer.Default.Equals(this, other);
/// 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 bool Equals(StrPtrAnsi other) => Equals(other.ptr);
/// 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
{
null => IsNull,
string s => Equals(s),
StrPtrAnsi p => Equals(p),
IntPtr p => Equals(p),
_ => base.Equals(obj),
};
/// Frees the unmanaged string memory.
public void Free() { StringHelper.FreeString(ptr, CharSet.Ansi); ptr = IntPtr.Zero; }
/// 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";
/// 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 * reference.
/// The resulting * from the conversion.
public static unsafe explicit operator sbyte*(StrPtrAnsi p) => (sbyte*)p.ptr;
/// 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 two specified instances of are equal.
/// The first pointer or handle to compare.
/// The second pointer or handle to compare.
/// if equals ; otherwise, .
public static bool operator ==(StrPtrAnsi left, StrPtrAnsi right) => left.Equals(right);
/// Determines whether two specified instances of are not equal.
/// The first pointer or handle to compare.
/// The second pointer or handle to compare.
/// if does not equal ; otherwise, .
public static bool operator !=(StrPtrAnsi left, StrPtrAnsi right) => !left.Equals(right);
}
/// The StrPtr structure represents a LPTSTR.
[StructLayout(LayoutKind.Sequential), DebuggerDisplay("{ptr}, {ToString()}")]
public struct StrPtrAuto : IEquatable, IEquatable, IEquatable
{
private IntPtr ptr;
/// Initializes a new instance of the struct.
/// The string value.
public StrPtrAuto(string s) => ptr = StringHelper.AllocString(s);
/// Initializes a new instance of the struct.
/// Number of characters to reserve in memory.
public StrPtrAuto(uint charLen) => ptr = StringHelper.AllocChars(charLen);
/// 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 string pointer value to the pointer.
/// The string pointer value.
public void Assign(IntPtr stringPtr) { Free(); ptr = stringPtr; }
/// Assigns a new string value to the pointer.
/// The string value.
public void Assign(string s) => StringHelper.RefreshString(ref ptr, out var _, s);
/// 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);
/// 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); 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 || 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();
/// Performs an explicit conversion from to .
/// The instance.
/// The result of the conversion.
public static explicit operator IntPtr(StrPtrAuto p) => p.ptr;
/// Performs an implicit conversion from to .
/// The pointer.
/// The result of the conversion.
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 bool Equals(IntPtr other) => EqualityComparer.Default.Equals(ptr, other);
/// 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 bool Equals(string other) => EqualityComparer.Default.Equals(this, other);
/// 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 bool Equals(StrPtrAuto other) => Equals(other.ptr);
/// 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
{
null => IsNull,
string s => Equals(s),
StrPtrAuto p => Equals(p),
IntPtr p => 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) ?? "null";
/// Determines whether two specified instances of are equal.
/// The first pointer or handle to compare.
/// The second pointer or handle to compare.
/// if equals ; otherwise, .
public static bool operator ==(StrPtrAuto left, StrPtrAuto right) => left.Equals(right);
/// Determines whether two specified instances of are not equal.
/// The first pointer or handle to compare.
/// The second pointer or handle to compare.
/// if does not equal ; otherwise, .
public static bool operator !=(StrPtrAuto left, StrPtrAuto right) => !left.Equals(right);
}
/// The StrPtr structure represents a LPWSTR.
[StructLayout(LayoutKind.Sequential), DebuggerDisplay("{ptr}, {ToString()}")]
public struct StrPtrUni : IEquatable, IEquatable, IEquatable
{
private IntPtr ptr;
/// Initializes a new instance of the struct.
/// The string value.
public StrPtrUni(string s) => ptr = StringHelper.AllocString(s, CharSet.Unicode);
/// Initializes a new instance of the struct.
/// Number of characters to reserve in memory.
public StrPtrUni(uint charLen) => ptr = StringHelper.AllocChars(charLen, CharSet.Unicode);
/// 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.Unicode);
/// 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.Unicode);
/// 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.Unicode); 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.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();
/// Performs an explicit conversion from to *.
/// The * reference.
/// The resulting * from the conversion.
public static unsafe explicit operator char*(StrPtrUni p) => (char*)p.ptr;
/// Performs an explicit conversion from to .
/// The instance.
/// The result of the conversion.
public static explicit operator IntPtr(StrPtrUni p) => p.ptr;
/// Performs an implicit conversion from to .
/// The pointer.
/// The result of the conversion.
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 bool Equals(IntPtr other) => EqualityComparer.Default.Equals(ptr, other);
/// 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 bool Equals(string other) => EqualityComparer.Default.Equals(this, other);
/// 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 bool Equals(StrPtrUni other) => Equals(other.ptr);
/// 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
{
null => IsNull,
string s => Equals(s),
StrPtrUni p => Equals(p),
IntPtr p => 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.Unicode) ?? "null";
/// Determines whether two specified instances of are equal.
/// The first pointer or handle to compare.
/// The second pointer or handle to compare.
/// if equals ; otherwise, .
public static bool operator ==(StrPtrUni left, StrPtrUni right) => left.Equals(right);
/// Determines whether two specified instances of are not equal.
/// The first pointer or handle to compare.
/// The second pointer or handle to compare.
/// if does not equal ; otherwise, .
public static bool operator !=(StrPtrUni left, StrPtrUni right) => !left.Equals(right);
}
///
/// 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.
///
public SafeGuidPtr() : base(IntPtr.Zero, true, 0) { }
/// Initializes a new instance of the class.
/// The unique identifier to assign to the pointer.
public SafeGuidPtr(in Guid guid) : base(guid) { }
/// Performs an implicit conversion from to .
/// The unique identifier.
/// The resulting instance from the conversion.
public static implicit operator SafeGuidPtr(Guid? guid) => guid.HasValue ? new SafeGuidPtr(guid.Value) : Null;
}
}