1use std::fmt;
2
3#[cfg(feature = "async")]
4use std::task::Waker;
5
6use bytes::{Buf, Bytes, BytesMut};
7use memchr::memmem;
8
9use crate::{
10 utils::{CRLF, CRLFS, DASHES},
11 Limits,
12};
13
14#[derive(Debug, PartialEq)]
15pub(crate) enum Flag {
16 Delimiting(bool),
17 Heading(usize),
18 Headed,
19 Header,
20 Next,
21 Eof,
22}
23
24pub struct State<T> {
26 io: T,
27 pub(crate) eof: bool,
28 pub(crate) flag: Flag,
29 pub(crate) length: u64,
30 pub(crate) buffer: BytesMut,
31 delimiter: Bytes,
32 pub(crate) is_readable: bool,
33 #[cfg(feature = "async")]
34 waker: Option<Waker>,
35 pub(crate) total: usize,
36 pub(crate) files: usize,
37 pub(crate) fields: usize,
38 pub(crate) limits: Limits,
39}
40
41impl<T> State<T> {
42 pub fn new(io: T, boundary: &[u8], limits: Limits) -> Self {
44 let mut delimiter = BytesMut::with_capacity(4 + boundary.len());
46 delimiter.extend_from_slice(&CRLF);
47 delimiter.extend_from_slice(&DASHES);
48 delimiter.extend_from_slice(boundary);
49
50 let mut buffer = BytesMut::with_capacity(limits.buffer_size);
52 buffer.extend_from_slice(&CRLF);
53
54 Self {
55 io,
56 limits,
57 total: 0,
58 files: 0,
59 fields: 0,
60 length: 0,
61
62 #[cfg(feature = "async")]
63 waker: None,
64 eof: false,
65 is_readable: false,
66
67 buffer,
68 flag: Flag::Delimiting(false),
69 delimiter: delimiter.freeze(),
70 }
71 }
72
73 pub fn io_mut(&mut self) -> &mut T {
75 &mut self.io
76 }
77
78 #[cfg(feature = "async")]
80 pub fn waker(&self) -> Option<&Waker> {
81 self.waker.as_ref()
82 }
83
84 #[cfg(feature = "async")]
86 pub fn waker_mut(&mut self) -> &mut Option<Waker> {
87 &mut self.waker
88 }
89
90 pub fn limits_mut(&mut self) -> &mut Limits {
92 &mut self.limits
93 }
94
95 pub fn split_buffer(&mut self, n: usize) -> Bytes {
97 self.buffer.split_to(n).freeze()
98 }
99
100 pub fn index(&mut self) -> usize {
102 let index = self.total;
103 self.total += 1;
104 index
105 }
106
107 pub fn len(&self) -> u64 {
109 self.length
110 }
111
112 pub fn is_empty(&self) -> bool {
114 self.length == 0
115 }
116
117 pub fn eof(&self) -> bool {
119 self.eof
120 }
121
122 pub fn total(&self) -> usize {
124 self.total
125 }
126
127 pub fn boundary(&self) -> &[u8] {
129 &self.delimiter[4..]
130 }
131
132 pub(crate) fn decode(&mut self) -> Option<Bytes> {
133 if let Flag::Delimiting(boding) = self.flag {
134 if let Some(n) = memmem::find(&self.buffer, &self.delimiter) {
135 self.flag = Flag::Heading(n);
136 } else {
137 if self.eof && self.buffer.len() == 2 && self.buffer[..2] == CRLF {
139 self.buffer.advance(2);
140 self.flag = Flag::Eof;
141 return None;
142 }
143
144 if memmem::find(&self.buffer, &self.delimiter[2..]).is_some() {
146 self.flag = Flag::Next;
147 self.buffer.advance(self.delimiter.len() - 2);
148 return None;
149 }
150
151 if boding {
153 if self.limits.buffer_size + self.delimiter.len() < self.buffer.len() {
155 return Some(self.buffer.split_to(self.limits.buffer_size).freeze());
156 }
157 }
158 }
159 }
160
161 if let Flag::Heading(ref mut n) = self.flag {
162 if self.total == 0 {
164 if *n > 0 {
165 self.buffer.advance(*n);
167 }
168 self.buffer.advance(self.delimiter.len());
169 self.flag = Flag::Headed;
170 } else {
171 if *n == 0 {
173 self.flag = Flag::Next;
175 self.buffer.advance(self.delimiter.len());
176 return None;
177 }
178 let buf = self.buffer.split_to(*n).freeze();
180 *n = 0;
181 return Some(buf);
182 }
183 }
184
185 if Flag::Next == self.flag {
186 self.flag = Flag::Headed;
187 }
188
189 if Flag::Headed == self.flag && self.buffer.len() > 1 {
190 if self.buffer[..2] == CRLF {
191 self.buffer.advance(2);
192 self.flag = Flag::Header;
193 } else if self.buffer[..2] == DASHES {
194 self.buffer.advance(2);
195 self.flag = Flag::Eof;
196 return None;
197 } else {
198 self.length -= (self.delimiter.len() - 2) as u64;
200 self.flag = Flag::Eof;
201 return None;
202 }
203 }
204
205 if Flag::Header == self.flag {
206 if let Some(n) = memmem::find(&self.buffer, &CRLFS) {
207 self.flag = Flag::Delimiting(true);
208 return Some(self.buffer.split_to(n + CRLFS.len()).freeze());
209 }
210 }
211
212 None
213 }
214}
215
216impl<T> fmt::Debug for State<T> {
217 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
218 f.debug_struct("State")
219 .field("eof", &self.eof)
220 .field("flag", &self.flag)
221 .field("total", &self.total)
222 .field("files", &self.files)
223 .field("fields", &self.fields)
224 .field("length", &self.length)
225 .field("limits", &self.limits)
226 .field("is_readable", &self.is_readable)
227 .field("boundary", &String::from_utf8_lossy(self.boundary()))
228 .finish_non_exhaustive()
229 }
230}