binary_cookies/tokio/
page.rs

1use tokio::io::{AsyncRead, AsyncReadExt};
2
3use super::{cookie::CookieHandle, cursor::CookieCursor};
4use crate::{
5    decode::{
6        cookies::CookiesOffset,
7        pages::{PageFsm, PagesOffset},
8        DecodeResult, OffsetSize,
9    },
10    error::Result,
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: AsyncRead, 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: AsyncRead + Unpin + Send, F: CookieCursor + Sync> PageDecoder<'a, R, F> {
61    pub async 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                .await?;
67            let count = fsm.buffer.available_space();
68            fsm.buffer.fill(count);
69            match fsm.process()? {
70                DecodeResult::Continue(fsm_) => {
71                    fsm = fsm_;
72                    continue;
73                },
74                DecodeResult::Done((cookie_offset_in_page, _)) => {
75                    let cookies_offset =
76                        CookiesOffset::new(self.offset, self.size, &cookie_offset_in_page);
77                    return Ok(CookieHandle::new(self.file, cookies_offset));
78                },
79            }
80        }
81    }
82}