diff --git a/lib/ShortDev.Microsoft.ConnectedDevices/Messages/CommonHeaders.cs b/lib/ShortDev.Microsoft.ConnectedDevices/Messages/CommonHeaders.cs index d16259bd..763d9c4c 100644 --- a/lib/ShortDev.Microsoft.ConnectedDevices/Messages/CommonHeaders.cs +++ b/lib/ShortDev.Microsoft.ConnectedDevices/Messages/CommonHeaders.cs @@ -1,12 +1,13 @@ using System.Buffers.Binary; using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; namespace ShortDev.Microsoft.ConnectedDevices.Messages; /// /// The is common for all Messages. /// -public sealed class CommonHeader : ICdpHeader +public sealed class CommonHeader : ICdpSerializable { public static CommonHeader Parse(ref EndianReader reader) { @@ -93,6 +94,35 @@ public void Write(EndianWriter writer) writer.Write((byte)0); } + [MethodImpl(MethodImplOptions.AggressiveOptimization | MethodImplOptions.AggressiveInlining)] + internal int CalcSize() + { + int size = + sizeof(ushort) + // Constants.Signature + sizeof(ushort) + // MessageLength + sizeof(byte) + // Constants.ProtocolVersion + sizeof(byte) + // Type + sizeof(short) + // Flags + sizeof(uint) + // SequenceNumber + sizeof(ulong) + // RequestID + sizeof(ushort) + // FragmentIndex + sizeof(ushort) + // FragmentCount + sizeof(ulong) + // SessionId + sizeof(ulong); // ChannelId + + foreach (var header in AdditionalHeaders) + { + size += + sizeof(byte) + // Type + sizeof(byte) + // Value.Length + header.Value.Length; // Value + } + + return size + + sizeof(byte) + // AdditionalHeaderType.None + sizeof(byte); // 0 + } + /// /// Entire message length in bytes including signature. /// @@ -150,7 +180,7 @@ public void Write(EndianWriter writer) /// Returns size of the whole rest of the message (excluding headers) (including hmac) /// public int PayloadSize - => MessageLength - (int)((ICdpSerializable)this).CalcSize(); + => MessageLength - (int)CalcSize(); #region Flags @@ -171,7 +201,7 @@ public void CorrectClientSessionBit() public const int MessageLengthOffset = 2; public void SetPayloadLength(int payloadSize) { - MessageLength = (ushort)(payloadSize + ((ICdpSerializable)this).CalcSize()); + MessageLength = (ushort)(payloadSize + CalcSize()); } public static void ModifyMessageLength(Span msgBuffer, short delta) diff --git a/lib/ShortDev.Microsoft.ConnectedDevices/Messages/ICdpSerializable.cs b/lib/ShortDev.Microsoft.ConnectedDevices/Messages/ICdpSerializable.cs index af683176..9642636f 100644 --- a/lib/ShortDev.Microsoft.ConnectedDevices/Messages/ICdpSerializable.cs +++ b/lib/ShortDev.Microsoft.ConnectedDevices/Messages/ICdpSerializable.cs @@ -5,13 +5,6 @@ public interface ICdpSerializable : ICdpWriteable where T : ICdpSerializable< static abstract T Parse(ref EndianReader reader); public static bool TryParse(ref EndianReader reader, out T? result, out Exception? error) => throw new NotImplementedException(); - - public long CalcSize() - { - EndianWriter writer = new(Endianness.BigEndian); - Write(writer); - return writer.Buffer.Size; - } } public interface ICdpArraySerializable where T : ICdpArraySerializable diff --git a/tests/ShortDev.Microsoft.ConnectedDevices.Test/Messages/CommonHeaderTest.cs b/tests/ShortDev.Microsoft.ConnectedDevices.Test/Messages/CommonHeaderTest.cs new file mode 100644 index 00000000..7b48ee12 --- /dev/null +++ b/tests/ShortDev.Microsoft.ConnectedDevices.Test/Messages/CommonHeaderTest.cs @@ -0,0 +1,43 @@ +using ShortDev.Microsoft.ConnectedDevices.Messages; +using System.Buffers; + +namespace ShortDev.Microsoft.ConnectedDevices.Test.Messages; + +public class CommonHeaderTest +{ + [Fact] + public void CalcSize_YieldsCorrectResult_WhenNoHeaders() + { + using EndianWriter writer = EndianWriter.Create(Endianness.BigEndian, ArrayPool.Shared); + + CommonHeader header = new(); + header.Write(writer); + var expected = writer.Buffer.WrittenSpan.Length; + + var actual = header.CalcSize(); + + Assert.Equal(expected, actual); + } + + [Fact] + public void CalcSize_YieldsCorrectResult_WhenWithHeaders() + { + using EndianWriter writer = EndianWriter.Create(Endianness.BigEndian, ArrayPool.Shared); + + CommonHeader header = new() + { + Type = MessageType.Connect, + AdditionalHeaders = { + AdditionalHeader.FromUInt32(AdditionalHeaderType.Header129, 0x70_00_00_03), + AdditionalHeader.FromUInt64(AdditionalHeaderType.PeerCapabilities, (ulong)PeerCapabilities.All), + AdditionalHeader.FromUInt64(AdditionalHeaderType.Header131, 6u) + } + }; + header.Write(writer); + var expected = writer.Buffer.WrittenSpan.Length; + + var actual = header.CalcSize(); + + Assert.Equal(expected, actual); + } +}