summaryrefslogtreecommitdiffstats
path: root/third_party/rust/neqo-qpack/src/prefix.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/neqo-qpack/src/prefix.rs')
-rw-r--r--third_party/rust/neqo-qpack/src/prefix.rs143
1 files changed, 143 insertions, 0 deletions
diff --git a/third_party/rust/neqo-qpack/src/prefix.rs b/third_party/rust/neqo-qpack/src/prefix.rs
new file mode 100644
index 0000000000..0085de0df9
--- /dev/null
+++ b/third_party/rust/neqo-qpack/src/prefix.rs
@@ -0,0 +1,143 @@
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[derive(Copy, Clone, Debug)]
+pub struct Prefix {
+ #[allow(unknown_lints)] // available with Rust v1.75
+ #[allow(clippy::struct_field_names)]
+ prefix: u8,
+ len: u8,
+ mask: u8,
+}
+
+impl Prefix {
+ pub fn new(prefix: u8, len: u8) -> Self {
+ // len should never be larger than 7.
+ // Most of Prefixes are instantiated as consts bellow. The only place where this
+ // construcrtor is used is in tests and when literals are encoded and the Huffman
+ // bit is added to one of the consts bellow. create_prefix guaranty that all const
+ // have len < 7 so we can safely assert that len is <=7.
+ assert!(len <= 7);
+ assert!((len == 0) || (prefix & ((1 << (8 - len)) - 1) == 0));
+ Self {
+ prefix,
+ len,
+ mask: if len == 0 {
+ 0xFF
+ } else {
+ ((1 << len) - 1) << (8 - len)
+ },
+ }
+ }
+
+ pub fn len(self) -> u8 {
+ self.len
+ }
+
+ pub fn prefix(self) -> u8 {
+ self.prefix
+ }
+
+ pub fn cmp_prefix(self, b: u8) -> bool {
+ (b & self.mask) == self.prefix
+ }
+}
+
+#[macro_export]
+macro_rules! create_prefix {
+ ($n:ident) => {
+ pub const $n: Prefix = Prefix {
+ prefix: 0x0,
+ len: 0,
+ mask: 0xFF,
+ };
+ };
+ ($n:ident, $v:expr, $l:expr) => {
+ static_assertions::const_assert!($l < 7);
+ static_assertions::const_assert!($v & ((1 << (8 - $l)) - 1) == 0);
+ pub const $n: Prefix = Prefix {
+ prefix: $v,
+ len: $l,
+ mask: ((1 << $l) - 1) << (8 - $l),
+ };
+ };
+ ($n:ident, $v:expr, $l:expr, $m:expr) => {
+ static_assertions::const_assert!($l < 7);
+ static_assertions::const_assert!($v & ((1 << (8 - $l)) - 1) == 0);
+ static_assertions::const_assert!((((1 << $l) - 1) << (8 - $l)) >= $m);
+ pub const $n: Prefix = Prefix {
+ prefix: $v,
+ len: $l,
+ mask: $m,
+ };
+ };
+}
+
+create_prefix!(NO_PREFIX);
+//=====================================================================
+// Decoder instructions prefix
+//=====================================================================
+
+// | 1 | Stream ID (7+) |
+create_prefix!(DECODER_HEADER_ACK, 0x80, 1);
+
+// | 0 | 1 | Stream ID (6+) |
+create_prefix!(DECODER_STREAM_CANCELLATION, 0x40, 2);
+
+// | 0 | 0 | Increment (6+) |
+create_prefix!(DECODER_INSERT_COUNT_INCREMENT, 0x00, 2);
+
+//=====================================================================
+// Encoder instructions prefix
+//=====================================================================
+
+// | 0 | 0 | 1 | Capacity (5+) |
+create_prefix!(ENCODER_CAPACITY, 0x20, 3);
+
+// | 1 | T | Name Index (6+) |
+// T == 1 static
+// T == 0 dynamic
+create_prefix!(ENCODER_INSERT_WITH_NAME_REF_STATIC, 0xC0, 2);
+create_prefix!(ENCODER_INSERT_WITH_NAME_REF_DYNAMIC, 0x80, 2);
+
+// | 0 | 1 | H | Name Length (5+) |
+// H is not relevant for decoding this prefix, therefore the mask is 1100 0000 = 0xC0
+create_prefix!(ENCODER_INSERT_WITH_NAME_LITERAL, 0x40, 2);
+
+// | 0 | 0 | 0 | Index (5+) |
+create_prefix!(ENCODER_DUPLICATE, 0x00, 3);
+
+//=====================================================================
+// Header block encoding prefixes
+//=====================================================================
+
+create_prefix!(BASE_PREFIX_POSITIVE, 0x00, 1);
+create_prefix!(BASE_PREFIX_NEGATIVE, 0x80, 1);
+
+// | 1 | T | index(6+) |
+// T == 1 static
+// T == 0 dynamic
+create_prefix!(HEADER_FIELD_INDEX_STATIC, 0xC0, 2);
+create_prefix!(HEADER_FIELD_INDEX_DYNAMIC, 0x80, 2);
+
+// | 0 | 0 | 0 | 1 | Index(4+) |
+create_prefix!(HEADER_FIELD_INDEX_DYNAMIC_POST, 0x10, 4);
+
+// | 0 | 1 | N | T | Index(4+) |
+// T == 1 static
+// T == 0 dynamic
+// N is ignored, therefore the mask is 1101 0000 = 0xD0
+create_prefix!(HEADER_FIELD_LITERAL_NAME_REF_STATIC, 0x50, 4, 0xD0);
+create_prefix!(HEADER_FIELD_LITERAL_NAME_REF_DYNAMIC, 0x40, 4, 0xD0);
+
+// | 0 | 0 | 0 | 0 | N | Index(3+) |
+// N is ignored, therefore the mask is 1111 0000 = 0xF0
+create_prefix!(HEADER_FIELD_LITERAL_NAME_REF_DYNAMIC_POST, 0x00, 5, 0xF0);
+
+// | 0 | 0 | 1 | N | H | Index(3+) |
+// N is ignored and H is not relevant for decoding this prefix, therefore the mask is 1110 0000 =
+// 0xE0
+create_prefix!(HEADER_FIELD_LITERAL_NAME_LITERAL, 0x20, 4, 0xE0);