From ec0e0ec0797e7c772c03e21ff02d561777c3d915 Mon Sep 17 00:00:00 2001 From: CheddarCrisp Date: Tue, 9 Jan 2024 21:04:25 -0500 Subject: [PATCH] Decoder implementation --- SDBD.Codec/Codec.cs | 47 ++++++++++++++++++++++++++++++------ SDBD.Codec/HeaderListener.cs | 16 ++++++++++++ 2 files changed, 56 insertions(+), 7 deletions(-) create mode 100644 SDBD.Codec/HeaderListener.cs diff --git a/SDBD.Codec/Codec.cs b/SDBD.Codec/Codec.cs index a9593c7..1f72257 100644 --- a/SDBD.Codec/Codec.cs +++ b/SDBD.Codec/Codec.cs @@ -2,12 +2,14 @@ public class Codec : ICodec { public Document Decode(byte[] data) { - return new( - new () { - { "content-name", "text.txt" } - }, - data - ); + using var input = new MemoryStream(data); + + var version = input.ReadByte(); + + return version switch { + 0x01 => DecodeV1(input), + _ => throw new Exception("Unsupported version") + }; } public byte[] Encode(Document document) { @@ -29,9 +31,40 @@ public class Codec : ICodec { return output.ToArray(); } + private Document DecodeV1(Stream stream) { + var headerLengthBytes = new byte[2]; + stream.ReadExactly(headerLengthBytes); + + var headerLength = BitConverter.ToUInt16(headerLengthBytes); + + var headerBytes = new byte[headerLength]; + stream.ReadExactly(headerBytes); + + var headers = unpackHeaders(headerBytes); + string contentLengthString; + headers.Remove("content-length", out contentLengthString); + var contentLength = int.Parse(contentLengthString); + + var data = new byte[contentLength]; + stream.ReadExactly(data); + + return new Document(headers, data); + } + + private Dictionary unpackHeaders(byte[] packedHeaders) { + var decoder = new hpack.Decoder(8192, 4096); + var listener = new HeaderListener(); + + using var reader = new BinaryReader(new MemoryStream(packedHeaders)); + decoder.Decode(reader, listener); + decoder.EndHeaderBlock(); + + return listener.Headers; + } + private byte[] packHeaders(IEnumerable> headers) { var encoder = new hpack.Encoder(0); //0 will disable dynamic table that we don't need anyways - + using var output = new MemoryStream(); using var writer = new BinaryWriter(output); diff --git a/SDBD.Codec/HeaderListener.cs b/SDBD.Codec/HeaderListener.cs new file mode 100644 index 0000000..0abaaf3 --- /dev/null +++ b/SDBD.Codec/HeaderListener.cs @@ -0,0 +1,16 @@ +using System.Text; + +internal class HeaderListener : hpack.IHeaderListener { + public Dictionary Headers { get; private set; } + + public HeaderListener() { + Headers = new Dictionary(); + } + + public void AddHeader(byte[] nameBytes, byte[] valueBytes, bool sensitive) { + var name = Encoding.UTF8.GetString(nameBytes); + var value = Encoding.UTF8.GetString(valueBytes); + + Headers.Add(name, value); + } +}