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 class Codec : ICodec {
|
||||||
public Document Decode(byte[] data) {
|
public Document Decode(byte[] data) {
|
||||||
return new(
|
using var input = new MemoryStream(data);
|
||||||
new () {
|
|
||||||
{ "content-name", "text.txt" }
|
var version = input.ReadByte();
|
||||||
},
|
|
||||||
data
|
return version switch {
|
||||||
);
|
0x01 => DecodeV1(input),
|
||||||
|
_ => throw new Exception("Unsupported version")
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] Encode(Document document) {
|
public byte[] Encode(Document document) {
|
||||||
|
@ -29,6 +31,37 @@ public class Codec : ICodec {
|
||||||
return output.ToArray();
|
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) {
|
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
|
var encoder = new hpack.Encoder(0); //0 will disable dynamic table that we don't need anyways
|
||||||
|
|
||||||
|
|
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