sark_http/field/metadata/
strings.rs1use o3::buffer::write;
4
5use crate::field::metadata::huffman::decoder;
6
7#[repr(u8)]
8#[derive(Clone, Copy, PartialEq, Eq)]
9pub enum Encoding {
10 Plain,
11 Huffman,
12}
13
14#[repr(u8)]
15#[derive(Clone, Copy, PartialEq, Eq)]
16pub enum Completion {
17 Pending,
18 Complete,
19}
20
21#[derive(Clone, Copy, PartialEq, Eq)]
22enum State {
23 Plain,
24 Huffman(decoder::Decoder),
25}
26
27#[derive(Clone, Copy, PartialEq, Eq)]
28pub struct Cursor {
29 remaining: usize,
30 decoded_len: u32,
31 state: State,
32}
33
34#[derive(Clone, Copy, PartialEq, Eq)]
35pub struct Progress {
36 consumed: usize,
37 decoded: usize,
38}
39
40impl Cursor {
41 pub const fn new(len: usize, encoding: Encoding) -> Self {
42 Self {
43 remaining: len,
44 decoded_len: 0,
45 state: match encoding {
46 Encoding::Plain => State::Plain,
47 Encoding::Huffman => State::Huffman(decoder::Decoder::new()),
48 },
49 }
50 }
51
52 pub const fn remaining(&self) -> usize {
53 self.remaining
54 }
55
56 pub const fn decoded_len(&self) -> usize {
57 self.decoded_len as usize
58 }
59
60 pub const fn completion(&self) -> Completion {
61 if self.remaining == 0 {
62 Completion::Complete
63 } else {
64 Completion::Pending
65 }
66 }
67
68 pub fn output_bound(&self, input: usize) -> Result<usize, decoder::Error> {
69 let consumed = input.min(self.remaining);
70 match self.state {
71 State::Huffman(_) => consumed.checked_mul(2).ok_or(decoder::Error),
72 State::Plain => Ok(consumed),
73 }
74 }
75
76 pub fn feed_count(&mut self, input: &[u8]) -> Result<Progress, decoder::Error> {
77 let consumed = input.len().min(self.remaining);
78 let payload = &input[..consumed];
79 let (state, decoded) = match self.state {
80 State::Huffman(decoder) => {
81 let (next, decoded) = decoder.feed_count(payload)?;
82 (State::Huffman(next), decoded)
83 }
84 State::Plain => (State::Plain, consumed),
85 };
86 self.advance(consumed, decoded, state)
87 }
88
89 pub fn feed_into<W: write::Sink>(
90 &mut self,
91 input: &[u8],
92 sink: W,
93 ) -> Result<(Progress, W), decoder::Failure<W, W::Error>> {
94 let consumed = input.len().min(self.remaining);
95 let payload = &input[..consumed];
96 let (state, sink, decoded) = match self.state {
97 State::Huffman(decoder) => {
98 let (next, sink, decoded) = decoder.feed_into(payload, sink)?.into_parts();
99 (State::Huffman(next), sink, decoded)
100 }
101 State::Plain => {
102 let mut sink = sink;
103 sink = match write::Sink::write_slice(&mut sink, payload) {
104 Ok(()) => Ok(sink),
105 Err(cause) => Err(decoder::Failure {
106 sink,
107 cause: decoder::DecodeError::Sink(cause),
108 progress: decoder::Progress::new(0, 0),
109 }),
110 }?;
111 (State::Plain, sink, consumed)
112 }
113 };
114 let progress = match self.advance(consumed, decoded, state) {
115 Ok(progress) => progress,
116 Err(cause) => {
117 return Err(decoder::Failure {
118 sink,
119 cause: decoder::DecodeError::InvalidEncoding(cause),
120 progress: decoder::Progress::new(consumed, decoded),
121 });
122 }
123 };
124 Ok((progress, sink))
125 }
126
127 pub fn finish(self) -> Result<usize, decoder::Error> {
128 if self.remaining != 0 {
129 return Err(decoder::Error);
130 }
131 match self.state {
132 State::Huffman(decoder) => decoder.finish()?,
133 State::Plain => {}
134 }
135 Ok(self.decoded_len())
136 }
137 fn advance(
138 &mut self,
139 consumed: usize,
140 decoded: usize,
141 state: State,
142 ) -> Result<Progress, decoder::Error> {
143 if decoded > u32::MAX as usize {
144 return Err(decoder::Error);
145 }
146 let decoded = decoded as u32;
147 let total = self
148 .decoded_len
149 .checked_add(decoded)
150 .ok_or(decoder::Error)?;
151 self.remaining -= consumed;
152 self.decoded_len = total;
153 self.state = state;
154 Ok(Progress {
155 consumed,
156 decoded: decoded as usize,
157 })
158 }
159}
160
161impl Progress {
162 pub const fn consumed(self) -> usize {
163 self.consumed
164 }
165
166 pub const fn decoded(self) -> usize {
167 self.decoded
168 }
169}
170
171const _: () = {
172 assert!(core::mem::size_of::<Encoding>() == core::mem::size_of::<bool>());
173 assert!(core::mem::size_of::<Completion>() == core::mem::size_of::<bool>());
174 assert!(core::mem::size_of::<State>() == core::mem::size_of::<Option<decoder::Decoder>>());
175 assert!(core::mem::align_of::<State>() == core::mem::align_of::<Option<decoder::Decoder>>());
176};