use crate::endian::Endian;
use crate::length::Len;
use crate::pin::Pin;
use crate::stream::Stream;
use std::io;
use std::io::{Read, Seek, SeekFrom, Write};
#[allow(dead_code)]
pub trait ValueRead<T: Read + Write + Seek>: Sized {
fn read(stream: &mut Stream<T>) -> io::Result<Self>;
}
#[allow(dead_code)]
pub trait ValueWrite: Sized {
fn write(&self, endian: &Endian) -> io::Result<Vec<u8>>;
}
pub trait Bytes<T: Read + Write + Seek> {
fn read_value<Value: ValueRead<T>>(&mut self) -> io::Result<Value>;
fn read_size(&mut self, size: u64) -> io::Result<Vec<u8>>;
fn fill_size(&mut self, size: u64) -> io::Result<&mut Self>;
fn extend_from_slice(&mut self, data: &[u8]) -> io::Result<&mut Self>;
fn splice(&mut self, offset: u64, data: &[u8]) -> io::Result<&mut Self>;
fn insert_data(&mut self, data: &[u8]) -> io::Result<&mut Self>;
}
#[allow(dead_code)]
impl<T: Read + Write + Seek> Bytes<T> for Stream<T> {
fn read_value<Value: ValueRead<T>>(&mut self) -> io::Result<Value> {
Value::read(self)
}
fn read_size(&mut self, size: u64) -> io::Result<Vec<u8>> {
let mut buf = vec![0u8; size as usize];
self.inner.read_exact(&mut buf)?;
Ok(buf)
}
fn fill_size(&mut self, size: u64) -> io::Result<&mut Self> {
let data_len = self.length()?;
if data_len < size {
let diff = size - data_len;
self.inner.write(&vec![0u8; diff as usize])?;
}
Ok(self)
}
fn extend_from_slice(&mut self, data: &[u8]) -> io::Result<&mut Self> {
self.pin()?;
self.seek(SeekFrom::End(0))?;
self.inner.write_all(data)?;
self.un_pin()?;
Ok(self)
}
fn splice(&mut self, offset: u64, data: &[u8]) -> io::Result<&mut Self> {
self.pin()?;
self.seek(SeekFrom::Start(offset))?;
let mut remain_data = vec![];
self.read_to_end(&mut remain_data)?;
self.seek(SeekFrom::Start(offset))?;
self.write_all(data)?;
self.write_all(&remain_data)?;
self.un_pin()?;
Ok(self)
}
fn insert_data(&mut self, data: &[u8]) -> io::Result<&mut Self> {
self.pin()?;
self.seek(SeekFrom::Start(0))?;
let mut remain_data = vec![];
self.read_to_end(&mut remain_data)?;
self.write_all(data)?;
self.write_all(&remain_data)?;
self.un_pin()?;
Ok(self)
}
}
impl<T: Read + Write + Seek> Stream<T> {
pub fn write_value<Value: ValueWrite>(&mut self, value: &Value) -> io::Result<&mut Self> {
let data = value.write(&self.endian)?;
self.inner.write(&data)?;
Ok(self)
}
}
#[macro_export]
macro_rules! value_read {
($($typ:ty, $size:expr),*) => {
$(
impl<T: std::io::Read + std::io::Write + std::io::Seek> ValueRead<T> for $typ {
fn read(stream: &mut Stream<T>) -> std::io::Result<Self> {
use crate::endian::Endian;
let mut buf = [0u8; $size];
stream.read_exact(&mut buf)?;
let value = match stream.endian {
Endian::Big => <$typ>::from_be_bytes(buf),
Endian::Little => <$typ>::from_le_bytes(buf),
};
Ok(value)
}
}
)*
}
}
value_read!(u8, 1, u16, 2, u32, 4, u64, 8);
#[macro_export]
macro_rules! value_write {
($($typ:ty),*) => {
$(
impl ValueWrite for $typ {
fn write(&self, endian: &crate::endian::Endian) -> std::io::Result<Vec<u8>> {
use crate::endian::Endian;
let value = match endian {
Endian::Big => self.to_be_bytes().to_vec(),
Endian::Little => self.to_le_bytes().to_vec(),
};
Ok(value)
}
}
)*
}
}
value_write!(u8, u16, u32, u64);
pub trait FromBytes<const N: usize> {
fn from_be_bytes(data: [u8; N]) -> Self;
fn from_le_bytes(data: [u8; N]) -> Self;
}
#[macro_export]
macro_rules! enum_to_bytes {
($typ:ty,$btyp:ty) => {
impl fast_stream::bytes::ValueWrite for $typ {
fn write(&self, endian: &fast_stream::endian::Endian) -> std::io::Result<Vec<u8>> {
let value: $btyp = self.clone() as $btyp;
value.write(endian)
}
}
impl<T: std::io::Read + std::io::Write + std::io::Seek> fast_stream::bytes::ValueRead<T>
for $typ
{
fn read(stream: &mut fast_stream::stream::Stream<T>) -> std::io::Result<Self> {
use fast_stream::bytes::Bytes;
let value: $btyp = stream.read_value()?;
Ok(value.into())
}
}
};
}
impl ValueWrite for String {
fn write(&self, _endian: &Endian) -> io::Result<Vec<u8>> {
Ok(self.as_bytes().to_vec())
}
}
impl ValueWrite for Vec<u8> {
fn write(&self, _endian: &Endian) -> io::Result<Vec<u8>> {
Ok(self.clone())
}
}
impl<T: Read + Write + Seek> ValueRead<T> for [u8; 4] {
fn read(stream: &mut Stream<T>) -> io::Result<Self> {
let mut value = [0u8; 4];
stream.read_exact(&mut value)?;
Ok(value)
}
}