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