More encoding work
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
use super::entry;
|
||||
use super::table::Table;
|
||||
use super::{huffman, Header};
|
||||
use super::table::{Table, Index};
|
||||
|
||||
use http::header::{HeaderName, HeaderValue};
|
||||
use bytes::BytesMut;
|
||||
use bytes::{BytesMut, BufMut};
|
||||
|
||||
pub struct Encoder {
|
||||
table: Table,
|
||||
@@ -24,7 +24,7 @@ impl Encoder {
|
||||
}
|
||||
|
||||
pub fn encode<'a, I>(&mut self, headers: I, dst: &mut BytesMut) -> Result<(), EncoderError>
|
||||
where I: IntoIterator<Item=Entry>,
|
||||
where I: IntoIterator<Item=Header>,
|
||||
{
|
||||
if let Some(max_size_update) = self.max_size_update.take() {
|
||||
// Write size update frame
|
||||
@@ -38,31 +38,118 @@ impl Encoder {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn encode_header(&mut self, entry: Entry, dst: &mut BytesMut)
|
||||
fn encode_header(&mut self, header: Header, dst: &mut BytesMut)
|
||||
-> Result<(), EncoderError>
|
||||
{
|
||||
if is_sensitive(&e) {
|
||||
if header.is_sensitive() {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
/*
|
||||
match self.table.entry(name, val) {
|
||||
Entry::Indexed(idx) => {
|
||||
unimplemented!();
|
||||
match self.table.index(header) {
|
||||
Index::Indexed(idx, _header) => {
|
||||
encode_int(idx, 7, 0x80, dst);
|
||||
}
|
||||
Entry::Name(idx) => {
|
||||
unimplemented!();
|
||||
Index::Name(idx, header) => {
|
||||
encode_int(idx, 4, 0, dst);
|
||||
encode_str(header.value_slice(), dst);
|
||||
}
|
||||
Entry::NotIndexed => {
|
||||
unimplemented!();
|
||||
Index::Inserted(header) => {
|
||||
dst.put_u8(0b01000000);
|
||||
encode_str(header.name().as_slice(), dst);
|
||||
encode_str(header.value_slice(), dst);
|
||||
}
|
||||
Index::InsertedValue(idx, header) => {
|
||||
encode_int(idx, 6, 0b01000000, dst);
|
||||
encode_str(header.value_slice(), dst);
|
||||
}
|
||||
Index::NotIndexed(header) => {
|
||||
dst.put_u8(0);
|
||||
encode_str(header.name().as_slice(), dst);
|
||||
encode_str(header.value_slice(), dst);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
unimplemented!();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn is_sensitive(e: &Entry) -> bool {
|
||||
false
|
||||
fn encode_str(val: &[u8], dst: &mut BytesMut) {
|
||||
use std::io::Cursor;
|
||||
|
||||
if val.len() != 0 {
|
||||
let idx = dst.len();
|
||||
|
||||
// Push a placeholder byte for the length header
|
||||
dst.put_u8(0);
|
||||
|
||||
// Encode with huffman
|
||||
huffman::encode(val, dst);
|
||||
|
||||
let huff_len = dst.len() - (idx + 1);
|
||||
|
||||
if encode_int_one_byte(huff_len, 7) {
|
||||
// Write the string head
|
||||
dst[idx] = (0x80 | huff_len as u8);
|
||||
} else {
|
||||
// Write the head to a placeholer
|
||||
let mut buf = [0; 8];
|
||||
|
||||
let head_len = {
|
||||
let mut head_dst = Cursor::new(&mut buf);
|
||||
encode_int(huff_len, 7, 0x80, &mut head_dst);
|
||||
head_dst.position() as usize
|
||||
};
|
||||
|
||||
// This is just done to reserve space in the destination
|
||||
dst.put_slice(&buf[1..head_len]);
|
||||
|
||||
// Shift the header forward
|
||||
for i in 0..huff_len {
|
||||
dst[idx + head_len + (huff_len - i)] = dst[idx + 1 + (huff_len - 1)];
|
||||
}
|
||||
|
||||
// Copy in the head
|
||||
for i in 0..head_len {
|
||||
dst[idx + i] = buf[i];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Write an empty string
|
||||
dst.put_u8(0);
|
||||
}
|
||||
}
|
||||
|
||||
/// Encode an integer into the given destination buffer
|
||||
fn encode_int<B: BufMut>(
|
||||
mut value: usize, // The integer to encode
|
||||
prefix_bits: usize, // The number of bits in the prefix
|
||||
first_byte: u8, // The base upon which to start encoding the int
|
||||
dst: &mut B) // The destination buffer
|
||||
{
|
||||
if encode_int_one_byte(value, prefix_bits) {
|
||||
dst.put_u8(first_byte | value as u8);
|
||||
return;
|
||||
}
|
||||
|
||||
let low = (1 << prefix_bits) - 1;
|
||||
|
||||
value -= low;
|
||||
|
||||
if value > 0x0fffffff {
|
||||
panic!("value out of range");
|
||||
}
|
||||
|
||||
dst.put_u8(first_byte | low as u8);
|
||||
|
||||
while value >= 128 {
|
||||
dst.put_u8(0b10000000 | value as u8);
|
||||
value = value >> 7;
|
||||
}
|
||||
|
||||
dst.put_u8(value as u8);
|
||||
}
|
||||
|
||||
/// Returns true if the in the int can be fully encoded in the first byte.
|
||||
fn encode_int_one_byte(value: usize, prefix_bits: usize) -> bool {
|
||||
value < (1 << prefix_bits) - 1
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user