|
@@ -2,7 +2,7 @@ pub use private::Trailered;
|
|
|
|
|
|
mod private {
|
|
|
use std::{
|
|
|
- io::{self, Read, Seek, SeekFrom, Write},
|
|
|
+ io::{self, BufReader, Read, Seek, SeekFrom, Write},
|
|
|
marker::PhantomData,
|
|
|
};
|
|
|
|
|
@@ -16,6 +16,7 @@ mod private {
|
|
|
inner: T,
|
|
|
body_len: u64,
|
|
|
phantom: PhantomData<D>,
|
|
|
+ write_buf: Vec<u8>,
|
|
|
}
|
|
|
|
|
|
impl<T: Read + Seek, D: DeserializeOwned> Trailered<T, D> {
|
|
@@ -24,11 +25,12 @@ mod private {
|
|
|
inner,
|
|
|
body_len: 0,
|
|
|
phantom: PhantomData,
|
|
|
+ write_buf: Vec::new(),
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// Creates a new `Trailered<T>` containing the given `T`. This method requires that the given
|
|
|
- /// stream is either empty, or contains a valid serialization of `D` and a the offset at which
|
|
|
+ /// stream is either empty, or contains a valid serialization of `D` and the offset at which
|
|
|
/// `D` is stored.
|
|
|
pub fn new(mut inner: T) -> Result<(Trailered<T, D>, Option<D>)> {
|
|
|
let pos = inner.stream_position()?;
|
|
@@ -36,17 +38,20 @@ mod private {
|
|
|
if 0 == end {
|
|
|
return Ok((Self::empty(inner), None));
|
|
|
}
|
|
|
- let offset: i64 = std::mem::size_of::<i64>().try_into().unwrap();
|
|
|
- inner.seek(SeekFrom::End(-offset))?;
|
|
|
- let offset: i64 = read_from(&mut inner)?;
|
|
|
- let body_len = inner.seek(SeekFrom::End(offset))?;
|
|
|
- let trailer: D = read_from(&mut inner)?;
|
|
|
+ let mut reader = BufReader::new(inner);
|
|
|
+ let offset: i64 = std::mem::size_of::<i64>() as i64;
|
|
|
+ reader.seek(SeekFrom::End(-offset))?;
|
|
|
+ let offset: i64 = read_from(&mut reader)?;
|
|
|
+ let body_len = reader.seek(SeekFrom::End(offset))?;
|
|
|
+ let trailer: D = read_from(&mut reader)?;
|
|
|
+ let mut inner = reader.into_inner();
|
|
|
inner.seek(SeekFrom::Start(pos))?;
|
|
|
Ok((
|
|
|
Trailered {
|
|
|
inner,
|
|
|
body_len,
|
|
|
phantom: PhantomData,
|
|
|
+ write_buf: Vec::new(),
|
|
|
},
|
|
|
Some(trailer),
|
|
|
))
|
|
@@ -88,10 +93,12 @@ mod private {
|
|
|
fn write_trailer(&mut self, trailer: &D) -> io::Result<u64> {
|
|
|
let pos = self.inner.stream_position()?;
|
|
|
self.inner.seek(SeekFrom::Start(self.body_len))?;
|
|
|
- write_to(trailer, &mut self.inner).box_err()?;
|
|
|
+ self.write_buf.clear();
|
|
|
+ write_to(trailer, &mut self.write_buf)?;
|
|
|
let offset_u64 = 8 + self.inner.stream_position()? - self.body_len;
|
|
|
let offset = -(offset_u64 as i64);
|
|
|
- write_to(&offset, &mut self.inner).box_err()?;
|
|
|
+ write_to(&offset, &mut self.write_buf)?;
|
|
|
+ self.inner.write_all(&self.write_buf)?;
|
|
|
Ok(pos)
|
|
|
}
|
|
|
|