QPACK: decoder instructions

This commit is contained in:
stammw
2019-01-21 07:31:53 +01:00
committed by Dirkjan Ochtman
parent d76cf81de2
commit bdf1ffc6ee
3 changed files with 115 additions and 30 deletions
+15 -15
View File
@@ -17,8 +17,8 @@ use super::bloc::{
LiteralWithPostBaseNameRef,
};
use super::stream::{
Duplicate, DynamicTableSizeUpdate, InsertWithNameRef, InsertWithoutNameRef, InstructionType,
TableSizeSync,
Duplicate, DynamicTableSizeUpdate, EncoderInstruction, InsertCountIncrement, InsertWithNameRef,
InsertWithoutNameRef,
};
use super::ParseError;
@@ -119,7 +119,7 @@ pub fn on_encoder_recv<R: Buf, W: BufMut>(
if table.total_inserted() != inserted_on_start {
//TODO RENAME
TableSizeSync {
InsertCountIncrement {
insert_count: table.total_inserted() - inserted_on_start,
}
.encode(write);
@@ -138,18 +138,18 @@ fn parse_instruction<R: Buf>(
let mut buf = Cursor::new(read.bytes());
let first = buf.bytes()[0];
let instruction = match InstructionType::decode(first) {
InstructionType::Unknown => return Err(Error::UnknownPrefix),
InstructionType::DynamicTableSizeUpdate => {
let instruction = match EncoderInstruction::decode(first) {
EncoderInstruction::Unknown => return Err(Error::UnknownPrefix),
EncoderInstruction::DynamicTableSizeUpdate => {
DynamicTableSizeUpdate::decode(&mut buf)?.map(|x| Instruction::TableSizeUpdate(x.size))
}
InstructionType::InsertWithoutNameRef => InsertWithoutNameRef::decode(&mut buf)?
EncoderInstruction::InsertWithoutNameRef => InsertWithoutNameRef::decode(&mut buf)?
.map(|x| Instruction::Insert(HeaderField::new(x.name, x.value))),
InstructionType::Duplicate => match Duplicate::decode(&mut buf)? {
EncoderInstruction::Duplicate => match Duplicate::decode(&mut buf)? {
Some(Duplicate(index)) => Some(Instruction::Insert(table.get_relative(index)?.clone())),
None => None,
},
InstructionType::InsertWithNameRef => match InsertWithNameRef::decode(&mut buf)? {
EncoderInstruction::InsertWithNameRef => match InsertWithNameRef::decode(&mut buf)? {
Some(InsertWithNameRef::Static { index, value }) => Some(Instruction::Insert(
StaticTable::get(index)?.with_value(value),
)),
@@ -249,8 +249,8 @@ mod tests {
let mut dec_cursor = Cursor::new(&dec);
assert_eq!(
TableSizeSync::decode(&mut dec_cursor),
Ok(Some(TableSizeSync { insert_count: 1 }))
InsertCountIncrement::decode(&mut dec_cursor),
Ok(Some(InsertCountIncrement { insert_count: 1 }))
);
}
@@ -317,8 +317,8 @@ mod tests {
let mut dec_cursor = Cursor::new(&dec);
assert_eq!(
TableSizeSync::decode(&mut dec_cursor),
Ok(Some(TableSizeSync { insert_count: 1 }))
InsertCountIncrement::decode(&mut dec_cursor),
Ok(Some(InsertCountIncrement { insert_count: 1 }))
);
}
@@ -351,8 +351,8 @@ mod tests {
let mut dec_cursor = Cursor::new(&dec);
assert_eq!(
TableSizeSync::decode(&mut dec_cursor),
Ok(Some(TableSizeSync { insert_count: 1 }))
InsertCountIncrement::decode(&mut dec_cursor),
Ok(Some(InsertCountIncrement { insert_count: 1 }))
);
}
+2 -2
View File
@@ -16,8 +16,8 @@ use super::bloc::{
};
use super::prefix_string::Error as StringError;
use super::stream::{
Duplicate, DynamicTableSizeUpdate, InsertWithNameRef, InsertWithoutNameRef, InstructionType,
TableSizeSync,
Duplicate, DynamicTableSizeUpdate, EncoderInstruction, InsertCountIncrement, InsertWithNameRef,
InsertWithoutNameRef,
};
use super::table::{
DynamicInsertionResult, DynamicLookupResult, DynamicTable, DynamicTableEncoder,
+98 -13
View File
@@ -7,7 +7,7 @@ use super::prefix_string::{self, Error as StringError};
use super::table::field::HeaderField;
use super::ParseError;
pub enum InstructionType {
pub enum EncoderInstruction {
InsertWithNameRef,
InsertWithoutNameRef,
Duplicate,
@@ -15,18 +15,18 @@ pub enum InstructionType {
Unknown,
}
impl InstructionType {
impl EncoderInstruction {
pub fn decode(first: u8) -> Self {
if first & 0b1000_0000 != 0 {
InstructionType::InsertWithNameRef
EncoderInstruction::InsertWithNameRef
} else if first & 0b0100_0000 == 0b0100_0000 {
InstructionType::InsertWithoutNameRef
EncoderInstruction::InsertWithoutNameRef
} else if first & 0b1110_0000 == 0 {
InstructionType::Duplicate
EncoderInstruction::Duplicate
} else if first & 0b0010_0000 == 0b0010_0000 {
InstructionType::DynamicTableSizeUpdate
EncoderInstruction::DynamicTableSizeUpdate
} else {
InstructionType::Unknown
EncoderInstruction::Unknown
}
}
}
@@ -164,11 +164,33 @@ impl DynamicTableSizeUpdate {
}
#[derive(Debug, PartialEq)]
pub struct TableSizeSync {
pub enum DecoderInstruciton {
InsertCountIncrement,
HeaderAck,
StreamCancel,
Unknown,
}
impl DecoderInstruciton {
pub fn decode(first: u8) -> Self {
if first & 0b1100_0000 == 0 {
DecoderInstruciton::InsertCountIncrement
} else if first & 0b1000_0000 != 0 {
DecoderInstruciton::HeaderAck
} else if first & 0b0100_0000 == 0b0100_0000 {
DecoderInstruciton::StreamCancel
} else {
DecoderInstruciton::Unknown
}
}
}
#[derive(Debug, PartialEq)]
pub struct InsertCountIncrement {
pub insert_count: usize,
}
impl TableSizeSync {
impl InsertCountIncrement {
pub fn decode<R: Buf>(buf: &mut R) -> Result<Option<Self>, ParseError> {
let insert_count = match prefix_int::decode(6, buf) {
Ok((0b00, x)) => x,
@@ -176,7 +198,7 @@ impl TableSizeSync {
Err(IntError::UnexpectedEnd) => return Ok(None),
Err(e) => return Err(e.into()),
};
Ok(Some(TableSizeSync { insert_count }))
Ok(Some(InsertCountIncrement { insert_count }))
}
pub fn encode<W: BufMut>(&self, buf: &mut W) {
@@ -184,6 +206,48 @@ impl TableSizeSync {
}
}
#[derive(Debug, PartialEq)]
pub struct HeaderAck {
pub stream_id: u64,
}
impl HeaderAck {
pub fn decode<R: Buf>(buf: &mut R) -> Result<Option<Self>, ParseError> {
let stream_id = match prefix_int::decode(7, buf) {
Ok((0b1, x)) => x as u64,
Ok((f, _)) => return Err(ParseError::InvalidPrefix(f)),
Err(IntError::UnexpectedEnd) => return Ok(None),
Err(e) => return Err(e.into()),
};
Ok(Some(HeaderAck { stream_id }))
}
pub fn encode<W: BufMut>(&self, buf: &mut W) {
prefix_int::encode(7, 0b1, self.stream_id as usize, buf);
}
}
#[derive(Debug, PartialEq)]
pub struct StreamCancel {
pub stream_id: u64,
}
impl StreamCancel {
pub fn decode<R: Buf>(buf: &mut R) -> Result<Option<Self>, ParseError> {
let stream_id = match prefix_int::decode(6, buf) {
Ok((0b01, x)) => x as u64,
Ok((f, _)) => return Err(ParseError::InvalidPrefix(f)),
Err(IntError::UnexpectedEnd) => return Ok(None),
Err(e) => return Err(e.into()),
};
Ok(Some(StreamCancel { stream_id }))
}
pub fn encode<W: BufMut>(&self, buf: &mut W) {
prefix_int::encode(6, 0b01, self.stream_id as usize, buf);
}
}
#[cfg(test)]
mod test {
use super::*;
@@ -231,11 +295,32 @@ mod test {
}
#[test]
fn table_size_sync() {
let instruction = TableSizeSync { insert_count: 42 };
fn insert_count_increment() {
let instruction = InsertCountIncrement { insert_count: 42 };
let mut buf = vec![];
instruction.encode(&mut buf);
let mut read = Cursor::new(&buf);
assert_eq!(TableSizeSync::decode(&mut read), Ok(Some(instruction)));
assert_eq!(
InsertCountIncrement::decode(&mut read),
Ok(Some(instruction))
);
}
#[test]
fn header_ack() {
let instruction = HeaderAck { stream_id: 42 };
let mut buf = vec![];
instruction.encode(&mut buf);
let mut read = Cursor::new(&buf);
assert_eq!(HeaderAck::decode(&mut read), Ok(Some(instruction)));
}
#[test]
fn stream_cancel() {
let instruction = StreamCancel { stream_id: 42 };
let mut buf = vec![];
instruction.encode(&mut buf);
let mut read = Cursor::new(&buf);
assert_eq!(StreamCancel::decode(&mut read), Ok(Some(instruction)));
}
}