80 lines
2.2 KiB
C#
80 lines
2.2 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Text;
|
|
|
|
namespace Questionable.LgbWorker;
|
|
|
|
internal static class LgbWorkerFraming
|
|
{
|
|
public static void Write(Stream stream, in LgbWorkerMessage message)
|
|
{
|
|
using MemoryStream memoryStream = new MemoryStream();
|
|
using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8, leaveOpen: true);
|
|
binaryWriter.Write((byte)message.Type);
|
|
switch (message.Type)
|
|
{
|
|
case LgbMessageType.Progress:
|
|
binaryWriter.Write(message.Done);
|
|
binaryWriter.Write(message.Total);
|
|
break;
|
|
case LgbMessageType.Final:
|
|
binaryWriter.Write(message.Success);
|
|
binaryWriter.Write(message.DurationMs);
|
|
binaryWriter.Write(message.Error ?? string.Empty);
|
|
break;
|
|
default:
|
|
throw new ArgumentOutOfRangeException("message");
|
|
}
|
|
binaryWriter.Flush();
|
|
byte[] array = memoryStream.ToArray();
|
|
Span<byte> span = stackalloc byte[4];
|
|
BitConverter.TryWriteBytes(span, array.Length);
|
|
stream.Write(span);
|
|
stream.Write(array);
|
|
}
|
|
|
|
public static LgbWorkerMessage Read(Stream stream)
|
|
{
|
|
Span<byte> span = stackalloc byte[4];
|
|
ReadExact(stream, span);
|
|
int num = BitConverter.ToInt32(span);
|
|
if ((num <= 0 || num > 65536) ? true : false)
|
|
{
|
|
throw new InvalidDataException($"Invalid frame length: {num}");
|
|
}
|
|
byte[] array = new byte[num];
|
|
ReadExact(stream, array);
|
|
using BinaryReader binaryReader = new BinaryReader(new MemoryStream(array), Encoding.UTF8);
|
|
LgbMessageType lgbMessageType = (LgbMessageType)binaryReader.ReadByte();
|
|
return lgbMessageType switch
|
|
{
|
|
LgbMessageType.Progress => new LgbWorkerMessage
|
|
{
|
|
Type = lgbMessageType,
|
|
Done = binaryReader.ReadInt32(),
|
|
Total = binaryReader.ReadInt32()
|
|
},
|
|
LgbMessageType.Final => new LgbWorkerMessage
|
|
{
|
|
Type = lgbMessageType,
|
|
Success = binaryReader.ReadBoolean(),
|
|
DurationMs = binaryReader.ReadInt64(),
|
|
Error = binaryReader.ReadString()
|
|
},
|
|
_ => throw new InvalidDataException($"Unknown message type: {lgbMessageType}"),
|
|
};
|
|
}
|
|
|
|
private static void ReadExact(Stream stream, Span<byte> buffer)
|
|
{
|
|
int num;
|
|
for (int i = 0; i < buffer.Length; i += num)
|
|
{
|
|
num = stream.Read(buffer.Slice(i));
|
|
if (num == 0)
|
|
{
|
|
throw new EndOfStreamException();
|
|
}
|
|
}
|
|
}
|
|
}
|