diff options
Diffstat (limited to 'src/serialise')
-rw-r--r-- | src/serialise/mod.rs | 186 | ||||
-rw-r--r-- | src/serialise/test.rs | 25 |
2 files changed, 179 insertions, 32 deletions
diff --git a/src/serialise/mod.rs b/src/serialise/mod.rs index b8f6dba..98c1417 100644 --- a/src/serialise/mod.rs +++ b/src/serialise/mod.rs @@ -22,7 +22,7 @@ #[cfg(test)] mod test; -use crate::SStream; +use crate::Sstream; use std::convert::Infallible; use std::mem::size_of; @@ -30,17 +30,22 @@ use std::num::NonZero; /// Denotes a type capable of being serialised. pub trait Serialise: Sized { + /// The maximum ammount of bytes that can result from serialisation. + const SERIALISE_LIMIT: usize; + /// Serialises `self` into a byte stream. /// - /// One may assume that the resulting stream has at most the same ammount of bytes as before serialisation. - /// Therefore, not observing this rule is a logic error. - fn serialise(&self, stream: &mut SStream); + /// This function should not append *more* bytes than specified in [`SERIALISE_LIMIT`](Serialise::SERIALISE_LIMIT). + /// Doing so is considered a logic error. + fn serialise(&self, stream: &mut Sstream); } macro_rules! impl_float { ($type:ty) => { impl Serialise for $type { - fn serialise(&self, stream: &mut SStream) { + const SERIALISE_LIMIT: usize = size_of::<$type>(); + + fn serialise(&self, stream: &mut Sstream) { stream.append(&self.to_be_bytes()) } } @@ -50,13 +55,17 @@ macro_rules! impl_float { macro_rules! impl_int { ($type:ty) => { impl Serialise for $type { - fn serialise(&self, stream: &mut SStream) { + const SERIALISE_LIMIT: usize = size_of::<$type>(); + + fn serialise(&self, stream: &mut Sstream) { stream.append(&self.to_be_bytes()) } } impl Serialise for NonZero<$type> { - fn serialise(&self, stream: &mut SStream) { + const SERIALISE_LIMIT: usize = size_of::<$type>(); + + fn serialise(&self, stream: &mut Sstream) { self.get().serialise(stream) } } @@ -67,7 +76,11 @@ impl<T0, T1> Serialise for (T0, T1) where T0: Serialise, T1: Serialise, { - fn serialise(&self, stream: &mut SStream) { + const SERIALISE_LIMIT: usize = + T0::SERIALISE_LIMIT + + T1::SERIALISE_LIMIT; + + fn serialise(&self, stream: &mut Sstream) { self.0.serialise(stream); self.1.serialise(stream); } @@ -78,7 +91,12 @@ where T0: Serialise, T1: Serialise, T2: Serialise, { - fn serialise(&self, stream: &mut SStream) { + const SERIALISE_LIMIT: usize = + T0::SERIALISE_LIMIT + + T1::SERIALISE_LIMIT + + T2::SERIALISE_LIMIT; + + fn serialise(&self, stream: &mut Sstream) { self.0.serialise(stream); self.1.serialise(stream); self.2.serialise(stream); @@ -91,7 +109,13 @@ where T1: Serialise, T2: Serialise, T3: Serialise, { - fn serialise(&self, stream: &mut SStream) { + const SERIALISE_LIMIT: usize = + T0::SERIALISE_LIMIT + + T1::SERIALISE_LIMIT + + T2::SERIALISE_LIMIT + + T3::SERIALISE_LIMIT; + + fn serialise(&self, stream: &mut Sstream) { self.0.serialise(stream); self.1.serialise(stream); self.2.serialise(stream); @@ -106,7 +130,14 @@ where T2: Serialise, T3: Serialise, T4: Serialise, { - fn serialise(&self, stream: &mut SStream) { + const SERIALISE_LIMIT: usize = + T0::SERIALISE_LIMIT + + T1::SERIALISE_LIMIT + + T2::SERIALISE_LIMIT + + T3::SERIALISE_LIMIT + + T4::SERIALISE_LIMIT; + + fn serialise(&self, stream: &mut Sstream) { self.0.serialise(stream); self.1.serialise(stream); self.2.serialise(stream); @@ -123,7 +154,15 @@ where T3: Serialise, T4: Serialise, T5: Serialise, { - fn serialise(&self, stream: &mut SStream) { + const SERIALISE_LIMIT: usize = + T0::SERIALISE_LIMIT + + T1::SERIALISE_LIMIT + + T2::SERIALISE_LIMIT + + T3::SERIALISE_LIMIT + + T4::SERIALISE_LIMIT + + T5::SERIALISE_LIMIT; + + fn serialise(&self, stream: &mut Sstream) { self.0.serialise(stream); self.1.serialise(stream); self.2.serialise(stream); @@ -142,7 +181,16 @@ where T4: Serialise, T5: Serialise, T6: Serialise, { - fn serialise(&self, stream: &mut SStream) { + const SERIALISE_LIMIT: usize = + T0::SERIALISE_LIMIT + + T1::SERIALISE_LIMIT + + T2::SERIALISE_LIMIT + + T3::SERIALISE_LIMIT + + T4::SERIALISE_LIMIT + + T5::SERIALISE_LIMIT + + T6::SERIALISE_LIMIT; + + fn serialise(&self, stream: &mut Sstream) { self.0.serialise(stream); self.1.serialise(stream); self.2.serialise(stream); @@ -163,7 +211,17 @@ where T5: Serialise, T6: Serialise, T7: Serialise, { - fn serialise(&self, stream: &mut SStream) { + const SERIALISE_LIMIT: usize = + T0::SERIALISE_LIMIT + + T1::SERIALISE_LIMIT + + T2::SERIALISE_LIMIT + + T3::SERIALISE_LIMIT + + T4::SERIALISE_LIMIT + + T5::SERIALISE_LIMIT + + T6::SERIALISE_LIMIT + + T7::SERIALISE_LIMIT; + + fn serialise(&self, stream: &mut Sstream) { self.0.serialise(stream); self.1.serialise(stream); self.2.serialise(stream); @@ -186,7 +244,18 @@ where T6: Serialise, T7: Serialise, T8: Serialise, { - fn serialise(&self, stream: &mut SStream) { + const SERIALISE_LIMIT: usize = + T0::SERIALISE_LIMIT + + T1::SERIALISE_LIMIT + + T2::SERIALISE_LIMIT + + T3::SERIALISE_LIMIT + + T4::SERIALISE_LIMIT + + T5::SERIALISE_LIMIT + + T6::SERIALISE_LIMIT + + T7::SERIALISE_LIMIT + + T8::SERIALISE_LIMIT; + + fn serialise(&self, stream: &mut Sstream) { self.0.serialise(stream); self.1.serialise(stream); self.2.serialise(stream); @@ -211,7 +280,19 @@ where T7: Serialise, T8: Serialise, T9: Serialise, { - fn serialise(&self, stream: &mut SStream) { + const SERIALISE_LIMIT: usize = + T0::SERIALISE_LIMIT + + T1::SERIALISE_LIMIT + + T2::SERIALISE_LIMIT + + T3::SERIALISE_LIMIT + + T4::SERIALISE_LIMIT + + T5::SERIALISE_LIMIT + + T6::SERIALISE_LIMIT + + T7::SERIALISE_LIMIT + + T8::SERIALISE_LIMIT + + T9::SERIALISE_LIMIT; + + fn serialise(&self, stream: &mut Sstream) { self.0.serialise(stream); self.1.serialise(stream); self.2.serialise(stream); @@ -238,7 +319,20 @@ where T8: Serialise, T9: Serialise, T10: Serialise, { - fn serialise(&self, stream: &mut SStream) { + const SERIALISE_LIMIT: usize = + T0::SERIALISE_LIMIT + + T1::SERIALISE_LIMIT + + T2::SERIALISE_LIMIT + + T3::SERIALISE_LIMIT + + T4::SERIALISE_LIMIT + + T5::SERIALISE_LIMIT + + T6::SERIALISE_LIMIT + + T7::SERIALISE_LIMIT + + T8::SERIALISE_LIMIT + + T9::SERIALISE_LIMIT + + T10::SERIALISE_LIMIT; + + fn serialise(&self, stream: &mut Sstream) { self.0.serialise(stream); self.1.serialise(stream); self.2.serialise(stream); @@ -267,7 +361,21 @@ where T9: Serialise, T10: Serialise, T11: Serialise, { - fn serialise(&self, stream: &mut SStream) { + const SERIALISE_LIMIT: usize = + T0::SERIALISE_LIMIT + + T1::SERIALISE_LIMIT + + T2::SERIALISE_LIMIT + + T3::SERIALISE_LIMIT + + T4::SERIALISE_LIMIT + + T5::SERIALISE_LIMIT + + T6::SERIALISE_LIMIT + + T7::SERIALISE_LIMIT + + T8::SERIALISE_LIMIT + + T9::SERIALISE_LIMIT + + T10::SERIALISE_LIMIT + + T11::SERIALISE_LIMIT; + + fn serialise(&self, stream: &mut Sstream) { self.0.serialise(stream); self.1.serialise(stream); self.2.serialise(stream); @@ -284,7 +392,9 @@ where } impl<T: Serialise, const N: usize> Serialise for [T; N] { - fn serialise(&self, stream: &mut SStream) { + const SERIALISE_LIMIT: usize = T::SERIALISE_LIMIT * N; + + fn serialise(&self, stream: &mut Sstream) { u64::try_from(self.len()).unwrap().serialise(stream); for v in self { v.serialise(stream) } @@ -292,35 +402,45 @@ impl<T: Serialise, const N: usize> Serialise for [T; N] { } impl Serialise for () { - fn serialise(&self, _stream: &mut SStream) { } + const SERIALISE_LIMIT: usize = size_of::<Self>(); + + fn serialise(&self, _stream: &mut Sstream) { } } impl Serialise for bool { - fn serialise(&self, stream: &mut SStream) { + const SERIALISE_LIMIT: usize = size_of::<Self>(); + + fn serialise(&self, stream: &mut Sstream) { u8::from(*self).serialise(stream) } } impl Serialise for char { - fn serialise(&self, stream: &mut SStream) { + const SERIALISE_LIMIT: usize = size_of::<Self>(); + + fn serialise(&self, stream: &mut Sstream) { u32::from(*self).serialise(stream) } } impl Serialise for Infallible { - fn serialise(&self, _stream: &mut SStream) { unreachable!() } + const SERIALISE_LIMIT: usize = size_of::<Self>(); + + fn serialise(&self, _stream: &mut Sstream) { unreachable!() } } impl<T: Serialise> Serialise for Option<T> { - fn serialise(&self, stream: &mut SStream) { + const SERIALISE_LIMIT: usize = T::SERIALISE_LIMIT + 0x1; + + fn serialise(&self, stream: &mut Sstream) { match *self { None => { - stream.append(&[0x00]); + stream.append_byte(0x00); stream.append(&vec![0x00; size_of::<T>()]); }, Some(ref v) => { - stream.append(&[0x01]); + stream.append_byte(0x01); v.serialise(stream); }, }; @@ -328,15 +448,23 @@ impl<T: Serialise> Serialise for Option<T> { } impl<T: Serialise, E: Serialise> Serialise for Result<T, E> { - fn serialise(&self, stream: &mut SStream) { + const SERIALISE_LIMIT: usize = const { + if size_of::<T>() > size_of::<T>() { + size_of::<T>() + } else { + size_of::<E>() + } + }; + + fn serialise(&self, stream: &mut Sstream) { match *self { Ok(ref v) => { - stream.append(&[0x00]); + stream.append_byte(0x00); v.serialise(stream); }, Err(ref e) => { - stream.append(&[0x01]); + stream.append_byte(0x01); e.serialise(stream); }, }; diff --git a/src/serialise/test.rs b/src/serialise/test.rs index e0a0004..245c2c3 100644 --- a/src/serialise/test.rs +++ b/src/serialise/test.rs @@ -1,10 +1,29 @@ -// Copyright 2022-2024 Gabriel Bjørnager Jensen. +// Copyright 2024 Gabriel Bjørnager Jensen. +// +// This file is part of bzipper. +// +// bzipper is free software: you can redistribute +// it and/or modify it under the terms of the GNU +// Lesser General Public License as published by +// the Free Software Foundation, either version 3 +// of the License, or (at your option) any later +// version. +// +// bzipper is distributed in the hope that it will +// be useful, but WITHOUT ANY WARRANTY; without +// even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Less- +// er General Public License along with bzipper. If +// not, see <https://www.gnu.org/licenses/>. -use crate::{FixedString, SStream, Serialise}; +use crate::{FixedString, Serialise, Sstream}; #[test] fn test_serialise() { - let mut stream = SStream::new(); + let mut stream = Sstream::new(); 0x00_u8.serialise(&mut stream); 0xFF_u8.serialise(&mut stream); |