net_wire/http2/hpack/
context.rs1use super::decoder::{HpackBlockDecoder, HpackDecodeError};
9use super::encoder::{HpackBlockEncoder, HpackEncodeError};
10use super::table::HpackDynamicTable;
11
12#[derive(Clone, Copy, Debug, Default)]
13pub(super) struct PendingSizes {
14 minimum: Option<usize>,
15 final_size: Option<usize>,
16}
17
18impl PendingSizes {
19 pub(super) const fn next(self) -> Option<usize> {
20 match self.minimum {
21 Some(minimum) => Some(minimum),
22 None => self.final_size,
23 }
24 }
25
26 pub(super) fn advance(&mut self) {
27 if self.minimum.is_some() {
28 self.minimum = None;
29 } else {
30 self.final_size = None;
31 }
32 }
33
34 fn queue_initial(&mut self, table_maximum: usize, allowed: usize) {
35 if table_maximum > allowed {
36 self.minimum = Some(allowed);
37 }
38 }
39
40 fn record_change(&mut self, allowed: usize) {
41 match self.minimum {
42 None => {
43 self.minimum = Some(allowed);
44 self.final_size = None;
45 }
46 Some(minimum) if allowed <= minimum => {
47 self.minimum = Some(allowed);
48 self.final_size = None;
49 }
50 Some(minimum) => {
51 self.minimum = Some(minimum);
52 self.final_size = Some(allowed);
53 }
54 }
55 }
56}
57
58pub struct HpackEncoderContext<'storage, 'entries> {
62 pub(super) table: HpackDynamicTable<'storage, 'entries>,
63 allowed_maximum_size: usize,
64 pub(super) pending: PendingSizes,
65}
66
67impl<'storage, 'entries> HpackEncoderContext<'storage, 'entries> {
68 pub fn new(
70 table: HpackDynamicTable<'storage, 'entries>,
71 allowed_maximum_size: usize,
72 ) -> Result<Self, HpackEncodeError> {
73 if allowed_maximum_size > table.capacity() {
74 return Err(HpackEncodeError::AllowedMaximumExceedsCapacity {
75 allowed: allowed_maximum_size,
76 capacity: table.capacity(),
77 });
78 }
79 let mut pending = PendingSizes::default();
80 pending.queue_initial(table.maximum_size(), allowed_maximum_size);
81 Ok(Self {
82 table,
83 allowed_maximum_size,
84 pending,
85 })
86 }
87
88 pub const fn allowed_maximum_size(&self) -> usize {
90 self.allowed_maximum_size
91 }
92
93 pub const fn dynamic_table(&self) -> &HpackDynamicTable<'storage, 'entries> {
95 &self.table
96 }
97
98 pub const fn next_required_size_update(&self) -> Option<usize> {
100 self.pending.next()
101 }
102
103 pub fn set_allowed_maximum_size(&mut self, allowed: usize) -> Result<(), HpackEncodeError> {
105 if allowed > self.table.capacity() {
106 return Err(HpackEncodeError::AllowedMaximumExceedsCapacity {
107 allowed,
108 capacity: self.table.capacity(),
109 });
110 }
111 if allowed != self.allowed_maximum_size {
112 self.pending.record_change(allowed);
113 self.allowed_maximum_size = allowed;
114 }
115 Ok(())
116 }
117
118 pub fn begin_block(&mut self) -> HpackBlockEncoder<'_, 'storage, 'entries> {
120 HpackBlockEncoder::from_context(
121 &mut self.table,
122 &mut self.pending,
123 self.allowed_maximum_size,
124 )
125 }
126
127 pub fn into_dynamic_table(self) -> HpackDynamicTable<'storage, 'entries> {
129 self.table
130 }
131}
132
133pub struct HpackDecoderContext<'storage, 'entries> {
135 pub(super) table: HpackDynamicTable<'storage, 'entries>,
136 allowed_maximum_size: usize,
137 pub(super) pending: PendingSizes,
138}
139
140impl<'storage, 'entries> HpackDecoderContext<'storage, 'entries> {
141 pub fn new(
143 table: HpackDynamicTable<'storage, 'entries>,
144 allowed_maximum_size: usize,
145 ) -> Result<Self, HpackDecodeError> {
146 if allowed_maximum_size > table.capacity() {
147 return Err(HpackDecodeError::AllowedMaximumExceedsCapacity {
148 allowed: allowed_maximum_size,
149 capacity: table.capacity(),
150 });
151 }
152 let mut pending = PendingSizes::default();
153 pending.queue_initial(table.maximum_size(), allowed_maximum_size);
154 Ok(Self {
155 table,
156 allowed_maximum_size,
157 pending,
158 })
159 }
160
161 pub const fn allowed_maximum_size(&self) -> usize {
163 self.allowed_maximum_size
164 }
165
166 pub const fn dynamic_table(&self) -> &HpackDynamicTable<'storage, 'entries> {
168 &self.table
169 }
170
171 pub const fn next_required_size_update(&self) -> Option<usize> {
173 self.pending.next()
174 }
175
176 pub fn set_allowed_maximum_size(&mut self, allowed: usize) -> Result<(), HpackDecodeError> {
178 if allowed > self.table.capacity() {
179 return Err(HpackDecodeError::AllowedMaximumExceedsCapacity {
180 allowed,
181 capacity: self.table.capacity(),
182 });
183 }
184 if allowed != self.allowed_maximum_size {
185 self.pending.record_change(allowed);
186 self.allowed_maximum_size = allowed;
187 }
188 Ok(())
189 }
190
191 pub fn decode_block<'block>(
193 &mut self,
194 block: &'block [u8],
195 ) -> HpackBlockDecoder<'block, '_, 'storage, 'entries> {
196 HpackBlockDecoder::from_context(
197 block,
198 &mut self.table,
199 &mut self.pending,
200 self.allowed_maximum_size,
201 )
202 }
203
204 pub fn into_dynamic_table(self) -> HpackDynamicTable<'storage, 'entries> {
206 self.table
207 }
208}