sdbd-demo.git

git clone https://git.crispbyte.dev/sdbd-demo.git

commit
ec0e0ec
parent
d4cdae8
author
CheddarCrisp
date
2024-01-10 03:04:25 +0100 CET
Decoder implementation
2 files changed,  +56, -7
M SDBD.Codec/Codec.cs
+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 
A SDBD.Codec/HeaderListener.cs
+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+}