Decoder implementation
This commit is contained in:
parent
d4cdae8c6e
commit
ec0e0ec079
2 changed files with 56 additions and 7 deletions
|
@ -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);
|
||||
|
||||
|
|
16
SDBD.Codec/HeaderListener.cs
Normal file
16
SDBD.Codec/HeaderListener.cs
Normal 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);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue