From 83b3dfb9420f748125205de355c86a87e2f7c3ec Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Thu, 13 Oct 2022 06:28:00 -0600 Subject: [PATCH] Add `BSTR.Length` property Closes #717 --- src/Microsoft.Windows.CsWin32/Generator.cs | 1 + .../templates/BSTR.cs | 7 ++++++ test/GenerationSandbox.Tests/BasicTests.cs | 23 +++++++++++++++++++ 3 files changed, 31 insertions(+) create mode 100644 src/Microsoft.Windows.CsWin32/templates/BSTR.cs diff --git a/src/Microsoft.Windows.CsWin32/Generator.cs b/src/Microsoft.Windows.CsWin32/Generator.cs index 5f62fafb..69de9f5f 100644 --- a/src/Microsoft.Windows.CsWin32/Generator.cs +++ b/src/Microsoft.Windows.CsWin32/Generator.cs @@ -4157,6 +4157,7 @@ private StructDeclarationSyntax DeclareTypeDefStruct(TypeDefinition typeDef, Typ { case "BSTR": members = members.AddRange(this.CreateAdditionalTypeDefBSTRMembers()); + members = members.AddRange(this.ExtractMembersFromTemplate(name.Identifier.ValueText)); break; case "PWSTR": members = members.AddRange(this.CreateAdditionalTypeDefPWSTRMembers()); diff --git a/src/Microsoft.Windows.CsWin32/templates/BSTR.cs b/src/Microsoft.Windows.CsWin32/templates/BSTR.cs new file mode 100644 index 00000000..e65b0ea8 --- /dev/null +++ b/src/Microsoft.Windows.CsWin32/templates/BSTR.cs @@ -0,0 +1,7 @@ +internal partial struct BSTR +{ + /// + /// Gets the length of the BSTR in characters. + /// + internal unsafe int Length => this.Value is null ? 0 : checked((int)(*(((uint*)this.Value) - 1) / sizeof(char))); +} diff --git a/test/GenerationSandbox.Tests/BasicTests.cs b/test/GenerationSandbox.Tests/BasicTests.cs index 906d8691..1855f2a9 100644 --- a/test/GenerationSandbox.Tests/BasicTests.cs +++ b/test/GenerationSandbox.Tests/BasicTests.cs @@ -80,6 +80,29 @@ public void BSTR_ToString_Null() Assert.Null(bstr.ToString()); } + [Theory] + [InlineData("")] + [InlineData("h")] + [InlineData("hello")] + public void BSTR_Length(string value) + { + BSTR bstr = (BSTR)Marshal.StringToBSTR(value); + try + { + Assert.Equal(value.Length, bstr.Length); + } + finally + { + Marshal.FreeBSTR(bstr); + } + } + + [Fact] + public void BSTR_Length_Null() + { + Assert.Equal(0, default(BSTR).Length); + } + [Fact] public unsafe void BSTR_ImplicitConversionTo_ReadOnlySpan() {