From ca92f2fa00bc8888dfc9e3bf3740fb09cfb7fa5e Mon Sep 17 00:00:00 2001 From: stammw Date: Sun, 13 Jan 2019 08:13:57 +0100 Subject: [PATCH] QPACK: retreive static index from name or name+value --- quinn-h3/src/qpack/table/field.rs | 2 +- quinn-h3/src/qpack/table/static_.rs | 80 +++++++++++++++++------------ 2 files changed, 48 insertions(+), 34 deletions(-) diff --git a/quinn-h3/src/qpack/table/field.rs b/quinn-h3/src/qpack/table/field.rs index 1df9d7abf..f3af9259b 100644 --- a/quinn-h3/src/qpack/table/field.rs +++ b/quinn-h3/src/qpack/table/field.rs @@ -10,7 +10,7 @@ use std::borrow::Cow; */ pub const ESTIMATED_OVERHEAD_BYTES: usize = 32; -#[derive(Debug, PartialEq, Clone)] +#[derive(Debug, PartialEq, Clone, Hash, Eq)] pub struct HeaderField { pub name: Cow<'static, [u8]>, pub value: Cow<'static, [u8]>, diff --git a/quinn-h3/src/qpack/table/static_.rs b/quinn-h3/src/qpack/table/static_.rs index 677be8d35..b35cf6ca5 100644 --- a/quinn-h3/src/qpack/table/static_.rs +++ b/quinn-h3/src/qpack/table/static_.rs @@ -7,6 +7,34 @@ use std::collections::HashMap; use super::field::HeaderField; +#[derive(Debug, PartialEq)] +pub enum Error { + Unknown(usize), +} + +pub struct StaticTable {} + +impl StaticTable { + pub fn get(index: usize) -> Result<&'static HeaderField, Error> { + match PREDEFINED_HEADERS.get(index) { + Some(f) => Ok(f), + None => Err(Error::Unknown(index)), + } + } + + pub fn count() -> usize { + PREDEFINED_HEADERS.len() + } + + pub fn find(field: &HeaderField) -> Option { + PREDEFINED_HEADERS_MAP.get(field).map(|i| *i) + } + + pub fn find_name(name: &[u8]) -> Option { + PREDEFINED_HEADERS_NAME_MAP.get(name).map(|i| *i) + } +} + #[allow(unused_macros)] macro_rules! decl_fields { [ $( ($key:expr, $value:expr) ),* ] => { @@ -132,36 +160,16 @@ const PREDEFINED_HEADERS: [HeaderField; 99] = decl_fields![ ]; lazy_static! { - static ref PREDEFINED_HEADERS_MAP: HashMap, (usize, &'static HeaderField)> = - PREDEFINED_HEADERS - .iter() - .enumerate() - .map(|(idx, field)| (field.name.clone(), (idx, field))) - .collect(); -} - -#[derive(Debug, PartialEq)] -pub enum Error { - Unknown(usize), -} - -pub struct StaticTable {} - -impl StaticTable { - pub fn get(index: usize) -> Result<&'static HeaderField, Error> { - match PREDEFINED_HEADERS.get(index) { - Some(f) => Ok(f), - None => Err(Error::Unknown(index)), - } - } - - pub fn count() -> usize { - PREDEFINED_HEADERS.len() - } - - pub fn find(name: &[u8]) -> Option<&'static (usize, &'static HeaderField)> { - PREDEFINED_HEADERS_MAP.get(name) - } + static ref PREDEFINED_HEADERS_NAME_MAP: HashMap, usize> = PREDEFINED_HEADERS + .iter() + .enumerate() + .map(|(idx, field)| (field.name.clone(), idx)) + .collect(); + static ref PREDEFINED_HEADERS_MAP: HashMap<&'static HeaderField, usize> = PREDEFINED_HEADERS + .iter() + .enumerate() + .map(|(idx, field)| (field, idx)) + .collect(); } #[cfg(test)] @@ -200,10 +208,16 @@ mod tests { #[test] fn find_by_name() { + assert_eq!(StaticTable::find_name(b"last-modified"), Some(10usize)); + assert_eq!(StaticTable::find_name(b"does-not-exist"), None); + } + + #[test] + fn find() { assert_eq!( - StaticTable::find(b"last-modified"), - Some(&(10usize, &HeaderField::new("last-modified", ""))) + StaticTable::find(&HeaderField::new(":method", "GET")), + Some(17usize) ); - assert_eq!(StaticTable::find(b"does-not-exist"), None); + assert_eq!(StaticTable::find(&HeaderField::new("foo", "bar")), None); } }