use alloc::vec::Vec; #[cfg(feature = "std")] use std::{io, mem};
usecrate::pod::{bytes_of, bytes_of_slice, Pod};
/// Trait for writable buffer. #[allow(clippy::len_without_is_empty)] pubtrait WritableBuffer { /// Returns position/offset for data to be written at. /// /// Should only be used in debug assertions fn len(&self) -> usize;
/// Reserves specified number of bytes in the buffer. /// /// This will be called exactly once before writing anything to the buffer, /// and the given size is the exact total number of bytes that will be written. fn reserve(&mutself, size: usize) -> Result<(), ()>;
/// Writes zero bytes at the end of the buffer until the buffer /// has the specified length. fn resize(&mutself, new_len: usize);
/// Writes the specified slice of bytes at the end of the buffer. fn write_bytes(&mutself, val: &[u8]);
/// Writes the specified `Pod` type at the end of the buffer. fn write_pod<T: Pod>(&mutself, val: &T) where Self: Sized,
{ self.write_bytes(bytes_of(val))
}
/// Writes the specified `Pod` slice at the end of the buffer. fn write_pod_slice<T: Pod>(&mutself, val: &[T]) where Self: Sized,
{ self.write_bytes(bytes_of_slice(val))
}
}
impl<'a> dyn WritableBuffer + 'a { /// Writes the specified `Pod` type at the end of the buffer. pubfn write<T: Pod>(&mutself, val: &T) { self.write_bytes(bytes_of(val))
}
/// Writes the specified `Pod` slice at the end of the buffer. pubfn write_slice<T: Pod>(&mutself, val: &[T]) { self.write_bytes(bytes_of_slice(val))
}
}
/// A [`WritableBuffer`] that streams data to a [`Write`](std::io::Write) implementation. /// /// [`Self::result`] must be called to determine if an I/O error occurred during writing. /// /// It is advisable to use a buffered writer like [`BufWriter`](std::io::BufWriter) /// instead of an unbuffered writer like [`File`](std::fs::File). #[cfg(feature = "std")] #[derive(Debug)] pubstruct StreamingBuffer<W> {
writer: W,
len: usize,
result: Result<(), io::Error>,
}
#[cfg(feature = "std")] impl<W> StreamingBuffer<W> { /// Create a new `StreamingBuffer` backed by the given writer. pubfn new(writer: W) -> Self {
StreamingBuffer {
writer,
len: 0,
result: Ok(()),
}
}
/// Unwraps this [`StreamingBuffer`] giving back the original writer. pubfn into_inner(self) -> W { self.writer
}
/// Returns any error that occurred during writing. pubfn result(&mutself) -> Result<(), io::Error> {
mem::replace(&mutself.result, Ok(()))
}
}
/// A trait for mutable byte slices. /// /// It provides convenience methods for `Pod` types. pub(crate) trait BytesMut { fn write_at<T: Pod>(self, offset: usize, val: &T) -> Result<(), ()>;
}
impl<'a> BytesMut for &'a mut [u8] { #[inline] fn write_at<T: Pod>(self, offset: usize, val: &T) -> Result<(), ()> { let src = bytes_of(val); let dest = self.get_mut(offset..).ok_or(())?; let dest = dest.get_mut(..src.len()).ok_or(())?;
dest.copy_from_slice(src);
Ok(())
}
}
/// Write an unsigned number using the LEB128 encoding to a buffer. /// /// Returns the number of bytes written. #[allow(dead_code)] pub(crate) fn write_uleb128(buf: &mut Vec<u8>, mut val: u64) -> usize { letmut len = 0; loop { letmut byte = (val & 0x7f) as u8;
val >>= 7; let done = val == 0; if !done {
byte |= 0x80;
}
buf.push(byte);
len += 1;
if done { return len;
}
}
}
/// Write a signed number using the LEB128 encoding to a buffer. /// /// Returns the number of bytes written. #[allow(dead_code)] pub(crate) fn write_sleb128(buf: &mut Vec<u8>, mut val: i64) -> usize { letmut len = 0; loop { letmut byte = val as u8; // Keep the sign bit for testing
val >>= 6; let done = val == 0 || val == -1; if done {
byte &= !0x80;
} else { // Remove the sign bit
val >>= 1;
byte |= 0x80;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.