1 //! Blocking `pxar` format handling.
6 use std
::task
::{Context, Poll}
;
8 use crate::decoder
::{self, SeqRead}
;
9 use crate::util
::poll_result_once
;
12 /// Blocking `pxar` decoder.
14 /// This is the blocking I/O version of the `pxar` decoder. This will *not* work with an
15 /// asynchronous I/O object. I/O must always return `Poll::Ready`.
17 /// Attempting to use a `Waker` from this context *will* `panic!`
19 /// If you need to use asynchronous I/O, use `aio::Decoder`.
21 pub struct Decoder
<T
> {
22 inner
: decoder
::DecoderImpl
<T
>,
25 impl<T
: io
::Read
> Decoder
<StandardReader
<T
>> {
26 /// Decode a `pxar` archive from a regular `std::io::Read` input.
28 pub fn from_std(input
: T
) -> io
::Result
<Self> {
29 Decoder
::new(StandardReader
::new(input
))
32 /// Get a direct reference to the reader contained inside the contained [`StandardReader`].
33 pub fn input(&mut self) -> &T
{
34 self.inner
.input().inner()
38 impl Decoder
<StandardReader
<std
::fs
::File
>> {
39 /// Convenience shortcut for `File::open` followed by `Accessor::from_file`.
40 pub fn open
<P
: AsRef
<Path
>>(path
: P
) -> io
::Result
<Self> {
41 Self::from_std(std
::fs
::File
::open(path
.as_ref())?
)
45 impl<T
: SeqRead
> Decoder
<T
> {
46 /// Create a *blocking* decoder from an input implementing our internal read interface.
48 /// Note that the `input`'s `SeqRead` implementation must always return `Poll::Ready` and is
49 /// not allowed to use the `Waker`, as this will cause a `panic!`.
50 pub fn new(input
: T
) -> io
::Result
<Self> {
52 inner
: poll_result_once(decoder
::DecoderImpl
::new(input
))?
,
56 /// Internal helper for `Accessor`. In this case we have the low-level state machine, and the
57 /// layer "above" the `Accessor` propagates the actual type (sync vs async).
58 pub(crate) fn from_impl(inner
: decoder
::DecoderImpl
<T
>) -> Self {
62 // I would normally agree with clippy, but this here is to be consistent with the async
63 // counterpart, and we *do* implement Iterator as well, so that's fine!
64 #[allow(clippy::should_implement_trait)]
65 /// If this is a directory entry, get the next item inside the directory.
66 pub fn next(&mut self) -> Option
<io
::Result
<Entry
>> {
67 poll_result_once(self.inner
.next_do()).transpose()
70 /// Get a reader for the contents of the current entry, if the entry has contents.
71 pub fn contents(&mut self) -> Option
<Contents
<T
>> {
72 self.inner
.content_reader().map(|inner
| Contents { inner }
)
75 /// Get the size of the current contents, if the entry has contents.
76 pub fn content_size(&self) -> Option
<u64> {
77 self.inner
.content_size()
80 /// Include goodbye tables in iteration.
81 pub fn enable_goodbye_entries(&mut self, on
: bool
) {
82 self.inner
.with_goodbye_tables
= on
;
86 impl<T
: SeqRead
> Iterator
for Decoder
<T
> {
87 type Item
= io
::Result
<Entry
>;
89 fn next(&mut self) -> Option
<Self::Item
> {
94 /// Pxar decoder read adapter for `std::io::Read`.
95 pub struct StandardReader
<T
> {
99 impl<T
: io
::Read
> StandardReader
<T
> {
100 /// Make a new [`StandardReader`].
101 pub fn new(inner
: T
) -> Self {
105 /// Get an immutable reference to the contained reader.
106 pub fn inner(&self) -> &T
{
111 impl<T
: io
::Read
> SeqRead
for StandardReader
<T
> {
113 self: Pin
<&mut Self>,
116 ) -> Poll
<io
::Result
<usize>> {
117 Poll
::Ready(unsafe { self.get_unchecked_mut() }
.inner
.read(buf
))
121 /// Reader for file contents inside a pxar archive.
122 pub struct Contents
<'a
, T
: SeqRead
> {
123 inner
: decoder
::Contents
<'a
, T
>,
126 impl<'a
, T
: SeqRead
> io
::Read
for Contents
<'a
, T
> {
127 fn read(&mut self, buf
: &mut [u8]) -> io
::Result
<usize> {
128 poll_result_once(super::seq_read(&mut self.inner
, buf
))