1use std::convert::From;
17use std::fmt::{Debug, Display, Formatter};
18
19#[derive(Copy, Clone, Eq, Ord, Hash, PartialOrd, PartialEq)]
21pub struct BlockInfo(pub u32);
22
23impl BlockInfo {
24 const MORE_FLAG: u32 = 0b1000;
25
26 pub const NUM_MAX: u32 = ((1 << 20) - 1);
28
29 const SZX_RESERVED: u8 = 0b0111;
30
31 pub const SZX_MAX: u8 = Self::SZX_RESERVED - 1;
33
34 pub fn new(num: u32, m: bool, szx: u8) -> Option<BlockInfo> {
36 if num > Self::NUM_MAX || szx > Self::SZX_MAX {
37 None
38 } else {
39 Some(BlockInfo((num << 4) + ((m as u32) << 3) + szx as u32))
40 }
41 }
42
43 #[inline]
45 pub fn num(&self) -> u32 {
46 self.0 >> 4
47 }
48
49 #[inline]
51 pub fn more_flag(&self) -> bool {
52 (self.0 & Self::MORE_FLAG) == Self::MORE_FLAG
53 }
54
55 #[inline]
57 pub fn szx(&self) -> u8 {
58 self.0 as u8 & 0b111
59 }
60
61 #[inline]
63 pub fn offset(&self) -> usize {
64 let val = self.0 as usize;
65 (val & !0xF) << (val & 0b0111)
66 }
67
68 #[inline]
70 pub fn len(&self) -> usize {
71 1 << (self.szx() as usize + 4)
72 }
73
74 pub fn is_max_block(&self) -> bool {
78 self.num() == Self::NUM_MAX
79 }
80
81 pub fn is_invalid(&self) -> bool {
83 (self.num() > Self::NUM_MAX) || self.szx() == Self::SZX_RESERVED
84 }
85
86 pub fn valid(self) -> Option<BlockInfo> {
88 if self.is_invalid() {
89 None
90 } else {
91 Some(self)
92 }
93 }
94
95 pub fn next(&self) -> Option<BlockInfo> {
97 if self.num() < Self::NUM_MAX {
98 BlockInfo(self.0 + 0x10).valid()
99 } else {
100 None
101 }
102 }
103
104 pub fn smaller(&self) -> Option<BlockInfo> {
106 let szx = self.szx();
107 if szx != Self::SZX_RESERVED && szx > 0 {
108 Self::new(self.num() * 2, self.more_flag(), szx - 1)
109 } else {
110 None
111 }
112 }
113
114 pub fn with_more_flag(&self) -> BlockInfo {
116 BlockInfo(self.0 | Self::MORE_FLAG)
117 }
118
119 pub fn without_more_flag(&self) -> BlockInfo {
121 BlockInfo(self.0 & !Self::MORE_FLAG)
122 }
123}
124
125impl From<u32> for BlockInfo {
126 fn from(x: u32) -> Self {
127 BlockInfo(x)
128 }
129}
130
131impl Default for BlockInfo {
132 fn default() -> Self {
134 BlockInfo(6)
135 }
136}
137
138impl Display for BlockInfo {
139 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
140 write!(
141 f,
142 "{}/{}/{}",
143 self.num(),
144 self.more_flag() as u8,
145 self.len()
146 )?;
147 if self.is_invalid() {
148 f.write_str("(!)")
149 } else {
150 Ok(())
151 }
152 }
153}
154
155impl Debug for BlockInfo {
156 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
157 write!(f, "BlockInfo(0x{:06X})", self.0)?;
158 Display::fmt(self, f)?;
159 f.write_str(")")
160 }
161}
162
163#[derive(Debug)]
168pub struct BlockReconstructor<F> {
169 next_block: BlockInfo,
170 is_finished: bool,
171 write: F,
172}
173
174impl<F: Default + std::io::Write> Default for BlockReconstructor<F> {
175 fn default() -> Self {
176 BlockReconstructor::new(F::default(), Default::default())
177 }
178}
179
180impl<F> BlockReconstructor<F>
181where
182 F: std::io::Write,
183{
184 pub fn new(write: F, next_block: BlockInfo) -> BlockReconstructor<F> {
186 BlockReconstructor {
187 next_block: next_block.without_more_flag(),
188 is_finished: false,
189 write,
190 }
191 }
192
193 pub fn next_block(&self) -> BlockInfo {
195 self.next_block
196 }
197
198 pub fn is_finished(&self) -> bool {
201 self.is_finished
202 }
203
204 pub fn into_inner(self) -> F {
206 self.write
207 }
208
209 pub fn feed(&mut self, block: BlockInfo, payload: &[u8]) -> Result<bool, ()> {
211 if self.is_finished {
212 return Ok(true);
213 }
214
215 if block.offset() < self.next_block.offset() {
216 return Ok(false);
218 }
219
220 if block.offset() > self.next_block.offset() {
221 return Err(());
223 }
224
225 if !block.more_flag() {
226 self.is_finished = true;
227 } else if block.len() > payload.len() {
228 return Err(());
230 } else if block.len() < payload.len() {
231 return Err(());
233 } else if let Some(next_block) = block.without_more_flag().next() {
234 self.next_block = next_block;
235 } else {
236 return Err(());
238 }
239
240 self.write.write_all(payload).map_err(|_| ())?;
241
242 Ok(self.is_finished)
243 }
244}
245
246#[cfg(test)]
247mod tests {
248 use super::*;
249
250 #[test]
251 fn defaults() {
252 let block = BlockInfo::default();
253 assert_eq!(false, block.more_flag());
254 assert_eq!(6, block.szx());
255 assert_eq!(0, block.num());
256 assert_eq!(1024, block.len());
257 assert_eq!(0, block.offset());
258 assert_eq!(false, block.is_max_block());
259 assert_eq!(false, block.is_invalid());
260 }
261
262 #[test]
263 fn next() {
264 let block = BlockInfo::default().next().unwrap();
265 assert_eq!(BlockInfo::default().more_flag(), block.more_flag());
266 assert_eq!(6, block.szx());
267 assert_eq!(1, block.num());
268 assert_eq!(1024, block.len());
269 assert_eq!(1024, block.offset());
270 assert_eq!(false, block.is_max_block());
271 assert_eq!(false, block.is_invalid());
272 }
273
274 #[test]
275 fn smaller() {
276 let block = BlockInfo::default().smaller().unwrap();
277 assert_eq!(BlockInfo::default().more_flag(), block.more_flag());
278 assert_eq!(5, block.szx());
279 assert_eq!(0, block.num());
280 assert_eq!(512, block.len());
281 assert_eq!(0, block.offset());
282 assert_eq!(false, block.is_max_block());
283 assert_eq!(false, block.is_invalid());
284 }
285
286 #[test]
287 fn next_smaller() {
288 let block = BlockInfo::default().next().unwrap().smaller().unwrap();
289 assert_eq!(BlockInfo::default().more_flag(), block.more_flag());
290 assert_eq!(5, block.szx());
291 assert_eq!(2, block.num());
292 assert_eq!(512, block.len());
293 assert_eq!(1024, block.offset());
294 assert_eq!(false, block.is_max_block());
295 assert_eq!(false, block.is_invalid());
296
297 let smaller = block.smaller().unwrap();
298 assert_eq!(256, smaller.len());
299 assert_eq!(block.offset(), smaller.offset());
300 }
301
302 #[test]
303 fn with_and_without_more_flag() {
304 let block = BlockInfo::default().without_more_flag();
305 assert_eq!(false, block.more_flag());
306 assert_eq!(6, block.szx());
307 assert_eq!(0, block.num());
308 assert_eq!(1024, block.len());
309 assert_eq!(0, block.offset());
310 assert_eq!(false, block.is_max_block());
311 assert_eq!(false, block.is_invalid());
312
313 let block = block.with_more_flag();
314 assert_eq!(true, block.more_flag());
315 assert_eq!(6, block.szx());
316 assert_eq!(0, block.num());
317 assert_eq!(1024, block.len());
318 assert_eq!(0, block.offset());
319 assert_eq!(false, block.is_max_block());
320 assert_eq!(false, block.is_invalid());
321 }
322
323 #[test]
324 fn check_next() {
325 let block = BlockInfo::new(BlockInfo::NUM_MAX - 1, true, 6).unwrap();
326 assert_eq!(true, block.more_flag());
327 assert_eq!(6, block.szx());
328 assert_eq!(BlockInfo::NUM_MAX - 1, block.num());
329 assert_eq!(1024, block.len());
330 assert_eq!(1073739776, block.offset());
331 assert_eq!(false, block.is_max_block());
332 assert_eq!(false, block.is_invalid());
333
334 let block = block.next().unwrap();
335
336 assert_eq!(true, block.more_flag());
337 assert_eq!(6, block.szx());
338 assert_eq!(BlockInfo::NUM_MAX, block.num());
339 assert_eq!(1024, block.len());
340 assert_eq!(1073739776 + 1024, block.offset());
341 assert_eq!(true, block.is_max_block());
342 assert_eq!(false, block.is_invalid());
343
344 assert_eq!(None, block.next());
345 }
346
347 #[test]
348 fn check_smaller() {
349 let block = BlockInfo::new(BlockInfo::NUM_MAX - 1, true, 6).unwrap();
350 assert_eq!(false, block.is_invalid());
351 assert_eq!(None, block.smaller());
352
353 let block = BlockInfo(0);
354 assert_eq!(false, block.is_invalid());
355 assert_eq!(None, block.smaller());
356 }
357
358 #[test]
359 fn validity() {
360 let block = BlockInfo(0);
361 assert_eq!(false, block.is_invalid());
362 assert_eq!(false, block.smaller().is_some());
363 assert_eq!(true, block.next().is_some());
364 assert_eq!(Some(block), block.valid());
365
366 let block = BlockInfo(1);
367 assert_eq!(false, block.is_invalid());
368 assert_eq!(true, block.smaller().is_some());
369 assert_eq!(true, block.next().is_some());
370 assert_eq!(Some(block), block.valid());
371
372 let block = BlockInfo(!0);
373 assert_eq!(true, block.is_invalid());
374 assert_eq!(None, block.smaller());
375 assert_eq!(None, block.next());
376 assert_eq!(None, block.valid());
377
378 let block = BlockInfo(BlockInfo::SZX_RESERVED as u32);
379 assert_eq!(true, block.is_invalid());
380 assert_eq!(None, block.smaller());
381 assert_eq!(None, block.next());
382 assert_eq!(None, block.valid());
383
384 let block = BlockInfo(BlockInfo::SZX_RESERVED as u32);
385 assert_eq!(true, block.is_invalid());
386 assert_eq!(None, block.smaller());
387 assert_eq!(None, block.next());
388 assert_eq!(None, block.valid());
389 }
390}