public void TestIsAncestor() { Setup(); var messageAllocation = new Span <byte>(new byte[IsAncestor.SizeInBytes]); var isAncestorReq = new IsAncestor(1, 5, _3, _1); // Serialize message to put it into the inbox MessageSerializers.ClientSerializeIsAncestor(isAncestorReq, messageAllocation); _inbox.TryWrite(messageAllocation); _controller.DoWork(); var result = _outbox.Peek(); Assert.Equal(MessageType.AncestorResponse, ClientServerMessage.GetMessageType(result)); Assert.True(ClientServerMessage.TryGetLength(result, out int responseSize)); Assert.Equal(AncestorResponse.SizeInBytes, responseSize); var response = MessageSerializers.ClientDeserializeAncestorResponse(result); Assert.Equal(1U, response.RequestId); Assert.Equal(5U, response.ClientId); Assert.True(response.Answer); // get a wrong ancestor isAncestorReq = new IsAncestor(1, 5, _3, _5); // Serialize message to put it into the inbox MessageSerializers.ClientSerializeIsAncestor(isAncestorReq, messageAllocation); _inbox.TryWrite(messageAllocation); _controller.DoWork(); _outbox.Next(); result = _outbox.Peek(); var response2 = MessageSerializers.ClientDeserializeAncestorResponse(result); Assert.Equal(1U, response2.RequestId); Assert.Equal(5U, response2.ClientId); Assert.Equal(MessageType.AncestorResponse, response2.ResponseType); Assert.False(response2.Answer); }
// TODO: [vermorel] Should probably be renamed 'GetInputMessageLenght()'. private int InputMessageLength() { if (_endIn < sizeof(int)) { return(0); } if (!ClientServerMessage.TryGetLength(_bufferIn, out var length)) { // TODO: [vermorel] Pattern below is bizarelly written, to be rewritten. new Span <byte>(_errorSpan).EmitRequestTooShort(_bufferIn); if (_socket.Connected()) { _socket.Send(_errorSpan); _socket.Close(); } return(0); } if (length > ClientServerMessage.MaxSizeInBytes || length < ClientServerMessage.MinSizeInBytes) { // TODO: [vermorel] Pattern below is bizarelly written, to be rewritten. new Span <byte>(_errorSpan).EmitRequestTooLong(_bufferIn); if (_socket.Connected()) { _socket.Send(_errorSpan); _socket.Close(); } return(0); } // TODO: [vermorel] Clarify what is the edge-case here. Unclear. if (_endIn < length) { return(0); } return(length); }
public void TestLengthField() { ClientServerMessage.TryGetLength(_bytes, out var length); Assert.Equal(0x14131211, length); Assert.False(ClientServerMessage.TryGetLength(new Span <byte>(_bytes, 0, 3), out length)); }
// TODO: [vermorel] The condition for not succeeding to write should be clarified. public bool TryWrite(Span <byte> message) { // TODO: [vermorel] If we are not even connected, we should throw an 'InvalidOperationException'. if (!IsConnected) { return(false); } if (message.Length > ClientServerMessage.MaxSizeInBytes) { throw new ArgumentException( $"Message size {message.Length} exceeds max size {ClientServerMessage.MaxSizeInBytes}."); } ClientServerMessage.TryGetLength(message, out var announcedMessageLength); if (announcedMessageLength != message.Length) { throw new ArgumentException( $"Message size {announcedMessageLength} in span of size {message.Length}."); } // TODO: [vermorel] This operation should be moving within the 'ClientServerMessage' // delete client ID which is just for internal purposes BitConverter.TryWriteBytes(message.Slice(8), 0U); // Try to send message only if buffer is empty, to not corrupt the message stream if (_endOut > 0) { if (message.Length > _bufferOut.Length - _endOut) { // No room in buffer for this message, close connection. // This behaviour may change in future versions. _socket.Close(); return(false); } if (!message.TryCopyTo(new Span <byte>(_bufferOut).Slice(_endOut))) { // Should really replace this with a span copy function throw new NotImplementedException("No handling for case when byte copy fails"); } _endOut += message.Length; return(true); } // Nothing in buffer, so the socket is free for sending var bytesSent = _socket.Send(message); if (bytesSent == message.Length) { return(true); } var bytesNotSent = message.Length - bytesSent; if (!message.Slice(bytesSent).TryCopyTo(_bufferOut)) { // TODO: Should really replace this with a span copy function throw new NotImplementedException("No handling for case when byte copy fails"); } _endOut += bytesNotSent; return(true); }