binary_cookies/sync/
page.rs1use std::io::Read;
2
3use crate::{
4 decode::{
5 cookies::CookiesOffset,
6 pages::{PageFsm, PagesOffset},
7 DecodeResult, OffsetSize,
8 },
9 error::Result,
10 sync::{cookie::CookieHandle, cursor::CookieCursor},
11};
12
13#[derive(Clone)]
14#[derive(Debug)]
15pub struct PagesHandle<'a, F: CookieCursor> {
16 pub(crate) file: &'a F,
17 pub(crate) offset: PagesOffset,
18}
19
20impl<'a, F: CookieCursor> PagesHandle<'a, F> {
21 pub fn decoders(
22 &self,
23 ) -> impl Iterator<Item = PageDecoder<'_, <F as CookieCursor>::Cursor<'_>, F>> {
24 self.offset
25 .offset_sizes
26 .iter()
27 .map(|&OffsetSize { offset, size }| PageDecoder {
28 file: self.file,
29 rd: self.file.cursor_at(offset),
30 offset,
31 size,
32 })
33 }
34
35 pub fn into_decoders(
36 self,
37 ) -> impl Iterator<Item = PageDecoder<'a, <F as CookieCursor>::Cursor<'a>, F>> {
38 self.offset
39 .offset_sizes
40 .into_iter()
41 .map(|OffsetSize { offset, size }| PageDecoder {
42 file: self.file,
43 rd: self.file.cursor_at(offset),
44 offset,
45 size,
46 })
47 }
48}
49
50#[derive(Clone, Copy)]
51#[derive(Debug)]
52#[derive(PartialEq, Eq, PartialOrd, Ord)]
53pub struct PageDecoder<'a, R: Read, F: CookieCursor> {
54 pub(crate) file: &'a F,
55 pub(crate) rd: R,
56 pub(crate) offset: u64,
57 pub(crate) size: u32,
58}
59
60impl<'a, R: Read, F: CookieCursor> PageDecoder<'a, R, F> {
61 pub fn decode(&mut self) -> Result<CookieHandle<'a, F>> {
62 let mut fsm = PageFsm::new();
63 loop {
64 self.rd
65 .read_exact(fsm.buffer.space())?;
66 let count = fsm.buffer.available_space();
67 fsm.buffer.fill(count);
68 match fsm.process()? {
69 DecodeResult::Continue(fsm_) => {
70 fsm = fsm_;
71 continue;
72 },
73 DecodeResult::Done((cookie_offset_in_page, _)) => {
74 let cookies_offset =
75 CookiesOffset::new(self.offset, self.size, &cookie_offset_in_page);
76 return Ok(CookieHandle::new(self.file, cookies_offset));
77 },
78 }
79 }
80 }
81}