binary_cookies/tokio/
page.rs1use 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}