]> git.proxmox.com Git - pxar.git/blob - src/decoder/sync.rs
import
[pxar.git] / src / decoder / sync.rs
1 //! Blocking `pxar` format handling.
2
3 use std::io;
4 use std::pin::Pin;
5 use std::task::{Context, Poll};
6
7 use crate::decoder::{self, SeqRead};
8 use crate::util::poll_result_once;
9 use crate::Entry;
10
11 /// Blocking `pxar` decoder.
12 ///
13 /// This is the blocking I/O version of the `pxar` decoder. This will *not* work with an
14 /// asynchronous I/O object. I/O must always return `Poll::Ready`.
15 ///
16 /// Attempting to use a `Waker` from this context *will* `panic!`
17 ///
18 /// If you need to use asynchronous I/O, use `aio::Decoder`.
19 #[repr(transparent)]
20 pub struct Decoder<T> {
21 inner: decoder::DecoderImpl<T>,
22 }
23
24 impl<T: io::Read> Decoder<T> {
25 /// Decode a `pxar` archive from a regular `std::io::Read` input.
26 #[inline]
27 pub fn from_std(input: T) -> io::Result<Decoder<StandardReader<T>>> {
28 Decoder::new(StandardReader::new(input))
29 }
30 }
31
32 impl<T: SeqRead> Decoder<T> {
33 /// Create a *blocking* decoder from an input implementing our internal read interface.
34 ///
35 /// Note that the `input`'s `SeqRead` implementation must always return `Poll::Ready` and is
36 /// not allowed to use the `Waker`, as this will cause a `panic!`.
37 pub fn new(input: T) -> io::Result<Self> {
38 Ok(Self {
39 inner: poll_result_once(decoder::DecoderImpl::new(input))?,
40 })
41 }
42
43 /// Internal helper for `Accessor`. In this case we have the low-level state machine, and the
44 /// layer "above" the `Accessor` propagates the actual type (sync vs async).
45 pub(crate) fn from_impl(inner: decoder::DecoderImpl<T>) -> Self {
46 Self { inner }
47 }
48
49 /// If this is a directory entry, get the next item inside the directory.
50 pub fn next(&mut self) -> Option<io::Result<Entry>> {
51 poll_result_once(self.inner.next_do()).transpose()
52 }
53 }
54
55 impl<T: SeqRead> Iterator for Decoder<T> {
56 type Item = io::Result<Entry>;
57
58 fn next(&mut self) -> Option<Self::Item> {
59 Decoder::next(self)
60 }
61 }
62
63 /// Pxar decoder read adapter for `std::io::Read`.
64 pub struct StandardReader<T> {
65 inner: T,
66 }
67
68 impl<T: io::Read> StandardReader<T> {
69 pub fn new(inner: T) -> Self {
70 Self { inner }
71 }
72 }
73
74 impl<T: io::Read> SeqRead for StandardReader<T> {
75 fn poll_seq_read(
76 self: Pin<&mut Self>,
77 _cx: &mut Context,
78 buf: &mut [u8],
79 ) -> Poll<io::Result<usize>> {
80 Poll::Ready(unsafe { self.get_unchecked_mut() }.inner.read(buf))
81 }
82 }