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