Skip to content

Commit

Permalink
Added a Delay property.
Browse files Browse the repository at this point in the history
  • Loading branch information
mgnsm committed May 10, 2022
1 parent 6894e25 commit 0b6de2d
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 37 deletions.
5 changes: 4 additions & 1 deletion Source/Millistream.Streaming/Interop/NativeImplementation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ unsafe internal sealed class NativeImplementation
internal readonly delegate* unmanaged[Cdecl]<IntPtr, MDF_OPTION, ref ulong, int> mdf_get_ulong_property;
internal readonly delegate* unmanaged[Cdecl]<IntPtr, MDF_OPTION, ref long, int> mdf_get_long_property;
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, IntPtr, int> mdf_connect;
internal readonly delegate* unmanaged[Cdecl]<IntPtr, void> mdf_disconnect;
internal readonly delegate* unmanaged[Cdecl]<IntPtr> mdf_message_create;
Expand Down Expand Up @@ -93,7 +94,9 @@ internal NativeImplementation(string libraryPath)
mdf_message_get_num = (delegate* unmanaged[Cdecl]<IntPtr, int>)nativeLibrary.GetExport(lib, nameof(mdf_message_get_num));
mdf_message_get_num_active = (delegate* unmanaged[Cdecl]<IntPtr, int>)nativeLibrary.GetExport(lib, nameof(mdf_message_get_num_active));

if (nativeLibrary.TryGetExport(lib, nameof(mdf_message_add_int), out IntPtr address))
if (nativeLibrary.TryGetExport(lib, nameof(mdf_get_delay), out IntPtr address))
mdf_get_delay = (delegate* unmanaged[Cdecl]<IntPtr, byte>)address;
if (nativeLibrary.TryGetExport(lib, nameof(mdf_message_add_int), out address))
mdf_message_add_int = (delegate* unmanaged[Cdecl]<IntPtr, uint, long, int, int>)address;
if (nativeLibrary.TryGetExport(lib, nameof(mdf_message_add_uint), out address))
mdf_message_add_uint = (delegate* unmanaged[Cdecl]<IntPtr, uint, ulong, int, int>)address;
Expand Down
67 changes: 43 additions & 24 deletions Source/Millistream.Streaming/MarketDataFeed.cs

Large diffs are not rendered by default.

22 changes: 11 additions & 11 deletions Source/Millistream.Streaming/Message.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ private Message(string nativeLibraryPath, bool validateArgument)
~Message() => Dispose();

/// <summary>
/// The zlib compression level used for the <see cref="AddString(uint, string)"/> and <see cref="AddString(uint, string, int)"/> methods.
/// Gets or sets the zlib compression level used for the <see cref="AddString(uint, string)"/> and <see cref="AddString(uint, string, int)"/> methods.
/// </summary>
/// <exception cref="InvalidOperationException">The installed version of the native library doesn't support setting the zlib compression level.</exception>
/// <exception cref="InvalidOperationException">The installed version of the native library doesn't include the mdf_message_set_property function.</exception>
Expand All @@ -73,7 +73,7 @@ public CompressionLevel CompressionLevel
}

/// <summary>
/// The total number of messages in the message handle (the number of active + the number of reused messages currently not used for active messages).
/// Gets the total number of messages in the message handle (the number of active + the number of reused messages currently not used for active messages).
/// </summary>
/// <exception cref="ObjectDisposedException">The <see cref="Message"/> instance has been disposed.</exception>
public int Count
Expand All @@ -86,7 +86,7 @@ public int Count
}

/// <summary>
/// The number of active messages in the message handle.
/// Gets the number of active messages in the message handle.
/// </summary>
/// <exception cref="ObjectDisposedException">The <see cref="Message"/> instance has been disposed.</exception>
public int ActiveCount
Expand All @@ -99,7 +99,7 @@ public int ActiveCount
}

/// <summary>
/// The number of added fields to the current message.
/// Gets the number of added fields to the current message.
/// </summary>
/// <exception cref="InvalidOperationException">The installed version of the native library doesn't include the mdf_message_get_num_fields function.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="Message"/> instance has been disposed.</exception>
Expand Down Expand Up @@ -650,19 +650,19 @@ public void Dispose()
}
}

private void ThrowIfDisposed()
{
if (_isDisposed)
throw new ObjectDisposedException(typeof(Message).FullName);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static unsafe void ThrowIfNativeFunctionIsMissing(void* function, string name)
internal static unsafe void ThrowIfNativeFunctionIsMissing(void* function, string name)
{
if (function == default)
throw new InvalidOperationException($"The installed version of the native library doesn't include the {name} function.");
}

private void ThrowIfDisposed()
{
if (_isDisposed)
throw new ObjectDisposedException(typeof(Message).FullName);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool TryGetAsciiBytes(string value, byte* bytes)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ public void GetAndSetPropertiesTest()
mdf.HandleDelay = true;
//Assert.IsTrue(mdf.HandleDelay);

//Delay
_ = mdf.Delay;

//FileDescriptor
Assert.AreEqual(-1, mdf.FileDescriptor);
Assert.IsTrue(mdf.Connect(GetTestRunParameter("host")));
Expand Down Expand Up @@ -158,6 +161,8 @@ public void GetAndSetPropertiesTest()
mdf.HandleDelay = false;
_ = mdf.HandleDelay;

_ = mdf.Delay;

Assert.AreEqual(allocatedBytes, GetTotalAllocatedBytes());
}

Expand Down
40 changes: 39 additions & 1 deletion Tests/Millistream.Streaming.UnitTests/MarketDataFeedTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ public void SetConnectionTimeoutTest()

[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void CreateMarketDataFeedWithNoNativeLibraryPathTest() => new MarketDataFeed(default);
public void CreateMarketDataFeedWithNoNativeLibraryPathTest() => new MarketDataFeed(default(string));

[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
Expand Down Expand Up @@ -415,6 +415,22 @@ public void GetAndSetHandleDelayTest()
nativeImplementation.Verify();
}

[TestMethod]
public void GetDelayTest()
{
const byte Delay = 1;
Mock<INativeImplementation> nativeImplementation = new();
IntPtr feedHandle = new(123);
nativeImplementation.Setup(x => x.mdf_create()).Returns(feedHandle);
nativeImplementation
.Setup(x => x.mdf_get_delay(feedHandle))
.Returns(Delay);
NativeImplementation.Implementation = nativeImplementation.Object;

using MarketDataFeed mdf = new();
Assert.AreEqual(Delay, mdf.Delay);
}

[TestMethod]
public void GetAndSetDataCallbackTest()
{
Expand Down Expand Up @@ -605,6 +621,24 @@ public void SendTest()
Assert.IsFalse(iMdf.Send(new Mock<IMessage>().Object));
}

[TestMethod]
public unsafe void DelayThrowsWhenNativeFunctionIsMissingTest()
{
NativeImplementation nativeImplementation = new(default);
nativeImplementation.mdf_get_delay = default;

using MarketDataFeed mdf = new(nativeImplementation);
try
{
_ = mdf.Delay;
Assert.Fail($"No expected {nameof(InvalidOperationException)} was thrown.");
}
catch (InvalidOperationException ex)
{
Assert.AreEqual($"The installed version of the native library doesn't include the {nameof(nativeImplementation.mdf_get_delay)} function.", ex.Message);
}
}

[TestMethod]
[ExpectedException(typeof(ObjectDisposedException))]
public void CannotGetFileDescriptorAfterDisposeTest() => _ = GetDisposedMdf().FileDescriptor;
Expand Down Expand Up @@ -725,6 +759,10 @@ public void SendTest()
[ExpectedException(typeof(ObjectDisposedException))]
public void CannotSetHandleDelayAfterDisposeTest() => GetDisposedMdf().HandleDelay = true;

[TestMethod]
[ExpectedException(typeof(ObjectDisposedException))]
public void CannotGetDelayAfterDisposeTest() => _ = GetDisposedMdf().Delay;

[TestMethod]
[ExpectedException(typeof(ObjectDisposedException))]
public void CannotGetDataCallbackfterDisposeTest() => _ = GetDisposedMdf().DataCallback;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public interface INativeImplementation
int mdf_get_property(IntPtr handle, int option, ref ulong value);
int mdf_get_property(IntPtr handle, int option, ref long value);
int mdf_set_property(IntPtr handle, int option, IntPtr value);
byte mdf_get_delay(IntPtr handle);
int mdf_connect(IntPtr handle, IntPtr server);
void mdf_disconnect(IntPtr handle);
IntPtr mdf_message_create();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ internal unsafe class NativeImplementation
internal delegate*<IntPtr, MDF_OPTION, ref ulong, int> mdf_get_ulong_property;
internal delegate*<IntPtr, MDF_OPTION, ref long, int> mdf_get_long_property;
internal delegate*<IntPtr, MDF_OPTION, IntPtr, int> mdf_set_property;
internal delegate*<IntPtr, byte> mdf_get_delay;
internal delegate*<IntPtr, IntPtr, int> mdf_connect;
internal delegate*<IntPtr, void> mdf_disconnect;
internal delegate*<IntPtr> mdf_message_create;
Expand Down Expand Up @@ -61,6 +62,7 @@ internal NativeImplementation(string _)
mdf_get_ulong_property = &MdfGetUInt64Property;
mdf_get_long_property = &MdfGetInt64Property;
mdf_set_property = &MdfSetProperty;
mdf_get_delay = &MdfGetDelay;
mdf_connect = &MdfConnect;
mdf_disconnect = &MdfDisconnect;
mdf_message_create = &MdfMessageCreate;
Expand Down Expand Up @@ -99,6 +101,7 @@ internal NativeImplementation(string _)
private static int MdfGetUInt64Property(IntPtr handle, MDF_OPTION option, ref ulong value) => Implementation.mdf_get_property(handle, (int)option, ref value);
private static int MdfGetInt64Property(IntPtr handle, MDF_OPTION option, ref long value) => Implementation.mdf_get_property(handle, (int)option, ref value);
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 int MdfConnect(IntPtr handle, IntPtr server) => Implementation.mdf_connect(handle, server);
private static void MdfDisconnect(IntPtr handle) => Implementation.mdf_disconnect(handle);
private static IntPtr MdfMessageCreate() => Implementation.mdf_message_create();
Expand Down

0 comments on commit 0b6de2d

Please sign in to comment.