Skip to content

Commit

Permalink
Don't throw ArgumentNullException
Browse files Browse the repository at this point in the history
  • Loading branch information
mgnsm committed Apr 17, 2023
1 parent d7371ef commit 56215e4
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 51 deletions.
24 changes: 6 additions & 18 deletions Source/Millistream.Streaming/MarketDataFeed.cs
Original file line number Diff line number Diff line change
Expand Up @@ -484,12 +484,11 @@ public bool GetNextField(out Field field, out ReadOnlySpan<byte> value)
/// </summary>
/// <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>
/// <exception cref="ArgumentNullException"><paramref name="servers"/> is <see langword="null" /> or <see cref="string.Empty"/>.</exception>
/// <remarks>The corresponding native function is mdf_connect.</remarks>
public bool Connect(string servers)
{
if (string.IsNullOrEmpty(servers))
throw new ArgumentNullException(nameof(servers));
return false;

int length = Encoding.UTF8.GetMaxByteCount(servers.Length);
byte[] bytes = ArrayPool<byte>.Shared.Rent(length + 1);
Expand Down Expand Up @@ -524,29 +523,18 @@ public bool Connect(string servers)
/// </summary>
/// <param name="message">The managed message handle.</param>
/// <returns><see langword="true" /> if there were no errors detected when sending the data, or <see langword="false" /> if an error was detected (such as not connected to any server). Due to the nature of TCP/IP, a successful return code does not guarantee that the server has received the messages.</returns>
/// <exception cref="ArgumentNullException"><paramref name="message"/> is <see langword="null" />.</exception>
/// <remarks>The corresponding native function is mdf_message_send.</remarks>
public bool Send(Message message)
{
if (message == null)
throw new ArgumentNullException(nameof(message));

return _nativeImplementation.mdf_message_send(_feedHandle, message.Handle) == 1;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Send(Message message) =>
message != null && _nativeImplementation.mdf_message_send(_feedHandle, message.Handle) == 1;

/// <summary>
/// Calls <see cref="Send(Message)"/> to send all the active messages in a managed message handle to the server if <paramref name="message"/> is a <see cref="Message"/>. For any other implementation of <see cref="IMessage" />, the method always returns <see langword="false" />.
/// </summary>
/// <param name="message">An implementation of the managed message handle.</param>
/// <returns><see langword="true" /> if <paramref name="message"/> is a <see cref="Message"/> and there were no errors detected when sending the data, or <see langword="false" /> if an error was detected or if <paramref name="message"/> is not a <see cref="Message"/>.</returns>
/// <exception cref="ArgumentNullException"><paramref name="message"/> is <see langword="null" />.</exception>
bool IMarketDataFeed<TCallbackUserData, TStatusCallbackUserData>.Send(IMessage message)
{
if (message == null)
throw new ArgumentNullException(nameof(message));

return message is Message messageWithHandle && Send(messageWithHandle);
}
bool IMarketDataFeed<TCallbackUserData, TStatusCallbackUserData>.Send(IMessage message) =>
message is Message messageWithHandle && Send(messageWithHandle);

/// <summary>
/// Releases any resources used by the <see cref="MarketDataFeed{TCallbackData,TStatusCallbackData}"/> instance.
Expand Down
26 changes: 8 additions & 18 deletions Source/Millistream.Streaming/Message.cs
Original file line number Diff line number Diff line change
Expand Up @@ -488,16 +488,11 @@ public bool AddList(Field tag, string value) =>
/// <param name="sourceInsref">The instrument reference of the messages to be moved.</param>
/// <param name="destinationInsRef">The new instrument reference of the moved or modified messages.</param>
/// <returns><see langword="true" /> if the operation was successfull, or <see langword="false" /> if it failed.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> is <see langword="null" />.</exception>
/// <remarks>The corresponding native function is mdf_message_move.</remarks>
public static bool Move(Message source, Message destination, ulong sourceInsref, ulong destinationInsRef)
{
if (source == null)
throw new ArgumentNullException(nameof(source));

return source._nativeImplementation.mdf_message_move != default
&& source._nativeImplementation.mdf_message_move(source._handle, destination?._handle ?? IntPtr.Zero, sourceInsref, destinationInsRef) == 1;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool Move(Message source, Message destination, ulong sourceInsref, ulong destinationInsRef) => source != null
&& source._nativeImplementation.mdf_message_move != default
&& source._nativeImplementation.mdf_message_move(source._handle, destination?._handle ?? IntPtr.Zero, sourceInsref, destinationInsRef) == 1;

/// <summary>
/// Serializes the message chain in the message handle and produces a base64 encoded string to the address pointed to by <paramref name="result"/>. It's the responsibility of the caller to free the produced unmanaged string.
Expand All @@ -517,16 +512,11 @@ public bool Serialize(out IntPtr result)
/// </summary>
/// <param name="data">A base64 encoded (serialized) message chain.</param>
/// <returns><see langword="true" /> if the message chain was successfully deserialized, or <see langword="false" /> if the deserialization failed (if so the current message chain in the message handler is left untouched).</returns>
/// <exception cref="ArgumentNullException"><paramref name="data"/> is <see langword="null" /> or <see cref="string.Empty"/>.</exception>
/// <remarks>The corresponding native function is mdf_message_deserialize.</remarks>
public bool Deserialize(string data)
{
if (string.IsNullOrEmpty(data))
throw new ArgumentNullException(nameof(data));

return _nativeImplementation.mdf_message_deserialize_str != default &&
_nativeImplementation.mdf_message_deserialize_str(_handle, data) == 1;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Deserialize(string data) => !string.IsNullOrEmpty(data)
&& _nativeImplementation.mdf_message_deserialize_str != default
&& _nativeImplementation.mdf_message_deserialize_str(_handle, data) == 1;

/// <summary>
/// Deserializes a base64 encoded message chain and replaces the existing (if any) message chain in the message handle.
Expand Down
5 changes: 5 additions & 0 deletions Tests/Millistream.Streaming.UnitTests/MarketDataFeedTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,9 @@ public void ConnectTest()
using MarketDataFeed mdf = new();
Assert.IsTrue(mdf.Connect(Servers));
nativeImplementation.Verify(expression, Times.Once);

Assert.IsFalse(mdf.Connect(default));
Assert.IsFalse(mdf.Connect(string.Empty));
}

[TestMethod]
Expand Down Expand Up @@ -674,6 +677,7 @@ public void SendTest()
using MarketDataFeed mdf = new();
Assert.IsTrue(mdf.Send(message));
nativeImplementation.Verify(expression, Times.Once);
Assert.IsFalse(mdf.Send(default));

IMarketDataFeed<object, object> iMdf = mdf;
Assert.IsTrue(iMdf.Send(message));
Expand All @@ -682,6 +686,7 @@ public void SendTest()
Assert.IsTrue(iMdf.Send(iMessage));
nativeImplementation.Verify(expression, Times.Exactly(3));
Assert.IsFalse(iMdf.Send(new Mock<IMessage>().Object));
Assert.IsFalse(iMdf.Send(default));
}

[TestMethod]
Expand Down
19 changes: 4 additions & 15 deletions Tests/Millistream.Streaming.UnitTests/MessageTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,8 @@ public void MoveTest()
_nativeImplementation.Setup(x => x.mdf_message_move(source.Handle, destination.Handle, SourceInsref, DestinationInsref)).Returns(0).Verifiable();
Assert.IsFalse(Message.Move(source, destination, SourceInsref, DestinationInsref));
_nativeImplementation.Verify();

Assert.IsFalse(Message.Move(null, new(), 1, 2));
}

[TestMethod]
Expand Down Expand Up @@ -426,6 +428,8 @@ public void DeserializeTest()
.Returns(1)
.Callback((IntPtr message, string data) => Assert.AreEqual(Data, data));
using Message message = new();
Assert.IsFalse(message.Deserialize(default(string)));
Assert.IsFalse(message.Deserialize(string.Empty));
Assert.IsTrue(message.Deserialize(Data));
_nativeImplementation.Verify(x => x.mdf_message_deserialize_str(messageHandle, It.IsAny<string>()), Times.Once);

Expand Down Expand Up @@ -460,21 +464,6 @@ public void DisposeTest()
[ExpectedException(typeof(ArgumentNullException))]
public void CreateMessageWithEmptyNativeLibraryPathTest() => new Message(string.Empty);

[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void MoveNullReferenceTest() =>
Message.Move(null, new(), 1, 2);

[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void DeserializeNullReferenceTest() =>
new Message().Deserialize(default(string));

[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void DeserializeEmptyStringTest() =>
new Message().Deserialize(string.Empty);

[TestMethod]
public void MethodsReturnFalseAfterDisposeTest()
{
Expand Down

0 comments on commit 56215e4

Please sign in to comment.