binary_cookies/sync/
stream.rs1use 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}