mirror of
git://git.proxmox.com/git/pxar.git
synced 2025-01-08 01:17:40 +03:00
decoder/aio: add contents() and content_size() calls
Returns a decoder::Contents without a wrapper type, since in this case we don't want to hide the SeqRead implementation (as done in decoder::sync). For conviencience also implement AsyncRead if "tokio-io" is enabled. Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
This commit is contained in:
parent
eae6dc06af
commit
8a9c71c035
@ -5,7 +5,7 @@ use std::io;
|
||||
#[cfg(feature = "tokio-fs")]
|
||||
use std::path::Path;
|
||||
|
||||
use crate::decoder::{self, SeqRead};
|
||||
use crate::decoder::{self, Contents, SeqRead};
|
||||
use crate::Entry;
|
||||
|
||||
/// Asynchronous `pxar` decoder.
|
||||
@ -56,6 +56,16 @@ impl<T: SeqRead> Decoder<T> {
|
||||
self.inner.next_do().await.transpose()
|
||||
}
|
||||
|
||||
/// Get a reader for the contents of the current entry, if the entry has contents.
|
||||
pub fn contents(&mut self) -> Option<Contents<T>> {
|
||||
self.inner.content_reader()
|
||||
}
|
||||
|
||||
/// Get the size of the current contents, if the entry has contents.
|
||||
pub fn content_size(&self) -> Option<u64> {
|
||||
self.inner.content_size()
|
||||
}
|
||||
|
||||
/// Include goodbye tables in iteration.
|
||||
pub fn enable_goodbye_entries(&mut self, on: bool) {
|
||||
self.inner.with_goodbye_tables = on;
|
||||
@ -67,6 +77,7 @@ mod tok {
|
||||
use std::io;
|
||||
use std::pin::Pin;
|
||||
use std::task::{Context, Poll};
|
||||
use crate::decoder::{Contents, SeqRead};
|
||||
|
||||
/// Read adapter for `futures::io::AsyncRead`
|
||||
pub struct TokioReader<T> {
|
||||
@ -93,6 +104,29 @@ mod tok {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: crate::decoder::SeqRead> tokio::io::AsyncRead for Contents<'a, T> {
|
||||
fn poll_read(
|
||||
self: Pin<&mut Self>,
|
||||
cx: &mut Context<'_>,
|
||||
buf: &mut tokio::io::ReadBuf<'_>,
|
||||
) -> Poll<io::Result<()>> {
|
||||
unsafe {
|
||||
// Safety: poll_seq_read will *probably* only write to the buffer, so we don't
|
||||
// initialize it first, instead we treat is a &[u8] immediately and uphold the
|
||||
// ReadBuf invariants in the conditional below.
|
||||
let write_buf =
|
||||
&mut *(buf.unfilled_mut() as *mut [std::mem::MaybeUninit<u8>] as *mut [u8]);
|
||||
let result = self.poll_seq_read(cx, write_buf);
|
||||
if let Poll::Ready(Ok(n)) = result {
|
||||
// if we've written data, advance both initialized and filled bytes cursor
|
||||
buf.assume_init(n);
|
||||
buf.advance(n);
|
||||
}
|
||||
result.map(|_| Ok(()))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "tokio-io")]
|
||||
|
Loading…
Reference in New Issue
Block a user