optimize
This commit is contained in:
parent
6625dab9c1
commit
5782951e68
25 changed files with 956 additions and 501 deletions
|
|
@ -1,6 +1,12 @@
|
|||
use std::io::{Cursor, Read, Write};
|
||||
use std::any::Any;
|
||||
use std::cmp::max;
|
||||
use std::fmt::Arguments;
|
||||
use std::io;
|
||||
use std::io::{Cursor, ErrorKind, IoSlice, Read, Write};
|
||||
use std::ops::Sub;
|
||||
use bytemuck::bytes_of;
|
||||
use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions};
|
||||
use crate::rmc::structures;
|
||||
use crate::rmc::structures::Error::VersionMismatch;
|
||||
use crate::rmc::structures::Result;
|
||||
|
||||
|
|
@ -10,35 +16,97 @@ struct StructureHeader{
|
|||
length: u32
|
||||
}
|
||||
|
||||
pub fn write_struct(writer: &mut dyn Write, version: u8, pred: impl FnOnce(&mut Vec<u8>) -> Result<()> ) -> Result<()> {
|
||||
#[cfg(feature = "rmc_struct_header")]
|
||||
pub const HEADER_SIZE: u32 = 0;
|
||||
#[cfg(not(feature = "rmc_struct_header"))]
|
||||
pub const HEADER_SIZE: u32 = 5;
|
||||
|
||||
pub struct OnlyWriteVec<'a>(&'a mut Vec<u8>);
|
||||
|
||||
impl Write for OnlyWriteVec<'_> {
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
self.0.flush()
|
||||
}
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
self.0.write(buf)
|
||||
}
|
||||
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
|
||||
self.0.write_all(buf)
|
||||
}
|
||||
fn write_fmt(&mut self, args: Arguments<'_>) -> io::Result<()> {
|
||||
self.0.write_fmt(args)
|
||||
}
|
||||
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
|
||||
self.0.write_vectored(bufs)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "rmc_struct_header")]
|
||||
pub fn write_struct<T: Write>(writer: &mut T, version: u8, inner_size: u32, pred: impl FnOnce(&mut T) -> Result<()> ) -> Result<()> {
|
||||
writer.write_all(&[version])?;
|
||||
|
||||
let mut scratch_space: Vec<u8> = Vec::new();
|
||||
writer.write_all(bytes_of(&inner_size))?;
|
||||
|
||||
(pred)(&mut scratch_space)?;
|
||||
|
||||
let u32_size = scratch_space.len() as u32;
|
||||
|
||||
writer.write_all(bytes_of(&u32_size))?;
|
||||
writer.write_all(&scratch_space)?;
|
||||
(pred)(writer)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn read_struct<T: Sized>(mut reader: &mut dyn Read, version: u8, pred: impl FnOnce(&mut Cursor<Vec<u8>>) -> Result<T>) -> Result<T> {
|
||||
|
||||
|
||||
#[cfg(not(feature = "rmc_struct_header"))]
|
||||
pub fn write_struct<T: Write>(writer: &mut T, version: u8, _inner_size: u32, pred: impl FnOnce(&mut T) -> Result<()> ) -> Result<()> {
|
||||
pred(writer)
|
||||
}
|
||||
|
||||
|
||||
pub struct SubRead<'a, T: Read>{
|
||||
left_to_read: usize,
|
||||
origin: &'a mut T
|
||||
}
|
||||
|
||||
impl<'a, T: Read> SubRead<'a, T>{
|
||||
pub const fn new(origin: &'a mut T, left_to_read: usize) -> Self{
|
||||
Self{
|
||||
left_to_read,
|
||||
origin
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Read> Read for SubRead<'_, T>{
|
||||
#[inline(always)]
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
let max_read = max(self.left_to_read, buf.len());
|
||||
let read = self.origin.read(&mut buf[..max_read])?;
|
||||
self.left_to_read -= read;
|
||||
Ok(read)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
|
||||
if buf.len() > self.left_to_read{
|
||||
return Err(io::Error::new(ErrorKind::UnexpectedEof, "Would run over end of SubRead"));
|
||||
}
|
||||
self.left_to_read -= buf.len();
|
||||
self.origin.read_exact(buf)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "rmc_struct_header")]
|
||||
pub fn read_struct<T: Sized, R: Read>(mut reader: &mut R, version: u8, pred: impl FnOnce(&mut SubRead<R>) -> Result<T>) -> Result<T> {
|
||||
let ver: u8 = reader.read_struct(IS_BIG_ENDIAN)?;
|
||||
|
||||
if ver != version{
|
||||
if ver != version {
|
||||
return Err(VersionMismatch(ver));
|
||||
}
|
||||
|
||||
let size: u32 = reader.read_struct(IS_BIG_ENDIAN)?;
|
||||
|
||||
let mut vec = vec![0u8; size as usize];
|
||||
Ok(pred(&mut SubRead::new(reader, size as usize))?)
|
||||
}
|
||||
|
||||
reader.read_exact(&mut vec)?;
|
||||
|
||||
let mut cursor = Cursor::new(vec);
|
||||
|
||||
Ok(pred(&mut cursor)?)
|
||||
}
|
||||
#[cfg(not(feature = "rmc_struct_header"))]
|
||||
pub fn read_struct<T: Sized, R: Read>(mut reader: &mut R, version: u8, pred: impl FnOnce(&mut R) -> Result<T>) -> Result<T> {
|
||||
Ok(pred(&mut reader)?)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue