Skip to content

Commit

Permalink
String marshalling
Browse files Browse the repository at this point in the history
  • Loading branch information
mgnsm committed Apr 17, 2023
1 parent 47c92fb commit d1b2255
Show file tree
Hide file tree
Showing 5 changed files with 9 additions and 32 deletions.
4 changes: 2 additions & 2 deletions Source/Millistream.Streaming/Interop/NativeImplementation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ unsafe internal sealed class NativeImplementation
internal readonly delegate* unmanaged[Cdecl]<IntPtr, MDF_OPTION, IntPtr, int> mdf_set_property;
internal readonly delegate* unmanaged[Cdecl]<IntPtr, byte> mdf_get_delay;
internal readonly delegate* unmanaged[Cdecl]<IntPtr, ulong> mdf_get_mclass;
internal readonly delegate* unmanaged[Cdecl]<IntPtr, IntPtr, int> mdf_connect;
internal readonly delegate* unmanaged[Cdecl]<IntPtr, string, int> mdf_connect;
internal readonly delegate* unmanaged[Cdecl]<IntPtr, void> mdf_disconnect;
internal readonly delegate* unmanaged[Cdecl]<IntPtr> mdf_message_create;
internal readonly delegate* unmanaged[Cdecl]<IntPtr, void> mdf_message_destroy;
Expand Down Expand Up @@ -98,7 +98,7 @@ internal NativeImplementation(string libraryPath)
mdf_get_ulong_property = (delegate* unmanaged[Cdecl]<IntPtr, MDF_OPTION, ref ulong, int>)nativeLibrary.GetExport(lib, nameof(mdf_get_property));
mdf_get_long_property = (delegate* unmanaged[Cdecl]<IntPtr, MDF_OPTION, ref long, int>)nativeLibrary.GetExport(lib, nameof(mdf_get_property));
mdf_set_property = (delegate* unmanaged[Cdecl]<IntPtr, MDF_OPTION, IntPtr, int>)nativeLibrary.GetExport(lib, nameof(mdf_set_property));
mdf_connect = (delegate* unmanaged[Cdecl]<IntPtr, IntPtr, int>)nativeLibrary.GetExport(lib, nameof(mdf_connect));
mdf_connect = (delegate* unmanaged[Cdecl]<IntPtr, string, int>)nativeLibrary.GetExport(lib, nameof(mdf_connect));
mdf_disconnect = (delegate* unmanaged[Cdecl]<IntPtr, void>)nativeLibrary.GetExport(lib, nameof(mdf_disconnect));
mdf_message_create = (delegate* unmanaged[Cdecl]<IntPtr>)nativeLibrary.GetExport(lib, nameof(mdf_message_create));
mdf_message_destroy = (delegate* unmanaged[Cdecl]<IntPtr, void>)nativeLibrary.GetExport(lib, nameof(mdf_message_destroy));
Expand Down
28 changes: 3 additions & 25 deletions Source/Millistream.Streaming/MarketDataFeed.cs
Original file line number Diff line number Diff line change
Expand Up @@ -485,31 +485,9 @@ public bool GetNextField(out Field field, out ReadOnlySpan<byte> value)
/// <param name="servers">A comma separated list of 'host:port' pairs, where 'host' can be a DNS host name or an ip address (IPv6 addressed must be enclosed in brackets).</param>
/// <returns><see langword="true" /> if a connection has been set up or <see langword="false" /> if a connection attempt failed with every server on the list.</returns>
/// <remarks>The corresponding native function is mdf_connect.</remarks>
public bool Connect(string servers)
{
if (string.IsNullOrEmpty(servers))
return false;

int length = Encoding.UTF8.GetMaxByteCount(servers.Length);
byte[] bytes = ArrayPool<byte>.Shared.Rent(length + 1);
try
{
unsafe
{
fixed (char* c = servers)
fixed (byte* b = bytes)
{
int bytesWritten = Encoding.UTF8.GetBytes(c, servers.Length, b, length);
b[bytesWritten] = 0;
return _nativeImplementation.mdf_connect(_feedHandle, (IntPtr)b) == 1;
}
}
}
finally
{
ArrayPool<byte>.Shared.Return(bytes);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Connect(string servers) => !string.IsNullOrEmpty(servers)
&& _nativeImplementation.mdf_connect(_feedHandle, servers) == 1;

/// <summary>
/// Disconnect a connected API handle. Safe to call even if the handle is already disconnected.
Expand Down
3 changes: 1 addition & 2 deletions Tests/Millistream.Streaming.UnitTests/MarketDataFeedTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -629,9 +629,8 @@ public void ConnectTest()
IntPtr feedHandle = new(123);
const string Servers = "host.server.com:9100";
nativeImplementation.Setup(x => x.mdf_create()).Returns(feedHandle);
Expression<Func<INativeImplementation, int>> expression = x => x.mdf_connect(feedHandle, It.IsAny<IntPtr>());
Expression<Func<INativeImplementation, int>> expression = x => x.mdf_connect(feedHandle, Servers);
nativeImplementation.Setup(expression)
.Callback((IntPtr handle, IntPtr server) => Compare(Servers, server))
.Returns(1);
NativeImplementation.Implementation = nativeImplementation.Object;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public interface INativeImplementation
int mdf_set_property(IntPtr handle, int option, IntPtr value);
byte mdf_get_delay(IntPtr handle);
ulong mdf_get_mclass(IntPtr handle);
int mdf_connect(IntPtr handle, IntPtr server);
int mdf_connect(IntPtr handle, string server);
void mdf_disconnect(IntPtr handle);
IntPtr mdf_message_create();
void mdf_message_destroy(IntPtr message);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ internal unsafe class NativeImplementation
internal delegate*<IntPtr, MDF_OPTION, IntPtr, int> mdf_set_property;
internal delegate*<IntPtr, byte> mdf_get_delay;
internal delegate*<IntPtr, ulong> mdf_get_mclass;
internal delegate*<IntPtr, IntPtr, int> mdf_connect;
internal delegate*<IntPtr, string, int> mdf_connect;
internal delegate*<IntPtr, void> mdf_disconnect;
internal delegate*<IntPtr> mdf_message_create;
internal delegate*<IntPtr, void> mdf_message_destroy;
Expand Down Expand Up @@ -122,7 +122,7 @@ internal NativeImplementation(string _)
private static int MdfSetProperty(IntPtr handle, MDF_OPTION option, IntPtr value) => Implementation.mdf_set_property(handle, (int)option, value);
private static byte MdfGetDelay(IntPtr handle) => Implementation.mdf_get_delay(handle);
private static ulong MdfGetMClass(IntPtr handle) => Implementation.mdf_get_mclass(handle);
private static int MdfConnect(IntPtr handle, IntPtr server) => Implementation.mdf_connect(handle, server);
private static int MdfConnect(IntPtr handle, string server) => Implementation.mdf_connect(handle, server);
private static void MdfDisconnect(IntPtr handle) => Implementation.mdf_disconnect(handle);
private static IntPtr MdfMessageCreate() => Implementation.mdf_message_create();
private static void MdfMessageDestroy(IntPtr message) => Implementation.mdf_message_destroy(message);
Expand Down

0 comments on commit d1b2255

Please sign in to comment.