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