Decoder implementation

This commit is contained in:
CheddarCrisp 2024-01-09 21:04:25 -05:00
parent d4cdae8c6e
commit ec0e0ec079
2 changed files with 56 additions and 7 deletions

View file

@ -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<string, string> 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<KeyValuePair<string, string>> 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);

View file

@ -0,0 +1,16 @@
using System.Text;
internal class HeaderListener : hpack.IHeaderListener {
public Dictionary<string, string> Headers { get; private set; }
public HeaderListener() {
Headers = new Dictionary<string, string>();
}
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);
}
}