Skip to content

Commit

Permalink
Encode/decode short strings
Browse files Browse the repository at this point in the history
  • Loading branch information
Havret committed Apr 16, 2024
1 parent bcabad6 commit b34ae25
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 4 deletions.
42 changes: 39 additions & 3 deletions src/ArtemisNetCoreClient/ArtemisBinaryConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ namespace ActiveMQ.Artemis.Core.Client;
internal static class ArtemisBinaryConverter
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int ReadInt32(in ReadOnlySpan<byte> source)
public static int ReadInt32(in ReadOnlySpan<byte> source, out int value)
{
return BinaryPrimitives.ReadInt32BigEndian(source);
value = BinaryPrimitives.ReadInt32BigEndian(source);
return sizeof(int);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
Expand Down Expand Up @@ -46,6 +47,14 @@ public static int WriteInt64(ref byte destination, long value)
return sizeof(long);
}


[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int ReadInt16(in ReadOnlySpan<byte> source, out short value)
{
value = BinaryPrimitives.ReadInt16BigEndian(source);
return sizeof(short);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int WriteInt16(ref byte destination, short value)
{
Expand Down Expand Up @@ -111,6 +120,33 @@ public static int GetStringByteCount(string value)
return byteCount;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int ReadString(in ReadOnlySpan<byte> source, out string value)
{
var readBytes = ReadInt32(source, out var length);
if (length < 9)
{
Span<char> chars = stackalloc char[length];
for (int i = 0; i < length; i++)
{
readBytes += ReadInt16(source[readBytes..], out var c);
chars[i] = (char) c;
}

value = new string(chars);
}
else if (length < 0xFFF)
{
value = string.Empty;
}
else
{
value = string.Empty;
}

return readBytes;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int WriteString(ref byte destination, string value)
{
Expand All @@ -135,7 +171,7 @@ private static int WriteAsShorts(ref byte destination, string value)
var offset = 0;
foreach (var c in value)
{
offset += WriteInt16(ref destination, (short) c);
offset += WriteInt16(ref destination.GetOffset(offset), (short) c);
}

return offset;
Expand Down
2 changes: 1 addition & 1 deletion src/ArtemisNetCoreClient/Transport2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ internal InboundPacket ReceivePacket()
{
Span<byte> frameSizeBuffer = stackalloc byte[sizeof(int)];
_ = _reader.Read(frameSizeBuffer);
var frameSize = ArtemisBinaryConverter.ReadInt32(frameSizeBuffer);
_ = ArtemisBinaryConverter.ReadInt32(frameSizeBuffer, out var frameSize);

Span<byte> typeBuffer = stackalloc byte[sizeof(byte)];
_ = _reader.Read(typeBuffer);
Expand Down
31 changes: 31 additions & 0 deletions test/ArtemisNetCoreClient.Tests/ArtemisBinaryConverterSpec.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,5 +90,36 @@ public void should_decode_nullable_bool(byte[] encoded, bool? expected)
// Assert
Assert.Equal(expected, value);
Assert.Equal(encoded.Length, readBytes);
}

[Fact]
public void should_encode_short_string()
{
// Arrange
var str = "abcdefgh";
var byteCount = ArtemisBinaryConverter.GetStringByteCount(str);
var byteBuffer = new byte[byteCount];

// Act
var writtenBytes = ArtemisBinaryConverter.WriteString(ref byteBuffer.AsSpan().GetReference(), str);

// Assert
var expected = new byte[] { 0, 0, 0, 8, 0, 97, 0, 98, 0, 99, 0, 100, 0, 101, 0, 102, 0, 103, 0, 104 };
Assert.Equal(expected, byteBuffer);
Assert.Equal(byteCount, writtenBytes);
}

[Fact]
public void should_decode_short_string()
{
// Arrange
var byteBuffer = new byte[] { 0, 0, 0, 8, 0, 97, 0, 98, 0, 99, 0, 100, 0, 101, 0, 102, 0, 103, 0, 104 };

// Act
var readBytes = ArtemisBinaryConverter.ReadString(byteBuffer, out var value);

// Assert
Assert.Equal("abcdefgh", value);
Assert.Equal(byteBuffer.Length, readBytes);
}
}

0 comments on commit b34ae25

Please sign in to comment.