Add test for WriteGetMessage

This commit is contained in:
Bond_009 2021-02-12 18:35:54 +01:00
parent 3a9fcb6abd
commit e1bc322b70
2 changed files with 48 additions and 22 deletions

View File

@ -288,19 +288,14 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
internal static int WriteGetMessage(Span<byte> buffer, int tuner, string name)
{
var byteName = string.Format(CultureInfo.InvariantCulture, "/tuner{0}/{1}", tuner, name);
int offset = WriteHeaderAndName(buffer, byteName);
// calculate crc and insert at the end of the message
var crc = Crc32.Compute(buffer.Slice(0, offset));
BinaryPrimitives.WriteUInt32LittleEndian(buffer.Slice(offset), crc);
return offset + 4;
int offset = WriteHeaderAndPayload(buffer, byteName);
return FinishPacket(buffer, offset);
}
private static int WriteSetMessage(Span<byte> buffer, int tuner, string name, string value, uint? lockkey)
{
var byteName = string.Format(CultureInfo.InvariantCulture, "/tuner{0}/{1}", tuner, name);
int offset = WriteHeaderAndName(buffer, byteName);
int offset = WriteHeaderAndPayload(buffer, byteName);
buffer[offset++] = GetSetValue;
offset += WriteNullTerminatedString(buffer.Slice(offset), value);
@ -313,17 +308,14 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
offset += 4;
}
// calculate crc and insert at the end of the message
var crc = Crc32.Compute(buffer.Slice(0, offset));
BinaryPrimitives.WriteUInt32LittleEndian(buffer.Slice(offset), crc);
return offset + 4;
return FinishPacket(buffer, offset);
}
internal static int WriteNullTerminatedString(Span<byte> buffer, ReadOnlySpan<char> value)
internal static int WriteNullTerminatedString(Span<byte> buffer, ReadOnlySpan<char> payload)
{
int len = Encoding.UTF8.GetBytes(value, buffer.Slice(1)) + 1;
int len = Encoding.UTF8.GetBytes(payload, buffer.Slice(1)) + 1;
// TODO: variable length: this can be 2 bytes if len > 127
// Write length in front of value
buffer[0] = Convert.ToByte(len);
@ -333,21 +325,36 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
return len;
}
private static int WriteHeaderAndName(Span<byte> buffer, ReadOnlySpan<char> payload)
private static int WriteHeaderAndPayload(Span<byte> buffer, ReadOnlySpan<char> payload)
{
// insert header bytes into message
// Packet type
BinaryPrimitives.WriteUInt16BigEndian(buffer, GetSetRequest);
int offset = 2;
// Subtract 4 bytes for header and 4 bytes for crc
BinaryPrimitives.WriteUInt16BigEndian(buffer.Slice(offset), (ushort)(payload.Length + 2));
// insert tag name and length
// We write the payload length at the end
int offset = 4;
// Tag
buffer[offset++] = GetSetName;
offset += WriteNullTerminatedString(buffer.Slice(offset), payload);
// Payload length + data
int strLen = WriteNullTerminatedString(buffer.Slice(offset), payload);
offset += strLen;
return offset;
}
private static int FinishPacket(Span<byte> buffer, int offset)
{
// Payload length
BinaryPrimitives.WriteUInt16BigEndian(buffer.Slice(2), (ushort)(offset - 4));
// calculate crc and insert at the end of the message
var crc = Crc32.Compute(buffer.Slice(0, offset));
BinaryPrimitives.WriteUInt32LittleEndian(buffer.Slice(offset), crc);
return offset + 4;
}
private static bool ParseReturnMessage(byte[] buf, int numBytes, out string returnVal)
{
returnVal = string.Empty;

View File

@ -35,5 +35,24 @@ namespace Jellyfin.Server.Implementations.Tests.LiveTv
Assert.Equal(expected.Length, len);
Assert.True(expected.SequenceEqual(buffer.Slice(0, len)));
}
[Fact]
public void WriteGetMessage_Valid_Success()
{
ReadOnlySpan<byte> expected = stackalloc byte[]
{
0, 4,
0, 12,
3,
10, (byte)'/', (byte)'t', (byte)'u', (byte)'n', (byte)'e', (byte)'r', (byte)'0', (byte)'/', (byte)'N', 0,
0xc0, 0xc9, 0x87, 0x33
};
Span<byte> buffer = stackalloc byte[128];
int len = HdHomerunManager.WriteGetMessage(buffer, 0, "N");
Assert.Equal(expected.Length, len);
Assert.True(expected.SequenceEqual(buffer.Slice(0, len)));
}
}
}