pub use std::io::Error as IoError;
use std::{
error::Error as StdError,
io::{ErrorKind, Seek},
mem::MaybeUninit,
rc::Rc,
sync::Arc,
};
use std::{
fmt::Display,
io::{Read, Write},
slice,
};
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum ByteOrder {
BigEndian,
LittleEndian,
}
impl ByteOrder {
pub const fn native() -> Self {
#[cfg(target_endian = "little")]
{
Self::LittleEndian
}
#[cfg(target_endian = "big")]
{
Self::BigEndian
}
#[cfg(not(any(target_endian = "little", target_endian = "big")))]
{
compile_error!("Unsupported Native Byte Order")
}
}
}
pub trait DataInput: Read {
fn read_fully(&mut self, bytes: &mut [u8]) -> std::io::Result<()> {
let len = <Self as Read>::read(self, bytes)?;
if len != bytes.len() {
Err(std::io::Error::new(
ErrorKind::UnexpectedEof,
"Unexpected EOF in read_fully",
))
} else {
Ok(())
}
}
fn read_byte(&mut self) -> std::io::Result<u8> {
let mut ret = 0u8;
self.read_fully(slice::from_mut(&mut ret))?;
Ok(ret)
}
fn byte_order(&self) -> ByteOrder;
fn set_byte_order(&mut self, order: ByteOrder);
}
impl<R: DataInput> DataInput for &mut R {
fn byte_order(&self) -> ByteOrder {
R::byte_order(self)
}
fn set_byte_order(&mut self, order: ByteOrder) {
R::set_byte_order(self, order)
}
fn read_fully(&mut self, bytes: &mut [u8]) -> std::io::Result<()> {
R::read_fully(self, bytes)
}
fn read_byte(&mut self) -> std::io::Result<u8> {
R::read_byte(self)
}
}
impl<R: DataInput> DataInput for Box<R> {
fn byte_order(&self) -> ByteOrder {
R::byte_order(self)
}
fn set_byte_order(&mut self, order: ByteOrder) {
R::set_byte_order(self, order)
}
fn read_fully(&mut self, bytes: &mut [u8]) -> std::io::Result<()> {
R::read_fully(self, bytes)
}
fn read_byte(&mut self) -> std::io::Result<u8> {
R::read_byte(self)
}
}
pub struct DataInputStream<R: ?Sized> {
order: ByteOrder,
read: R,
}
impl<R> DataInputStream<R> {
pub const fn new(read: R, order: ByteOrder) -> Self {
Self { read, order }
}
pub const fn new_native(read: R) -> Self {
Self::new(read, ByteOrder::native())
}
pub fn into_inner(self) -> R {
self.read
}
}
impl<R: Read + ?Sized> Read for DataInputStream<R> {
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
self.read.read(buf)
}
}
impl<R: Read + ?Sized> DataInput for DataInputStream<R> {
fn byte_order(&self) -> ByteOrder {
self.order
}
fn set_byte_order(&mut self, order: ByteOrder) {
self.order = order
}
}
impl<R: Read + Seek + ?Sized> Seek for DataInputStream<R> {
fn seek(&mut self, pos: std::io::SeekFrom) -> std::io::Result<u64> {
self.read.seek(pos)
}
}
pub trait Deserializeable {
fn deserialize<R: DataInput + ?Sized>(&mut self, input: &mut R) -> std::io::Result<()>;
}
impl<T: Deserializeable + ?Sized> Deserializeable for &mut T {
fn deserialize<R: DataInput + ?Sized>(&mut self, input: &mut R) -> std::io::Result<()> {
T::deserialize(self, input)
}
}
impl<T: Deserializeable + ?Sized> Deserializeable for Box<T> {
fn deserialize<R: DataInput + ?Sized>(&mut self, input: &mut R) -> std::io::Result<()> {
T::deserialize(self, input)
}
}
impl<T: Deserializeable> Deserializeable for [T] {
fn deserialize<R: DataInput + ?Sized>(&mut self, input: &mut R) -> std::io::Result<()> {
for r in self {
r.deserialize(input)?;
}
Ok(())
}
}
impl<T: Deserializeable, const N: usize> Deserializeable for [T; N] {
fn deserialize<R: DataInput + ?Sized>(&mut self, input: &mut R) -> std::io::Result<()> {
<[T]>::deserialize(self, input)
}
}
impl<T: Deserializeable> Deserializeable for Option<T> {
fn deserialize<R: DataInput + ?Sized>(&mut self, input: &mut R) -> std::io::Result<()> {
match self {
Some(t) => t.deserialize(input),
None => Ok(()),
}
}
}
pub trait DeserializeCopy: Deserializeable + Sized {
fn deserialize_copy<R: DataInput + ?Sized>(input: &mut R) -> std::io::Result<Self>;
}
impl<T: DeserializeCopy> DeserializeCopy for Box<T> {
fn deserialize_copy<R: DataInput + ?Sized>(input: &mut R) -> std::io::Result<Self> {
T::deserialize_copy(input).map(Box::new)
}
}
impl<T: DeserializeCopy, const N: usize> DeserializeCopy for [T; N] {
fn deserialize_copy<R: DataInput + ?Sized>(input: &mut R) -> std::io::Result<Self> {
let mut uninit = MaybeUninit::<[T; N]>::uninit();
let ptr = uninit.as_mut_ptr().cast::<T>();
for i in 0..N {
let ptr = unsafe { ptr.add(i) };
unsafe { ptr.write(T::deserialize_copy(input)?) }
}
Ok(unsafe { uninit.assume_init() })
}
}
pub trait DataOutput: Write {
fn write_bytes(&mut self, bytes: &[u8]) -> std::io::Result<()> {
Ok(self.write_all(bytes)?)
}
fn write_byte(&mut self, byte: u8) -> std::io::Result<()> {
self.write_bytes(slice::from_ref(&byte))
}
fn byte_order(&self) -> ByteOrder;
fn set_byte_order(&mut self, order: ByteOrder);
}
pub struct DataOutputStream<W: ?Sized> {
order: ByteOrder,
write: W,
}
impl<W> DataOutputStream<W> {
pub const fn new(write: W, order: ByteOrder) -> Self {
Self { write, order }
}
pub const fn new_native(write: W) -> Self {
Self::new(write, ByteOrder::native())
}
pub fn into_inner(self) -> W {
self.write
}
}
impl<W: Write + ?Sized> Write for DataOutputStream<W> {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
self.write.write(buf)
}
fn flush(&mut self) -> std::io::Result<()> {
self.write.flush()
}
}
impl<W: Write + ?Sized> DataOutput for DataOutputStream<W> {
fn byte_order(&self) -> ByteOrder {
self.order
}
fn set_byte_order(&mut self, order: ByteOrder) {
self.order = order;
}
}
impl<W: Write + Seek + ?Sized> Seek for DataOutputStream<W> {
fn seek(&mut self, pos: std::io::SeekFrom) -> std::io::Result<u64> {
self.write.seek(pos)
}
}
pub trait Serializeable {
fn serialize<W: DataOutput + ?Sized>(&self, output: &mut W) -> std::io::Result<()>;
}
impl<T: Serializeable + ?Sized> Serializeable for &T {
fn serialize<W: DataOutput + ?Sized>(&self, output: &mut W) -> std::io::Result<()> {
T::serialize(self, output)
}
}
impl<T: Serializeable + ?Sized> Serializeable for &mut T {
fn serialize<W: DataOutput + ?Sized>(&self, output: &mut W) -> std::io::Result<()> {
T::serialize(self, output)
}
}
impl<T: Serializeable + ?Sized> Serializeable for Box<T> {
fn serialize<W: DataOutput + ?Sized>(&self, output: &mut W) -> std::io::Result<()> {
T::serialize(self, output)
}
}
impl<T: Serializeable + ?Sized> Serializeable for Rc<T> {
fn serialize<W: DataOutput + ?Sized>(&self, output: &mut W) -> std::io::Result<()> {
T::serialize(self, output)
}
}
impl<T: Serializeable + ?Sized> Serializeable for Arc<T> {
fn serialize<W: DataOutput + ?Sized>(&self, output: &mut W) -> std::io::Result<()> {
T::serialize(self, output)
}
}
impl<T: Serializeable> Serializeable for [T] {
fn serialize<W: DataOutput + ?Sized>(&self, output: &mut W) -> std::io::Result<()> {
for t in self {
t.serialize(output)?;
}
Ok(())
}
}
impl<T: Serializeable, const N: usize> Serializeable for [T; N] {
fn serialize<W: DataOutput + ?Sized>(&self, output: &mut W) -> std::io::Result<()> {
for t in self {
t.serialize(output)?;
}
Ok(())
}
}
impl<T: Serializeable> Serializeable for Option<T> {
fn serialize<W: DataOutput + ?Sized>(&self, output: &mut W) -> std::io::Result<()> {
match self {
Some(v) => v.serialize(output),
None => Ok(()),
}
}
}
impl Deserializeable for u8 {
fn deserialize<R: DataInput + ?Sized>(&mut self, input: &mut R) -> std::io::Result<()> {
input.read_fully(slice::from_mut(self))
}
}
impl DeserializeCopy for u8 {
fn deserialize_copy<R: DataInput + ?Sized>(input: &mut R) -> std::io::Result<Self> {
input.read_byte()
}
}
impl Deserializeable for i8 {
fn deserialize<R: DataInput + ?Sized>(&mut self, input: &mut R) -> std::io::Result<()> {
input.read_fully(slice::from_mut(unsafe {
&mut *(self as *mut i8 as *mut u8)
}))
}
}
impl DeserializeCopy for i8 {
fn deserialize_copy<R: DataInput + ?Sized>(input: &mut R) -> std::io::Result<Self> {
input.read_byte().map(|u| u as i8)
}
}
impl Serializeable for u8 {
fn serialize<W: DataOutput + ?Sized>(&self, input: &mut W) -> std::io::Result<()> {
input.write_byte(*self)
}
}
impl Serializeable for i8 {
fn serialize<W: DataOutput + ?Sized>(&self, input: &mut W) -> std::io::Result<()> {
input.write_byte(*self as u8)
}
}
macro_rules! impl_for_tuples{
() => {
impl Deserializeable for (){
fn deserialize<S: DataInput + ?Sized>(&mut self,_: &mut S) -> std::io::Result<()>{
Ok(())
}
}
impl DeserializeCopy for (){
fn deserialize_copy<S: DataInput + ?Sized>(_: &mut S) -> std::io::Result<()>{
Ok(())
}
}
impl Serializeable for (){
fn serialize<S: DataOutput + ?Sized>(&self,_: &mut S) -> std::io::Result<()>{
Ok(())
}
}
};
($a:ident) => {
#[allow(non_snake_case)]
impl<$a : Deserializeable + ?Sized> Deserializeable for ($a ,){
fn deserialize<S: DataInput + ?Sized>(&mut self,input: &mut S) -> std::io::Result<()>{
let ($a,) = self;
$a.deserialize(input)
}
}
#[allow(non_snake_case)]
impl<$a : DeserializeCopy> DeserializeCopy for ($a ,){
fn deserialize_copy<S: DataInput + ?Sized>(input: &mut S) -> std::io::Result<Self>{
Ok((<$a>::deserialize_copy(input)?,))
}
}
#[allow(non_snake_case)]
impl<$a : Serializeable + ?Sized> Serializeable for ($a ,){
fn serialize<S: DataOutput + ?Sized>(&self,input: &mut S) -> std::io::Result<()>{
let ($a,) = self;
$a.serialize(input)
}
}
};
($($leading:ident),+) => {
#[allow(non_snake_case)]
impl<$($leading: Deserializeable),+ +?Sized> Deserializeable for ($($leading),+){
fn deserialize<S: DataInput + ?Sized>(&mut self,input: &mut S) -> std::io::Result<()>{
let ($($leading),+,) = self;
$({$leading .deserialize(input)?})*
Ok(())
}
}
#[allow(non_snake_case)]
impl<$($leading: DeserializeCopy),*> DeserializeCopy for ($($leading),* ){
fn deserialize_copy<S: DataInput + ?Sized>(input: &mut S) -> std::io::Result<Self>{
Ok(($($leading::deserialize_copy(input)?),*))
}
}
#[allow(non_snake_case)]
impl<$($leading: Serializeable),+ +?Sized> Serializeable for ($($leading),+){
fn serialize<S: DataOutput + ?Sized>(&self,input: &mut S) -> std::io::Result<()>{
let ($($leading),+,) = self;
$({$leading .serialize(input)?})*
Ok(())
}
}
};
}
impl_for_tuples!();
impl_for_tuples!(A);
impl_for_tuples!(A, B);
impl_for_tuples!(A, B, C);
impl_for_tuples!(A, B, C, D);
impl_for_tuples!(A, B, C, D, E);
impl_for_tuples!(A, B, C, D, E, F);
impl_for_tuples!(A, B, C, D, E, F, G);
impl_for_tuples!(A, B, C, D, E, F, G, H);
impl_for_tuples!(A, B, C, D, E, F, G, H, I);
impl_for_tuples!(A, B, C, D, E, F, G, H, I, J);
impl_for_tuples!(A, B, C, D, E, F, G, H, I, J, K);
impl_for_tuples!(A, B, C, D, E, F, G, H, I, J, K, L);
macro_rules! impl_for_primitives{
[$($ty:ty),+] => {
$(
impl Deserializeable for $ty{
fn deserialize<R: DataInput + ?Sized>(&mut self,input: &mut R) -> std::io::Result<()>{
let mut bytes = [0u8;std::mem::size_of::<$ty>()];
input.read_fully(&mut bytes)?;
*self = match input.byte_order(){
ByteOrder::BigEndian => <$ty>::from_be_bytes(bytes),
ByteOrder::LittleEndian => <$ty>::from_le_bytes(bytes)
};
Ok(())
}
}
impl DeserializeCopy for $ty{
fn deserialize_copy<R: DataInput + ?Sized>(input: &mut R) -> std::io::Result<Self>{
let mut bytes = [0u8;std::mem::size_of::<$ty>()];
input.read_fully(&mut bytes)?;
Ok(match input.byte_order(){
ByteOrder::BigEndian => <$ty>::from_be_bytes(bytes),
ByteOrder::LittleEndian => <$ty>::from_le_bytes(bytes)
})
}
}
impl Serializeable for $ty{
fn serialize<W: DataOutput + ?Sized>(&self,output: &mut W) -> std::io::Result<()>{
let bytes = match output.byte_order(){
ByteOrder::BigEndian => <$ty>::to_be_bytes(*self),
ByteOrder::LittleEndian => <$ty>::to_le_bytes(*self)
};
output.write_bytes(&bytes)
}
}
)+
}
}
impl_for_primitives![i16, u16, i32, u32, i64, u64, i128, u128, f32, f64];
impl Deserializeable for String {
fn deserialize<R: DataInput + ?Sized>(&mut self, input: &mut R) -> std::io::Result<()> {
let size = u16::deserialize_copy(input)? as usize;
let mut vec = vec![0u8; size];
input.read_fully(&mut vec)?;
*self =
String::from_utf8(vec).map_err(|e| std::io::Error::new(ErrorKind::InvalidData, e))?;
Ok(())
}
}
impl DeserializeCopy for String {
fn deserialize_copy<R: DataInput + ?Sized>(input: &mut R) -> std::io::Result<Self> {
let size = u16::deserialize_copy(input)? as usize;
let mut vec = vec![0u8; size];
input.read_fully(&mut vec)?;
String::from_utf8(vec).map_err(|e| std::io::Error::new(ErrorKind::InvalidData, e))
}
}
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub struct OutOfRange<T>(pub T);
impl<T: Display> Display for OutOfRange<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_fmt(format_args!(
"{} is not in range for this operation",
&self.0
))
}
}
impl<T> StdError for OutOfRange<T> where Self: std::fmt::Debug + Display {}
impl Serializeable for String {
fn serialize<W: DataOutput + ?Sized>(&self, output: &mut W) -> std::io::Result<()> {
let size = self.len();
if size > u16::MAX as usize {
Err(std::io::Error::new(
ErrorKind::InvalidData,
OutOfRange(size),
))
} else {
(size as u16).serialize(output)?;
output.write_bytes(self.as_bytes())
}
}
}