binary_cookies/sync/
stream.rs

1use std::{io::Read, mem};
2
3use oval::Buffer;
4
5use crate::{
6    decode::{
7        binary_cookies::BinaryCookieFsm,
8        cookies::CookieFsm,
9        meta::MetaFsm,
10        pages::PageFsm,
11        stream::{State, Values},
12        DecodeResult,
13    },
14    error::{ParseError, Result},
15};
16
17#[derive(Clone)]
18#[derive(Debug)]
19pub struct StreamDecoder<R: Read> {
20    state: State,
21    rd: R,
22}
23
24impl<R: Read> StreamDecoder<R> {
25    const BUF_SIZE: usize = 64;
26
27    pub fn new(rd: R) -> Self {
28        Self {
29            state: State::Bc {
30                fsm: BinaryCookieFsm {
31                    buffer: Buffer::with_capacity(Self::BUF_SIZE),
32                },
33            },
34            rd,
35        }
36    }
37
38    pub fn decode(&mut self) -> Result<Values> {
39        match mem::take(&mut self.state) {
40            State::Bc { mut fsm } => loop {
41                let readed = self.rd.read(fsm.buffer.space())?;
42                fsm.buffer.fill(readed);
43
44                match fsm.process()? {
45                    DecodeResult::Continue(fsm_) => {
46                        fsm = fsm_;
47                        continue;
48                    },
49                    DecodeResult::Done((meta_offset, pages_offset, buffer)) => {
50                        self.state = State::Page {
51                            fsm: PageFsm { buffer },
52                            remaining_page: pages_offset.offset_sizes.len() as u32,
53                        };
54                        return Ok(Values::Bc { meta_offset, pages_offset });
55                    },
56                }
57            },
58            State::Page { mut fsm, remaining_page } => loop {
59                let readed = self.rd.read(fsm.buffer.space())?;
60                fsm.buffer.fill(readed);
61                match fsm.process()? {
62                    DecodeResult::Continue(fsm_) => {
63                        fsm = fsm_;
64                        continue;
65                    },
66                    DecodeResult::Done((c, buffer)) => {
67                        self.state = State::Cookie {
68                            fsm: CookieFsm { buffer },
69                            remaining_cookie: c.len() as u32,
70                            remaining_page: remaining_page - 1,
71                        };
72                        return Ok(Values::Page(c));
73                    },
74                }
75            },
76            State::Cookie {
77                remaining_cookie,
78                remaining_page,
79                mut fsm,
80            } => loop {
81                let readed = self.rd.read(fsm.buffer.space())?;
82                fsm.buffer.fill(readed);
83
84                match fsm.process()? {
85                    DecodeResult::Continue(fsm_) => {
86                        fsm = fsm_;
87                        continue;
88                    },
89                    DecodeResult::Done((cookie, buffer)) => {
90                        let remaining_cookie = remaining_cookie - 1;
91                        match (remaining_cookie, remaining_page) {
92                            (0, 0) => self.state = State::Meta { fsm: MetaFsm { buffer } },
93                            (0, _) => {
94                                self.state = State::Page {
95                                    fsm: PageFsm { buffer },
96                                    remaining_page,
97                                };
98                            },
99                            _ => {
100                                self.state = State::Cookie {
101                                    fsm: CookieFsm { buffer },
102                                    remaining_cookie,
103                                    remaining_page,
104                                };
105                            },
106                        }
107                        return Ok(Values::Cookie(cookie));
108                    },
109                }
110            },
111            State::Meta { mut fsm } => loop {
112                let readed = self.rd.read(fsm.buffer.space())?;
113                fsm.buffer.fill(readed);
114
115                match fsm.process()? {
116                    DecodeResult::Continue(fsm_) => {
117                        fsm = fsm_;
118                        continue;
119                    },
120                    DecodeResult::Done((checksum, meta)) => {
121                        self.state = State::Finished;
122                        return Ok(Values::Meta { checksum, meta });
123                    },
124                }
125            },
126            State::Finished => Err(ParseError::ParsingCompleted),
127            State::Transition => unreachable!(),
128        }
129    }
130}