binary_cookies/decode/
pages.rs

1use oval::Buffer;
2use winnow::{
3    stream::{Offset, Stream},
4    Parser,
5};
6
7use super::{cookies::CookiesOffsetInPage, DecodeResult, OffsetSize};
8use crate::{cookie::Page, decode::StreamIn, error::Result};
9
10#[derive(Clone)]
11#[derive(Debug)]
12#[derive(PartialEq, Eq, PartialOrd, Ord)]
13pub struct PagesOffset {
14    pub(crate) offset_sizes: Vec<OffsetSize>,
15}
16
17impl PagesOffset {
18    pub(crate) fn new(page_sizes: Vec<u32>) -> Self {
19        let head_len = 4 * 2 + page_sizes.len() as u64 * 4;
20        let mut offset = head_len;
21        let offset_sizes = page_sizes
22            .into_iter()
23            .map(|size| {
24                let prev = offset;
25                offset += size as u64;
26                OffsetSize { offset: prev, size }
27            })
28            .collect();
29        Self { offset_sizes }
30    }
31
32    /// Returns the offset and size of each page in binarycookies
33    pub fn offset_sizes(&self) -> &[OffsetSize] {
34        &self.offset_sizes
35    }
36}
37
38#[derive(Clone)]
39#[derive(Debug)]
40pub struct PageFsm {
41    pub(crate) buffer: Buffer,
42}
43
44impl PageFsm {
45    /// 4(`header`) + 4(`num_cookies`) + 4 * `num_cookies`
46    /// assume `num_cookies` = 3 round up to a power of 2
47    const BUF_SIZE: usize = 4 + 4 + 4 * 2;
48
49    pub fn new() -> Self {
50        let buffer = Buffer::with_capacity(Self::BUF_SIZE);
51        Self { buffer }
52    }
53
54    pub fn with_capacity(size: usize) -> Self {
55        let buffer = Buffer::with_capacity(size);
56        Self { buffer }
57    }
58
59    pub fn process(mut self) -> Result<DecodeResult<Self, (CookiesOffsetInPage, Buffer)>> {
60        let mut input: StreamIn = StreamIn::new(self.buffer.data());
61        let start = input.checkpoint();
62
63        let e = match Page::decode_head.parse_next(&mut input) {
64            Ok(o) => {
65                let consumed = input.offset_from(&start);
66                self.buffer.consume(consumed);
67                return Ok(DecodeResult::Done((o, self.buffer)));
68            },
69            Err(e) => e,
70        };
71
72        mode_err! {self, e, self.buffer}
73    }
74}
75
76impl Default for PageFsm {
77    fn default() -> Self {
78        Self::new()
79    }
80}