net_wire/qpack/field/section/
prefix.rs1use core::fmt;
4
5use crate::qpack::integer::{
6 QPACK_INTEGER_MAX, QpackInteger, QpackIntegerBuildError, QpackIntegerParseError,
7 canonical_encoded_len, integer_from_prevalidated, write_canonical_prevalidated,
8};
9
10#[derive(Clone, Copy, Debug, Eq, PartialEq)]
12pub struct QpackFieldSectionPrefix<'a> {
13 bytes: &'a [u8],
14 encoded_required_insert_count: QpackInteger<'a>,
15 negative: bool,
16 delta_base: QpackInteger<'a>,
17}
18
19impl<'a> QpackFieldSectionPrefix<'a> {
20 pub fn parse(bytes: &'a [u8]) -> Result<Self, QpackFieldSectionPrefixParseError> {
22 let encoded_required_insert_count = QpackInteger::parse(bytes, 8)
23 .map_err(QpackFieldSectionPrefixParseError::RequiredInsertCount)?;
24 let required_insert_count_len = encoded_required_insert_count.as_bytes().len();
25 let delta_bytes = &bytes[required_insert_count_len..];
26 let delta_base = QpackInteger::parse(delta_bytes, 7)
27 .map_err(QpackFieldSectionPrefixParseError::DeltaBase)?;
28 let length = required_insert_count_len
29 .checked_add(delta_base.as_bytes().len())
30 .ok_or(QpackFieldSectionPrefixParseError::LengthOverflow)?;
31 Ok(Self {
32 bytes: &bytes[..length],
33 encoded_required_insert_count,
34 negative: delta_base.high_bits() & 0x80 != 0,
35 delta_base,
36 })
37 }
38
39 pub const fn as_bytes(self) -> &'a [u8] {
41 self.bytes
42 }
43 pub const fn encoded_required_insert_count(self) -> QpackInteger<'a> {
45 self.encoded_required_insert_count
46 }
47 pub const fn is_negative(self) -> bool {
49 self.negative
50 }
51 pub const fn delta_base(self) -> QpackInteger<'a> {
53 self.delta_base
54 }
55}
56
57#[derive(Clone, Copy, Debug, Eq, PartialEq)]
59pub enum QpackFieldSectionPrefixParseError {
60 RequiredInsertCount(
62 #[doc = "The nested Required Insert Count failure."] QpackIntegerParseError,
63 ),
64 DeltaBase(#[doc = "The nested Delta Base failure."] QpackIntegerParseError),
66 LengthOverflow,
68}
69impl fmt::Display for QpackFieldSectionPrefixParseError {
70 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
71 match self {
72 Self::RequiredInsertCount(error) => {
73 write!(f, "QPACK Encoded Required Insert Count is invalid: {error}")
74 }
75 Self::DeltaBase(error) => write!(f, "QPACK Delta Base is invalid: {error}"),
76 Self::LengthOverflow => {
77 f.write_str("QPACK field-section prefix length overflows usize")
78 }
79 }
80 }
81}
82impl core::error::Error for QpackFieldSectionPrefixParseError {}
83
84#[derive(Clone, Copy)]
86pub(crate) struct QpackFieldSectionPrefixPlan {
87 encoded_required_insert_count: u64,
88 negative: bool,
89 delta_base: u64,
90 required_insert_count_len: usize,
91 encoded_len: usize,
92}
93impl QpackFieldSectionPrefixPlan {
94 pub(crate) const fn encoded_len(self) -> usize {
96 self.encoded_len
97 }
98 pub(crate) fn write(self, destination: &mut [u8]) {
100 if destination.len() != self.encoded_len {
101 return;
102 }
103 let (ric, delta) = destination.split_at_mut(self.required_insert_count_len);
104 write_canonical_prevalidated(ric, 8, 0, self.encoded_required_insert_count);
105 write_canonical_prevalidated(
106 delta,
107 7,
108 if self.negative { 0x80 } else { 0 },
109 self.delta_base,
110 );
111 }
112}
113
114pub(crate) fn plan_field_section_prefix(
116 encoded_required_insert_count: u64,
117 negative: bool,
118 delta_base: u64,
119) -> Result<QpackFieldSectionPrefixPlan, QpackFieldSectionPrefixBuildError> {
120 if encoded_required_insert_count > QPACK_INTEGER_MAX {
121 return Err(QpackFieldSectionPrefixBuildError::RequiredInsertCount(
122 QpackIntegerBuildError::ValueTooLarge {
123 value: encoded_required_insert_count,
124 },
125 ));
126 }
127 if delta_base > QPACK_INTEGER_MAX {
128 return Err(QpackFieldSectionPrefixBuildError::DeltaBase(
129 QpackIntegerBuildError::ValueTooLarge { value: delta_base },
130 ));
131 }
132 let required_insert_count_len = canonical_encoded_len(encoded_required_insert_count, 8);
133 let delta_base_len = canonical_encoded_len(delta_base, 7);
134 let encoded_len = required_insert_count_len
135 .checked_add(delta_base_len)
136 .ok_or(QpackFieldSectionPrefixBuildError::RequiredLengthOverflow)?;
137 Ok(QpackFieldSectionPrefixPlan {
138 encoded_required_insert_count,
139 negative,
140 delta_base,
141 required_insert_count_len,
142 encoded_len,
143 })
144}
145
146pub struct QpackFieldSectionPrefixBuilder<'a> {
148 destination: &'a mut [u8],
149 encoded_required_insert_count: u64,
150 negative: bool,
151 delta_base: u64,
152}
153impl<'a> QpackFieldSectionPrefixBuilder<'a> {
154 pub fn new(
156 destination: &'a mut [u8],
157 encoded_required_insert_count: u64,
158 negative: bool,
159 delta_base: u64,
160 ) -> Self {
161 Self {
162 destination,
163 encoded_required_insert_count,
164 negative,
165 delta_base,
166 }
167 }
168 pub fn build(self) -> Result<QpackFieldSectionPrefix<'a>, QpackFieldSectionPrefixBuildError> {
170 let plan = plan_field_section_prefix(
171 self.encoded_required_insert_count,
172 self.negative,
173 self.delta_base,
174 )?;
175 let required = plan.encoded_len();
176 if self.destination.len() < required {
177 return Err(QpackFieldSectionPrefixBuildError::BufferTooShort {
178 required,
179 available: self.destination.len(),
180 });
181 }
182 plan.write(&mut self.destination[..required]);
183 let bytes = &self.destination[..required];
184 let ric_len = plan.required_insert_count_len;
185 Ok(QpackFieldSectionPrefix {
186 bytes,
187 encoded_required_insert_count: integer_from_prevalidated(
188 &bytes[..ric_len],
189 8,
190 0,
191 self.encoded_required_insert_count,
192 ),
193 negative: self.negative,
194 delta_base: integer_from_prevalidated(
195 &bytes[ric_len..],
196 7,
197 if self.negative { 0x80 } else { 0 },
198 self.delta_base,
199 ),
200 })
201 }
202}
203
204#[derive(Clone, Copy, Debug, Eq, PartialEq)]
206pub enum QpackFieldSectionPrefixBuildError {
207 RequiredInsertCount(
209 #[doc = "The nested Required Insert Count failure."] QpackIntegerBuildError,
210 ),
211 DeltaBase(#[doc = "The nested Delta Base failure."] QpackIntegerBuildError),
213 RequiredLengthOverflow,
215 BufferTooShort {
217 required: usize,
219 available: usize,
221 },
222}
223impl fmt::Display for QpackFieldSectionPrefixBuildError {
224 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
225 match self {
226 Self::RequiredInsertCount(error) => write!(
227 f,
228 "QPACK Encoded Required Insert Count cannot be built: {error}"
229 ),
230 Self::DeltaBase(error) => write!(f, "QPACK Delta Base cannot be built: {error}"),
231 Self::RequiredLengthOverflow => {
232 f.write_str("QPACK field-section prefix length overflows usize")
233 }
234 Self::BufferTooShort {
235 required,
236 available,
237 } => write!(
238 f,
239 "QPACK field-section prefix buffer is too short: need {required} bytes, have {available}"
240 ),
241 }
242 }
243}
244impl core::error::Error for QpackFieldSectionPrefixBuildError {}