binary_cookies/sync/
page.rs

1use 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}