binary_io/
data.rs

1//! Implementation of LCS4 IO for
2
3pub use std::io::Error as IoError;
4use std::{
5    error::Error as StdError,
6    io::{ErrorKind, Seek},
7    mem::MaybeUninit,
8    rc::Rc,
9    sync::Arc,
10};
11use std::{
12    fmt::Display,
13    io::{Read, Write},
14    slice,
15};
16
17/// An enumeration that stores the possible byte order modes as specified by LCS4
18#[derive(Copy, Clone, PartialEq, Eq, Debug)]
19pub enum ByteOrder {
20    /// The Big Endian (Most Significant Byte first) Byte Order
21    BigEndian,
22    /// The Little Endian (Least Significant Byte first) Byte Order
23    LittleEndian,
24}
25
26impl ByteOrder {
27    /// Returns the Byte Order used by the host
28    pub const fn native() -> Self {
29        #[cfg(target_endian = "little")]
30        {
31            Self::LittleEndian
32        }
33        #[cfg(target_endian = "big")]
34        {
35            Self::BigEndian
36        }
37        #[cfg(not(any(target_endian = "little", target_endian = "big")))]
38        {
39            compile_error!("Unsupported Native Byte Order")
40        }
41    }
42}
43
44/// A Trait for types that can perform binary IO Reads
45pub trait DataInput: Read {
46    ///
47    /// Reads exactly bytes.len() bytes into bytes.
48    /// Returns an error if an End of File prevents reading the entire array.
49    fn read_fully(&mut self, bytes: &mut [u8]) -> std::io::Result<()> {
50        let len = <Self as Read>::read(self, bytes)?;
51        if len != bytes.len() {
52            Err(std::io::Error::new(
53                ErrorKind::UnexpectedEof,
54                "Unexpected EOF in read_fully",
55            ))
56        } else {
57            Ok(())
58        }
59    }
60    /// Reads a single byte, and returns it, or an error if a byte cannot be read
61    fn read_byte(&mut self) -> std::io::Result<u8> {
62        let mut ret = 0u8;
63        self.read_fully(slice::from_mut(&mut ret))?;
64        Ok(ret)
65    }
66    /// Gets the current byte order mode
67    fn byte_order(&self) -> ByteOrder;
68    /// Sets the current byte order mode
69    fn set_byte_order(&mut self, order: ByteOrder);
70}
71
72impl<R: DataInput> DataInput for &mut R {
73    fn byte_order(&self) -> ByteOrder {
74        R::byte_order(self)
75    }
76
77    fn set_byte_order(&mut self, order: ByteOrder) {
78        R::set_byte_order(self, order)
79    }
80
81    fn read_fully(&mut self, bytes: &mut [u8]) -> std::io::Result<()> {
82        R::read_fully(self, bytes)
83    }
84
85    fn read_byte(&mut self) -> std::io::Result<u8> {
86        R::read_byte(self)
87    }
88}
89
90impl<R: DataInput> DataInput for Box<R> {
91    fn byte_order(&self) -> ByteOrder {
92        R::byte_order(self)
93    }
94
95    fn set_byte_order(&mut self, order: ByteOrder) {
96        R::set_byte_order(self, order)
97    }
98
99    fn read_fully(&mut self, bytes: &mut [u8]) -> std::io::Result<()> {
100        R::read_fully(self, bytes)
101    }
102
103    fn read_byte(&mut self) -> std::io::Result<u8> {
104        R::read_byte(self)
105    }
106}
107
108///
109/// A type that can perform Binary IO Reads by passing through reads to a type that implements Read
110pub struct DataInputStream<R: ?Sized> {
111    order: ByteOrder,
112    read: R,
113}
114
115impl<R> DataInputStream<R> {
116    ///
117    /// Constructs a new DataInputStream from a given stream, in the given byte order mode
118    pub const fn new(read: R, order: ByteOrder) -> Self {
119        Self { read, order }
120    }
121
122    ///
123    /// Constructs a new DataInputStream from a given stream, in the native byte order mode
124    pub const fn new_native(read: R) -> Self {
125        Self::new(read, ByteOrder::native())
126    }
127
128    ///
129    /// Returns the inner stream
130    pub fn into_inner(self) -> R {
131        self.read
132    }
133}
134
135impl<R: Read + ?Sized> Read for DataInputStream<R> {
136    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
137        self.read.read(buf)
138    }
139}
140
141impl<R: Read + ?Sized> DataInput for DataInputStream<R> {
142    fn byte_order(&self) -> ByteOrder {
143        self.order
144    }
145
146    fn set_byte_order(&mut self, order: ByteOrder) {
147        self.order = order
148    }
149}
150
151impl<R: Read + Seek + ?Sized> Seek for DataInputStream<R> {
152    fn seek(&mut self, pos: std::io::SeekFrom) -> std::io::Result<u64> {
153        self.read.seek(pos)
154    }
155}
156
157///
158/// A trait for types which can be deserialized from a stream of bytes according to LCS 4
159pub trait Deserializeable {
160    /// Deserializes the bytes on the stream and stores the result in self or returns an error
161    fn deserialize<R: DataInput + ?Sized>(&mut self, input: &mut R) -> std::io::Result<()>;
162}
163
164impl<T: Deserializeable + ?Sized> Deserializeable for &mut T {
165    fn deserialize<R: DataInput + ?Sized>(&mut self, input: &mut R) -> std::io::Result<()> {
166        T::deserialize(self, input)
167    }
168}
169
170impl<T: Deserializeable + ?Sized> Deserializeable for Box<T> {
171    fn deserialize<R: DataInput + ?Sized>(&mut self, input: &mut R) -> std::io::Result<()> {
172        T::deserialize(self, input)
173    }
174}
175
176impl<T: Deserializeable> Deserializeable for [T] {
177    fn deserialize<R: DataInput + ?Sized>(&mut self, input: &mut R) -> std::io::Result<()> {
178        for r in self {
179            r.deserialize(input)?;
180        }
181        Ok(())
182    }
183}
184
185impl<T: Deserializeable, const N: usize> Deserializeable for [T; N] {
186    fn deserialize<R: DataInput + ?Sized>(&mut self, input: &mut R) -> std::io::Result<()> {
187        <[T]>::deserialize(self, input)
188    }
189}
190
191impl<T: Deserializeable> Deserializeable for Option<T> {
192    fn deserialize<R: DataInput + ?Sized>(&mut self, input: &mut R) -> std::io::Result<()> {
193        match self {
194            Some(t) => t.deserialize(input),
195            None => Ok(()),
196        }
197    }
198}
199
200///
201/// A trait for types which can be deserialized and produce a new instance
202/// It's intended that this impl should be more efficient then creating a new instance, then reading into it
203pub trait DeserializeCopy: Deserializeable + Sized {
204    /// Deserializes the bytes on the stream and returns the resulting value or an error
205    fn deserialize_copy<R: DataInput + ?Sized>(input: &mut R) -> std::io::Result<Self>;
206}
207
208impl<T: DeserializeCopy> DeserializeCopy for Box<T> {
209    fn deserialize_copy<R: DataInput + ?Sized>(input: &mut R) -> std::io::Result<Self> {
210        T::deserialize_copy(input).map(Box::new)
211    }
212}
213
214// MCG too OP
215impl<T: DeserializeCopy, const N: usize> DeserializeCopy for [T; N] {
216    fn deserialize_copy<R: DataInput + ?Sized>(input: &mut R) -> std::io::Result<Self> {
217        let mut uninit = MaybeUninit::<[T; N]>::uninit();
218        let ptr = uninit.as_mut_ptr().cast::<T>();
219        for i in 0..N {
220            // SAFETY:
221            // i is between 0 and N, and the array has length N
222            let ptr = unsafe { ptr.add(i) };
223            // SAFETY:
224            // ptr is within the array uninit, and thus is valid
225            unsafe { ptr.write(T::deserialize_copy(input)?) }
226        }
227        // SAFETY:
228        // uninit is initialized by initializing each element in the above loop
229        Ok(unsafe { uninit.assume_init() })
230    }
231}
232
233/// A Trait for types that can perform binary IO Writes
234pub trait DataOutput: Write {
235    ///
236    /// Writes all of `bytes` to the underlying stream or returns an error
237    fn write_bytes(&mut self, bytes: &[u8]) -> std::io::Result<()> {
238        Ok(self.write_all(bytes)?)
239    }
240    ///
241    /// Writes byte to the underlying stream or returns an error
242    fn write_byte(&mut self, byte: u8) -> std::io::Result<()> {
243        self.write_bytes(slice::from_ref(&byte))
244    }
245    ///
246    /// Returns the byte order mode for the stream
247    fn byte_order(&self) -> ByteOrder;
248    ///
249    /// Sets the byte order mode on the stream
250    fn set_byte_order(&mut self, order: ByteOrder);
251}
252
253///
254/// A type that can serialize types according to LCS4
255pub struct DataOutputStream<W: ?Sized> {
256    order: ByteOrder,
257    write: W,
258}
259
260impl<W> DataOutputStream<W> {
261    ///
262    /// Constructs a new DataOutputStream from the given underlying stream and byte order mode
263    pub const fn new(write: W, order: ByteOrder) -> Self {
264        Self { write, order }
265    }
266
267    ///
268    /// Constructs a new DataOutputStream from the given underlying stream and the native byte order mode
269    pub const fn new_native(write: W) -> Self {
270        Self::new(write, ByteOrder::native())
271    }
272
273    ///
274    /// unwraps the DataOutputStream into the inner stream
275    pub fn into_inner(self) -> W {
276        self.write
277    }
278}
279
280impl<W: Write + ?Sized> Write for DataOutputStream<W> {
281    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
282        self.write.write(buf)
283    }
284
285    fn flush(&mut self) -> std::io::Result<()> {
286        self.write.flush()
287    }
288}
289
290impl<W: Write + ?Sized> DataOutput for DataOutputStream<W> {
291    fn byte_order(&self) -> ByteOrder {
292        self.order
293    }
294
295    fn set_byte_order(&mut self, order: ByteOrder) {
296        self.order = order;
297    }
298}
299
300impl<W: Write + Seek + ?Sized> Seek for DataOutputStream<W> {
301    fn seek(&mut self, pos: std::io::SeekFrom) -> std::io::Result<u64> {
302        self.write.seek(pos)
303    }
304}
305
306///
307/// A trait for types that can be serialized as a sequence of bytes according to LCS 4
308pub trait Serializeable {
309    ///
310    /// Serializes the type to the stream
311    fn serialize<W: DataOutput + ?Sized>(&self, output: &mut W) -> std::io::Result<()>;
312}
313
314impl<T: Serializeable + ?Sized> Serializeable for &T {
315    fn serialize<W: DataOutput + ?Sized>(&self, output: &mut W) -> std::io::Result<()> {
316        T::serialize(self, output)
317    }
318}
319impl<T: Serializeable + ?Sized> Serializeable for &mut T {
320    fn serialize<W: DataOutput + ?Sized>(&self, output: &mut W) -> std::io::Result<()> {
321        T::serialize(self, output)
322    }
323}
324
325impl<T: Serializeable + ?Sized> Serializeable for Box<T> {
326    fn serialize<W: DataOutput + ?Sized>(&self, output: &mut W) -> std::io::Result<()> {
327        T::serialize(self, output)
328    }
329}
330
331impl<T: Serializeable + ?Sized> Serializeable for Rc<T> {
332    fn serialize<W: DataOutput + ?Sized>(&self, output: &mut W) -> std::io::Result<()> {
333        T::serialize(self, output)
334    }
335}
336
337impl<T: Serializeable + ?Sized> Serializeable for Arc<T> {
338    fn serialize<W: DataOutput + ?Sized>(&self, output: &mut W) -> std::io::Result<()> {
339        T::serialize(self, output)
340    }
341}
342
343impl<T: Serializeable> Serializeable for [T] {
344    fn serialize<W: DataOutput + ?Sized>(&self, output: &mut W) -> std::io::Result<()> {
345        for t in self {
346            t.serialize(output)?;
347        }
348        Ok(())
349    }
350}
351
352impl<T: Serializeable, const N: usize> Serializeable for [T; N] {
353    fn serialize<W: DataOutput + ?Sized>(&self, output: &mut W) -> std::io::Result<()> {
354        for t in self {
355            t.serialize(output)?;
356        }
357        Ok(())
358    }
359}
360
361impl<T: Serializeable> Serializeable for Option<T> {
362    fn serialize<W: DataOutput + ?Sized>(&self, output: &mut W) -> std::io::Result<()> {
363        match self {
364            Some(v) => v.serialize(output),
365            None => Ok(()),
366        }
367    }
368}
369
370impl Deserializeable for u8 {
371    fn deserialize<R: DataInput + ?Sized>(&mut self, input: &mut R) -> std::io::Result<()> {
372        input.read_fully(slice::from_mut(self))
373    }
374}
375
376impl DeserializeCopy for u8 {
377    fn deserialize_copy<R: DataInput + ?Sized>(input: &mut R) -> std::io::Result<Self> {
378        input.read_byte()
379    }
380}
381
382impl Deserializeable for i8 {
383    fn deserialize<R: DataInput + ?Sized>(&mut self, input: &mut R) -> std::io::Result<()> {
384        // SAFETY:
385        // the pointer is from self
386        // i8 and u8 have the same size, alignment, and representation
387        input.read_fully(slice::from_mut(unsafe {
388            &mut *(self as *mut i8 as *mut u8)
389        }))
390    }
391}
392
393impl DeserializeCopy for i8 {
394    fn deserialize_copy<R: DataInput + ?Sized>(input: &mut R) -> std::io::Result<Self> {
395        input.read_byte().map(|u| u as i8)
396    }
397}
398
399impl Serializeable for u8 {
400    fn serialize<W: DataOutput + ?Sized>(&self, input: &mut W) -> std::io::Result<()> {
401        input.write_byte(*self)
402    }
403}
404
405impl Serializeable for i8 {
406    fn serialize<W: DataOutput + ?Sized>(&self, input: &mut W) -> std::io::Result<()> {
407        input.write_byte(*self as u8)
408    }
409}
410
411macro_rules! impl_for_tuples{
412    () => {
413        impl Deserializeable for (){
414            fn deserialize<S: DataInput + ?Sized>(&mut self,_: &mut S) -> std::io::Result<()>{
415                Ok(())
416            }
417        }
418        impl DeserializeCopy for (){
419            fn deserialize_copy<S: DataInput + ?Sized>(_: &mut S) -> std::io::Result<()>{
420                Ok(())
421            }
422        }
423        impl Serializeable for (){
424            fn serialize<S: DataOutput + ?Sized>(&self,_: &mut S) -> std::io::Result<()>{
425                Ok(())
426            }
427        }
428    };
429    ($a:ident) => {
430        #[allow(non_snake_case)]
431        impl<$a : Deserializeable + ?Sized> Deserializeable for ($a ,){
432            fn deserialize<S: DataInput + ?Sized>(&mut self,input: &mut S) -> std::io::Result<()>{
433                let ($a,) = self;
434                $a.deserialize(input)
435            }
436        }
437        #[allow(non_snake_case)]
438        impl<$a : DeserializeCopy> DeserializeCopy for ($a ,){
439            fn deserialize_copy<S: DataInput + ?Sized>(input: &mut S) -> std::io::Result<Self>{
440                Ok((<$a>::deserialize_copy(input)?,))
441            }
442        }
443        #[allow(non_snake_case)]
444        impl<$a : Serializeable + ?Sized> Serializeable for ($a ,){
445            fn serialize<S: DataOutput + ?Sized>(&self,input: &mut S) -> std::io::Result<()>{
446                let ($a,) = self;
447                $a.serialize(input)
448            }
449        }
450    };
451    ($($leading:ident),+) => {
452        #[allow(non_snake_case)]
453        impl<$($leading: Deserializeable),+ +?Sized> Deserializeable for ($($leading),+){
454            fn deserialize<S: DataInput + ?Sized>(&mut self,input: &mut S) -> std::io::Result<()>{
455                let ($($leading),+,) = self;
456                $({$leading .deserialize(input)?})*
457                Ok(())
458            }
459        }
460        #[allow(non_snake_case)]
461        impl<$($leading: DeserializeCopy),*> DeserializeCopy for ($($leading),* ){
462            fn deserialize_copy<S: DataInput + ?Sized>(input: &mut S) -> std::io::Result<Self>{
463                Ok(($($leading::deserialize_copy(input)?),*))
464            }
465        }
466        #[allow(non_snake_case)]
467        impl<$($leading: Serializeable),+ +?Sized> Serializeable for ($($leading),+){
468            fn serialize<S: DataOutput + ?Sized>(&self,input: &mut S) -> std::io::Result<()>{
469                let ($($leading),+,) = self;
470                $({$leading .serialize(input)?})*
471                Ok(())
472            }
473        }
474    };
475}
476
477impl_for_tuples!();
478impl_for_tuples!(A);
479impl_for_tuples!(A, B);
480impl_for_tuples!(A, B, C);
481impl_for_tuples!(A, B, C, D);
482impl_for_tuples!(A, B, C, D, E);
483impl_for_tuples!(A, B, C, D, E, F);
484impl_for_tuples!(A, B, C, D, E, F, G);
485impl_for_tuples!(A, B, C, D, E, F, G, H);
486impl_for_tuples!(A, B, C, D, E, F, G, H, I);
487impl_for_tuples!(A, B, C, D, E, F, G, H, I, J);
488impl_for_tuples!(A, B, C, D, E, F, G, H, I, J, K);
489impl_for_tuples!(A, B, C, D, E, F, G, H, I, J, K, L);
490
491macro_rules! impl_for_primitives{
492    [$($ty:ty),+] => {
493        $(
494            impl Deserializeable for $ty{
495                fn deserialize<R: DataInput + ?Sized>(&mut self,input: &mut R) -> std::io::Result<()>{
496                    let mut bytes = [0u8;std::mem::size_of::<$ty>()];
497                    input.read_fully(&mut bytes)?;
498                    *self = match input.byte_order(){
499                        ByteOrder::BigEndian => <$ty>::from_be_bytes(bytes),
500                        ByteOrder::LittleEndian => <$ty>::from_le_bytes(bytes)
501                    };
502                    Ok(())
503                }
504            }
505            impl DeserializeCopy for $ty{
506                fn deserialize_copy<R: DataInput + ?Sized>(input: &mut R) -> std::io::Result<Self>{
507                    let mut bytes = [0u8;std::mem::size_of::<$ty>()];
508                    input.read_fully(&mut bytes)?;
509                    Ok(match input.byte_order(){
510                        ByteOrder::BigEndian => <$ty>::from_be_bytes(bytes),
511                        ByteOrder::LittleEndian => <$ty>::from_le_bytes(bytes)
512                    })
513                }
514            }
515            impl Serializeable for $ty{
516                fn serialize<W: DataOutput + ?Sized>(&self,output: &mut W) -> std::io::Result<()>{
517                    let bytes = match output.byte_order(){
518                        ByteOrder::BigEndian => <$ty>::to_be_bytes(*self),
519                        ByteOrder::LittleEndian => <$ty>::to_le_bytes(*self)
520                    };
521                    output.write_bytes(&bytes)
522                }
523            }
524        )+
525    }
526}
527
528impl_for_primitives![i16, u16, i32, u32, i64, u64, i128, u128, f32, f64];
529
530impl Deserializeable for String {
531    fn deserialize<R: DataInput + ?Sized>(&mut self, input: &mut R) -> std::io::Result<()> {
532        let size = u16::deserialize_copy(input)? as usize;
533        let mut vec = vec![0u8; size];
534        input.read_fully(&mut vec)?;
535        *self =
536            String::from_utf8(vec).map_err(|e| std::io::Error::new(ErrorKind::InvalidData, e))?;
537        Ok(())
538    }
539}
540
541impl DeserializeCopy for String {
542    fn deserialize_copy<R: DataInput + ?Sized>(input: &mut R) -> std::io::Result<Self> {
543        let size = u16::deserialize_copy(input)? as usize;
544        let mut vec = vec![0u8; size];
545        input.read_fully(&mut vec)?;
546        String::from_utf8(vec).map_err(|e| std::io::Error::new(ErrorKind::InvalidData, e))
547    }
548}
549
550///
551/// An error type that indicates a particular value is outside of a range imposed for {de,}serialization
552#[derive(Copy, Clone, PartialEq, Eq, Debug)]
553pub struct OutOfRange<T>(pub T);
554
555impl<T: Display> Display for OutOfRange<T> {
556    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
557        f.write_fmt(format_args!(
558            "{} is not in range for this operation",
559            &self.0
560        ))
561    }
562}
563
564impl<T> StdError for OutOfRange<T> where Self: std::fmt::Debug + Display {}
565
566impl Serializeable for String {
567    fn serialize<W: DataOutput + ?Sized>(&self, output: &mut W) -> std::io::Result<()> {
568        let size = self.len();
569        if size > u16::MAX as usize {
570            Err(std::io::Error::new(
571                ErrorKind::InvalidData,
572                OutOfRange(size),
573            ))
574        } else {
575            (size as u16).serialize(output)?;
576            output.write_bytes(self.as_bytes())
577        }
578    }
579}