BSTR
using System;
using System.CodeDom.Compiler;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace Windows.Win32.Foundation
{
[DebuggerDisplay("{Value}")]
[GeneratedCode("Microsoft.Windows.CsWin32", "0.3.151+58e949951d.RR")]
internal readonly struct BSTR : IDisposable, IEquatable<BSTR>
{
internal unsafe readonly char* Value;
public unsafe bool IsNull => Value == null;
public bool IsNullOrEmpty => Length == 0;
internal unsafe int Length {
get {
checked {
if (Value != null)
return (int)unchecked(*(uint*)checked(unchecked((ulong)Value) - 4) / 2);
return 0;
}
}
}
[NullableContext(2)]
public unsafe BSTR(string value)
{
this = new BSTR((char*)(long)Marshal.StringToBSTR(value));
}
public unsafe void Dispose()
{
if (Value != null) {
Marshal.FreeBSTR((IntPtr)Value);
Unsafe.AsRef(ref this) = default(BSTR);
}
}
[NullableContext(1)]
public string ToStringAndFree()
{
string result = ToString() ?? string.Empty;
Dispose();
return result;
}
[NullableContext(2)]
public string ToNullableStringAndFree()
{
string result = ToString();
Dispose();
return result;
}
internal unsafe BSTR(char* value)
{
Value = value;
}
internal unsafe BSTR(IntPtr value)
{
this = new BSTR((char*)(long)value);
}
public unsafe static implicit operator char*(BSTR value)
{
return value.Value;
}
public unsafe static explicit operator BSTR(char* value)
{
return new BSTR(value);
}
public unsafe static bool operator ==(BSTR left, BSTR right)
{
return left.Value == right.Value;
}
public static bool operator !=(BSTR left, BSTR right)
{
return !(left == right);
}
public unsafe bool Equals(BSTR other)
{
return Value == other.Value;
}
public override bool Equals(object obj)
{
if (obj is BSTR) {
BSTR other = (BSTR)obj;
return Equals(other);
}
return false;
}
public unsafe override int GetHashCode()
{
return (int)Value;
}
public unsafe override string ToString()
{
if (Value == null)
return null;
return Marshal.PtrToStringBSTR(new IntPtr(Value));
}
public unsafe static implicit operator IntPtr(BSTR value)
{
return new IntPtr(value.Value);
}
public unsafe static explicit operator BSTR(IntPtr value)
{
return new BSTR((char*)value.ToPointer());
}
public unsafe static explicit operator BSTR(UIntPtr value)
{
return new BSTR((char*)value.ToPointer());
}
public unsafe static implicit operator ReadOnlySpan<char>(BSTR bstr)
{
if (bstr.Value == null)
return default(ReadOnlySpan<char>);
return new ReadOnlySpan<char>(bstr.Value, *(int*)(bstr.Value - 2) / 2);
}
internal ReadOnlySpan<char> AsSpan()
{
return this;
}
}
}