Skip to content

Commit

Permalink
Merge pull request #11 from badcel/ignore-null-termination-for-buffers
Browse files Browse the repository at this point in the history
No automatic null termination in case of buffer scenario
  • Loading branch information
badcel authored Jun 16, 2024
2 parents 15a4eb6 + 47da194 commit 35373d3
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 6 deletions.
13 changes: 10 additions & 3 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,24 @@ To work with WCharT data create a new instance of `WCharTString`:

```csharp
//Read data from a byte*
byte* pointer = NativeCal();
var data = new WCharTString(pointer).GetString();
byte* pointer = NativeCall();
var str = new WCharTString(pointer).GetString();

//Create a buffer for a native library and read the data after it was filled
ReadOnlySpan<byte> data = new WCharTString(int bufferCharSize);
NativeCall(data);
NativeCall(...);
var str = data.GetString();

//Pass a string to a native library
ReadOnlySpan<byte> data = new WCharTString(string str);
NativeCall(data);

//Can be used in fixed statements
var data = new WCharTString(string str);
fixed (byte* ptr = data)
{
NativeCall(ptr);
}
```

## Build
Expand Down
12 changes: 11 additions & 1 deletion src/WCharT.Net.Tests/Tests.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Runtime.InteropServices;
using System.Text;
using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;

Expand All @@ -17,6 +16,17 @@ public void TestEncoding()
str.GetString().Should().Be(text);
}

[TestMethod]
public void BufferSizeIsRetained()
{
var bufferSize = 3;
var str = new WCharTString(bufferSize);

var result = str.GetString();
result.Should().Be(new string(new[] { char.MinValue, char.MinValue, char.MinValue }));
result.Length.Should().Be(bufferSize);
}

[TestMethod]
public void TestUnicode()
{
Expand Down
2 changes: 1 addition & 1 deletion src/WCharT.Net/Platforms/Unix.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ internal static class Unix
public static ReadOnlySpan<byte> CreateData(int chars)
{
var length = chars * sizeof(uint);
var data = new byte[length + sizeof(uint)]; //Null terminated
var data = new byte[length];
return new ReadOnlySpan<byte>(data, 0, length);
}

Expand Down
2 changes: 1 addition & 1 deletion src/WCharT.Net/Platforms/Windows.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ internal static class Windows
public static ReadOnlySpan<byte> CreateData(int chars)
{
var length = chars * sizeof(ushort);
var data = new byte[length + sizeof(ushort)]; //Null terminated
var data = new byte[length];
return new ReadOnlySpan<byte>(data, 0, length);
}

Expand Down
3 changes: 3 additions & 0 deletions src/WCharT.Net/WCharTString.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public unsafe WCharTString(byte* p)
/// Creates an instance from a given string to be able to pass on the data later.
/// </summary>
/// <param name="str">A string which should be encoded into a wchar_t string.</param>
/// <remarks>The internal representation of the string is null terminated. Meaning it is possible to simply pass the pointer of the <see cref="ReadOnlySpan{T}"/> to native code without any length information. At the same time the length parameter of the <see cref="ReadOnlySpan{T}"/> does not include the null termination character. Meaning if an API requires the size of the data in bytes without the null termination character the length value of the <see cref="ReadOnlySpan{T}"/>can be used.</remarks>
public WCharTString(string str)
{
data = Platform.CreateData(str);
Expand All @@ -37,6 +38,7 @@ public WCharTString(string str)
/// Creates an instance for a given amount of wchar_t characters.
/// </summary>
/// <param name="length">The number of wchar_t characters which should be able to put into the instance.</param>
/// <remarks>This does not automatically add a character in case a null termination character is needed.</remarks>
public WCharTString(int length)
{
data = Platform.CreateData(length);
Expand All @@ -46,6 +48,7 @@ public WCharTString(int length)
/// Reads the current data and returns the contained string.
/// </summary>
/// <returns>The decoded wchar_t string from the data.</returns>
/// <remarks>The string has the size of the internal data block which can include null termination characters. If not needed those can be trimmed.</remarks>
public string GetString()
{
return Platform.GetString(data);
Expand Down

0 comments on commit 35373d3

Please sign in to comment.