mod error;
mod primitives;
pub use error::*;
use primitives::*;
pub use httlib_huffman::DecoderSpeed;
use super::Table;
#[derive(Debug)]
pub struct Decoder<'a> {
speed: DecoderSpeed,
max_dynamic_size: u32,
table: Table<'a>,
}
impl<'a> Decoder<'a> {
pub const WITH_INDEXING: u8 = 0x4;
pub const NEVER_INDEXED: u8 = 0x8;
pub fn with_dynamic_size(max_dynamic_size: u32) -> Self {
Self {
speed: DecoderSpeed::FiveBits,
max_dynamic_size,
table: Table::with_dynamic_size(max_dynamic_size),
}
}
pub fn max_dynamic_size(&self) -> u32 {
self.table.max_dynamic_size()
}
pub fn set_max_dynamic_size(&mut self, size: u32) {
self.max_dynamic_size = size;
}
pub fn decode(
&mut self,
buf: &mut Vec<u8>,
dst: &mut Vec<(Vec<u8>, Vec<u8>, u8)>,
) -> Result<usize, DecoderError> {
let mut total = 0;
loop {
if buf.is_empty() {
return Ok(total);
}
let mut data = Vec::with_capacity(1);
total += self.decode_exact(buf, &mut data)?;
dst.append(&mut data);
}
}
pub fn decode_exact(
&mut self,
buf: &mut Vec<u8>,
dst: &mut Vec<(Vec<u8>, Vec<u8>, u8)>,
) -> Result<usize, DecoderError> {
let mut total = 0;
let mut limit = dst.capacity();
loop {
if buf.is_empty() || limit == 0 {
return Ok(total);
} else {
limit -= 1;
}
let octet = buf[0];
if octet & 128 == 128 { total += self.decode_indexed(buf, dst)?;
} else if octet & 64 == 64 { total += self.decode_literal(buf, dst)?;
} else if octet & 32 == 32 {
self.update_max_dynamic_size(buf)?;
} else if octet & 16 == 16 { total += self.decode_literal(buf, dst)?;
} else { total += self.decode_literal(buf, dst)?;
}
}
}
fn decode_indexed(
&self,
buf: &mut Vec<u8>,
dst: &mut Vec<(Vec<u8>, Vec<u8>, u8)>,
) -> Result<usize, DecoderError> {
let mut index = 0;
let total = decode_integer(buf, &mut index, 7)?;
let (name, value) = match self.table.get(index) {
Some(field) => field,
None => return Err(DecoderError::InvalidIndex),
};
dst.push((name.to_vec(), value.to_vec(), 0x0));
buf.drain(0..total);
Ok(total)
}
fn decode_literal(
&mut self,
buf: &mut Vec<u8>,
dst: &mut Vec<(Vec<u8>, Vec<u8>, u8)>,
) -> Result<usize, DecoderError> {
let mut total = 0;
let octet = buf[0];
let prefix = if octet & 64 == 64 { 6
} else { 4
};
let mut index = 0;
total += decode_integer(&buf[total..], &mut index, prefix)?;
let name = if index == 0 {
let mut name = Vec::new();
total += decode_string(&buf[total..], self.speed, &mut name)?;
name
} else if let Some(h) = self.table.get(index) {
h.0.to_vec()
} else {
return Err(DecoderError::InvalidIndex);
};
let mut value = Vec::new();
total += decode_string(&buf[total..], self.speed, &mut value)?;
if octet & 64 == 64 {
self.table.insert(name.clone(), value.clone());
dst.push((name, value, 0x4));
} else if octet & 16 == 16 {
dst.push((name, value, 0x8));
} else {
dst.push((name, value, 0x0));
}
buf.drain(0..total);
Ok(total)
}
fn update_max_dynamic_size(
&mut self,
buf: &mut Vec<u8>,
) -> Result<usize, DecoderError> {
let mut new_size = 0;
let total = decode_integer(buf, &mut new_size, 5)?;
if new_size > self.max_dynamic_size {
return Err(DecoderError::InvalidMaxDynamicSize)
} else {
self.table.update_max_dynamic_size(new_size);
}
buf.drain(0..total);
Ok(total)
}
}
impl<'a> Default for Decoder<'a> {
fn default() -> Self {
let table = Table::default();
Self {
speed: DecoderSpeed::FiveBits, max_dynamic_size: table.max_dynamic_size(),
table,
}
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn decodes_indexed() {
let mut decoder = Decoder::default();
let mut dst = Vec::new();
let mut buf = vec![
0x80 | 2, 0x80 | 14, ];
decoder.decode(&mut buf, &mut dst).unwrap();
assert_eq!(dst, vec![
(b":method".to_vec(), b"GET".to_vec(), 0x0),
(b":status".to_vec(), b"500".to_vec(), 0x0),
]);
}
#[test]
fn decodes_indexed_name_with_indexing() {
let mut decoder = Decoder::default();
let mut dst = Vec::new();
let mut buf = vec![
66, 133, 215, 14, 251, 216, 255, 78, 130, 108, 1 ];
decoder.decode(&mut buf, &mut dst).unwrap();
assert_eq!(dst, vec![
(b":method".to_vec(), b"PATCH".to_vec(), 0x4), (b":status".to_vec(), b"501".to_vec(), 0x4), ]);
assert_eq!(decoder.table.len(), 63); }
#[test]
fn decodes_literal_with_indexing() {
let mut decoder = Decoder::default();
let mut dst = Vec::new();
let mut buf = vec![
64, 131, 148, 231, 7, 131, 148, 231, 15, 64, 131, 140, 118, 3, 131, 140, 118, 7 ];
decoder.decode(&mut buf, &mut dst).unwrap();
assert_eq!(dst, vec![
(b"foo0".to_vec(), b"foo1".to_vec(), 0x4), (b"bar0".to_vec(), b"bar1".to_vec(), 0x4), ]);
assert_eq!(decoder.table.len(), 63); }
#[test]
fn decodes_indexed_name_without_indexing() {
let mut decoder = Decoder::default();
let mut dst = Vec::new();
let mut buf = vec![
2, 5, 80, 65, 84, 67, 72, 14, 130, 108, 1 ];
decoder.decode(&mut buf, &mut dst).unwrap();
assert_eq!(dst, vec![
(b":method".to_vec(), b"PATCH".to_vec(), 0x0), (b":status".to_vec(), b"501".to_vec(), 0x0), ]);
assert_eq!(decoder.table.len(), 61); }
#[test]
fn decodes_literal_without_indexing() {
let mut decoder = Decoder::default();
let mut dst = Vec::new();
let mut buf = vec![
0, 4, 102, 111, 111, 48, 4, 98, 97, 114, 48, 0, 131, 148, 231, 15, 131, 140, 118, 7 ];
decoder.decode(&mut buf, &mut dst).unwrap();
assert_eq!(dst, vec![
(b"foo0".to_vec(), b"bar0".to_vec(), 0x0), (b"foo1".to_vec(), b"bar1".to_vec(), 0x0), ]);
assert_eq!(decoder.table.len(), 61); }
#[test]
fn decodes_indexed_name_never_indexed() {
let mut decoder = Decoder::default();
let mut dst = Vec::new();
let mut buf = vec![
18, 5, 80, 65, 84, 67, 72, 30, 130, 108, 1 ];
decoder.decode(&mut buf, &mut dst).unwrap();
assert_eq!(dst, vec![
(b":method".to_vec(), b"PATCH".to_vec(), 0x8), (b":status".to_vec(), b"501".to_vec(), 0x8), ]);
assert_eq!(decoder.table.len(), 61); }
#[test]
fn decodes_literal_never_indexed() {
let mut decoder = Decoder::default();
let mut dst = Vec::new();
let mut buf = vec![
16, 4, 102, 111, 111, 48, 4, 98, 97, 114, 48, 16, 4, 102, 111, 111, 49, 4, 98, 97, 114, 49 ];
decoder.decode(&mut buf, &mut dst).unwrap();
assert_eq!(dst, vec![
(b"foo0".to_vec(), b"bar0".to_vec(), 0x8), (b"foo1".to_vec(), b"bar1".to_vec(), 0x8), ]);
assert_eq!(decoder.table.len(), 61); }
#[test]
fn decodes_exact() {
let mut decoder = Decoder::default();
let mut dst = Vec::with_capacity(1);
let mut buf = vec![
0x80 | 2, 0x80 | 14, ];
decoder.decode_exact(&mut buf, &mut dst).unwrap();
assert_eq!(dst.len(), 1);
}
#[test]
fn decodes_max_dynamic_size() {
let mut decoder = Decoder::with_dynamic_size(70);
decoder.table.insert(b"a".to_vec(), b"a".to_vec()); decoder.table.insert(b"b".to_vec(), b"b".to_vec()); let mut dst = Vec::new();
decoder.decode(&mut vec![63, 19], &mut dst).unwrap(); assert_eq!(dst, vec![]); assert_eq!(decoder.table.max_dynamic_size(), 50); assert_eq!(decoder.table.dynamic_len(), 1); }
}