use crate::Result;
pub trait MdfWrite {
fn write_all(&mut self, bytes: &[u8]) -> Result<()>;
fn seek(&mut self, pos: u64) -> Result<u64>;
fn position(&self) -> u64;
fn flush(&mut self) -> Result<()>;
}
pub struct VecWriter {
buffer: alloc::vec::Vec<u8>,
position: u64,
}
impl VecWriter {
pub fn new() -> Self {
Self {
buffer: alloc::vec::Vec::new(),
position: 0,
}
}
pub fn with_capacity(capacity: usize) -> Self {
Self {
buffer: alloc::vec::Vec::with_capacity(capacity),
position: 0,
}
}
pub fn into_inner(self) -> alloc::vec::Vec<u8> {
self.buffer
}
pub fn as_slice(&self) -> &[u8] {
&self.buffer
}
pub fn len(&self) -> usize {
self.buffer.len()
}
pub fn is_empty(&self) -> bool {
self.buffer.is_empty()
}
}
impl Default for VecWriter {
fn default() -> Self {
Self::new()
}
}
impl MdfWrite for VecWriter {
fn write_all(&mut self, bytes: &[u8]) -> Result<()> {
let pos = self.position as usize;
let end = pos + bytes.len();
if end > self.buffer.len() {
self.buffer.resize(end, 0);
}
self.buffer[pos..end].copy_from_slice(bytes);
self.position = end as u64;
Ok(())
}
fn seek(&mut self, pos: u64) -> Result<u64> {
self.position = pos;
Ok(self.position)
}
fn position(&self) -> u64 {
self.position
}
fn flush(&mut self) -> Result<()> {
Ok(())
}
}
#[cfg(feature = "std")]
mod std_impl {
use super::MdfWrite;
use crate::Result;
use std::fs::File;
use std::io::{BufWriter, Seek, SeekFrom, Write};
pub struct FileWriter {
inner: BufWriter<File>,
position: u64,
}
impl FileWriter {
pub fn new(path: &str) -> Result<Self> {
Self::with_capacity(path, 1_048_576) }
pub fn with_capacity(path: &str, capacity: usize) -> Result<Self> {
let file = File::create(path)?;
let inner = BufWriter::with_capacity(capacity, file);
Ok(Self { inner, position: 0 })
}
}
impl MdfWrite for FileWriter {
fn write_all(&mut self, bytes: &[u8]) -> Result<()> {
self.inner.write_all(bytes)?;
self.position += bytes.len() as u64;
Ok(())
}
fn seek(&mut self, pos: u64) -> Result<u64> {
self.inner.seek(SeekFrom::Start(pos))?;
self.position = pos;
Ok(self.position)
}
fn position(&self) -> u64 {
self.position
}
fn flush(&mut self) -> Result<()> {
self.inner.flush()?;
Ok(())
}
}
}
#[cfg(feature = "std")]
pub use std_impl::FileWriter;