using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using Vanara.Extensions;
namespace Vanara.InteropServices
{
/// The StrPtr structure represents a LPTSTR.
[StructLayout(LayoutKind.Sequential), DebuggerDisplay("{ptr}, {ToString()}")]
public struct StrPtrAuto
{
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; }
/// 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 StrPtrAuto { 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.Auto));
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) ?? "null";
}
/// The StrPtr structure represents a LPWSTR.
[StructLayout(LayoutKind.Sequential), DebuggerDisplay("{ptr}, {ToString()}")]
public struct StrPtrUni
{
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; }
/// 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 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 StrPtrUni { 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.Unicode));
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.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
{
///
/// 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;
/// The equivalent of a pointer to a GUID value.
public static readonly SafeGuidPtr Null = new SafeGuidPtr();
}
}