- commit
- ec0e0ec
- parent
- d4cdae8
- author
- CheddarCrisp
- date
- 2024-01-10 03:04:25 +0100 CET
Decoder implementation
2 files changed,
+56,
-7
+40,
-7
1@@ -2,12 +2,14 @@
2
3 public class Codec : ICodec {
4 public Document Decode(byte[] data) {
5- return new(
6- new () {
7- { "content-name", "text.txt" }
8- },
9- data
10- );
11+ using var input = new MemoryStream(data);
12+
13+ var version = input.ReadByte();
14+
15+ return version switch {
16+ 0x01 => DecodeV1(input),
17+ _ => throw new Exception("Unsupported version")
18+ };
19 }
20
21 public byte[] Encode(Document document) {
22@@ -29,9 +31,40 @@ public class Codec : ICodec {
23 return output.ToArray();
24 }
25
26+ private Document DecodeV1(Stream stream) {
27+ var headerLengthBytes = new byte[2];
28+ stream.ReadExactly(headerLengthBytes);
29+
30+ var headerLength = BitConverter.ToUInt16(headerLengthBytes);
31+
32+ var headerBytes = new byte[headerLength];
33+ stream.ReadExactly(headerBytes);
34+
35+ var headers = unpackHeaders(headerBytes);
36+ string contentLengthString;
37+ headers.Remove("content-length", out contentLengthString);
38+ var contentLength = int.Parse(contentLengthString);
39+
40+ var data = new byte[contentLength];
41+ stream.ReadExactly(data);
42+
43+ return new Document(headers, data);
44+ }
45+
46+ private Dictionary<string, string> unpackHeaders(byte[] packedHeaders) {
47+ var decoder = new hpack.Decoder(8192, 4096);
48+ var listener = new HeaderListener();
49+
50+ using var reader = new BinaryReader(new MemoryStream(packedHeaders));
51+ decoder.Decode(reader, listener);
52+ decoder.EndHeaderBlock();
53+
54+ return listener.Headers;
55+ }
56+
57 private byte[] packHeaders(IEnumerable<KeyValuePair<string, string>> headers) {
58 var encoder = new hpack.Encoder(0); //0 will disable dynamic table that we don't need anyways
59-
60+
61 using var output = new MemoryStream();
62 using var writer = new BinaryWriter(output);
63
+16,
-0
1@@ -0,0 +1,16 @@
2+using System.Text;
3+
4+internal class HeaderListener : hpack.IHeaderListener {
5+ public Dictionary<string, string> Headers { get; private set; }
6+
7+ public HeaderListener() {
8+ Headers = new Dictionary<string, string>();
9+ }
10+
11+ public void AddHeader(byte[] nameBytes, byte[] valueBytes, bool sensitive) {
12+ var name = Encoding.UTF8.GetString(nameBytes);
13+ var value = Encoding.UTF8.GetString(valueBytes);
14+
15+ Headers.Add(name, value);
16+ }
17+}