diff options
Diffstat (limited to 'old/evc/src/format/ser.rs')
-rw-r--r-- | old/evc/src/format/ser.rs | 335 |
1 files changed, 335 insertions, 0 deletions
diff --git a/old/evc/src/format/ser.rs b/old/evc/src/format/ser.rs new file mode 100644 index 0000000..f063377 --- /dev/null +++ b/old/evc/src/format/ser.rs @@ -0,0 +1,335 @@ +use anyhow::Context; +use std::io::{Read, Write}; + +use crate::helpers::{matrix::Mat2, vector::Vec2}; + +pub trait Sink { + fn put<V: Ser>(&mut self, value: V) -> anyhow::Result<()>; +} +pub trait Source { + fn get<V: Ser>(&mut self) -> anyhow::Result<V>; +} + +impl<T: Write> Sink for T { + fn put<V: Ser>(&mut self, value: V) -> anyhow::Result<()> { + value.write(self) + } +} +impl<T: Read> Source for T { + fn get<V: Ser>(&mut self) -> anyhow::Result<V> { + V::read(self) + } +} + +pub trait Ser: Sized { + fn write(&self, sink: &mut impl Write) -> anyhow::Result<()>; + fn read(source: &mut impl Read) -> anyhow::Result<Self>; +} + +impl<A: Ser, B: Ser> Ser for (A, B) { + fn write(&self, sink: &mut impl Write) -> anyhow::Result<()> { + self.0.write(sink).context("first tuple field")?; + self.1.write(sink).context("second tuple field")?; + Ok(()) + } + + fn read(source: &mut impl Read) -> anyhow::Result<Self> { + Ok((A::read(source)?, B::read(source)?)) + } +} +impl<A: Ser, B: Ser, C: Ser> Ser for (A, B, C) { + fn write(&self, sink: &mut impl Write) -> anyhow::Result<()> { + self.0.write(sink).context("first tuple field")?; + self.1.write(sink).context("second tuple field")?; + self.2.write(sink).context("third tuple field")?; + Ok(()) + } + + fn read(source: &mut impl Read) -> anyhow::Result<Self> { + Ok((A::read(source)?, B::read(source)?, C::read(source)?)) + } +} +impl<A: Ser, B: Ser, C: Ser, D: Ser> Ser for (A, B, C, D) { + fn write(&self, sink: &mut impl Write) -> anyhow::Result<()> { + self.0.write(sink).context("first tuple field")?; + self.1.write(sink).context("second tuple field")?; + self.2.write(sink).context("third tuple field")?; + self.3.write(sink).context("fourth tuple field")?; + Ok(()) + } + + fn read(source: &mut impl Read) -> anyhow::Result<Self> { + Ok(( + A::read(source)?, + B::read(source)?, + C::read(source)?, + D::read(source)?, + )) + } +} + +impl<A: Ser, const N: usize> Ser for [A; N] { + fn write(&self, sink: &mut impl Write) -> anyhow::Result<()> { + for e in self { + e.write(sink).context("some array")?; + } + Ok(()) + } + + fn read(source: &mut impl Read) -> anyhow::Result<Self> { + let mut k: [A; N] = unsafe { std::mem::zeroed() }; + for i in 0..N { + k[i] = A::read(source)?; + } + Ok(k) + } +} + +impl<T: Ser> Ser for Vec<T> { + fn write(&self, sink: &mut impl Write) -> anyhow::Result<()> { + self.len().write(sink)?; + for e in self { + e.write(sink).context("some vec")?; + } + Ok(()) + } + + fn read(source: &mut impl Read) -> anyhow::Result<Self> { + let mut v = vec![]; + for _ in 0..usize::read(source)? { + v.push(T::read(source)?) + } + Ok(v) + } +} + +pub trait ConstSizeSerExt: Sized { + fn write_const_size(&self, sink: &mut impl Write, size: usize) -> anyhow::Result<()>; + fn read_const_size(source: &mut impl Read, size: usize) -> anyhow::Result<Self>; +} +impl<T: Ser> ConstSizeSerExt for Vec<T> { + fn write_const_size(&self, sink: &mut impl Write, size: usize) -> anyhow::Result<()> { + assert_eq!(self.len(), size); + for e in self { + e.write(sink).context("some const-size vec")?; + } + Ok(()) + } + + fn read_const_size(source: &mut impl Read, size: usize) -> anyhow::Result<Self> { + let mut v = vec![]; + for _ in 0..size { + v.push(T::read(source)?) + } + Ok(v) + } +} + +impl Ser for u8 { + fn write(&self, sink: &mut impl Write) -> anyhow::Result<()> { + Ok(sink.write_all(&[*self]).context("write u8")?) + } + fn read(source: &mut impl Read) -> anyhow::Result<Self> { + let mut buf = [0u8; 1]; + source.read_exact(&mut buf)?; + Ok(buf[0]) + } +} +impl Ser for i8 { + fn write(&self, sink: &mut impl Write) -> anyhow::Result<()> { + Ok(sink + .write_all(&unsafe { std::mem::transmute_copy::<_, [u8; 1]>(self) }) + .context("write i8")?) + } + fn read(source: &mut impl Read) -> anyhow::Result<Self> { + let mut buf = [0u8; 1]; + source.read_exact(&mut buf)?; + Ok(unsafe { std::mem::transmute_copy(&buf) }) + } +} +impl Ser for u16 { + fn write(&self, sink: &mut impl Write) -> anyhow::Result<()> { + Ok(sink + .write_all(&unsafe { std::mem::transmute_copy::<_, [u8; 2]>(self) }) + .context("write u16")?) + } + fn read(source: &mut impl Read) -> anyhow::Result<Self> { + let mut buf = [0u8; 2]; + source.read_exact(&mut buf)?; + Ok(unsafe { std::mem::transmute_copy(&buf) }) + } +} +impl Ser for u32 { + fn write(&self, sink: &mut impl Write) -> anyhow::Result<()> { + Ok(sink + .write_all(&unsafe { std::mem::transmute_copy::<_, [u8; 4]>(self) }) + .context("write u32")?) + } + fn read(source: &mut impl Read) -> anyhow::Result<Self> { + let mut buf = [0u8; 4]; + source.read_exact(&mut buf)?; + Ok(unsafe { std::mem::transmute_copy(&buf) }) + } +} +impl Ser for u64 { + fn write(&self, sink: &mut impl Write) -> anyhow::Result<()> { + Ok(sink + .write_all(&unsafe { std::mem::transmute_copy::<_, [u8; 8]>(self) }) + .context("write u64")?) + } + fn read(source: &mut impl Read) -> anyhow::Result<Self> { + let mut buf = [0u8; 8]; + source.read_exact(&mut buf)?; + Ok(unsafe { std::mem::transmute_copy(&buf) }) + } +} +impl Ser for usize { + fn write(&self, sink: &mut impl Write) -> anyhow::Result<()> { + Ok(sink + .write_all(&unsafe { std::mem::transmute_copy::<_, [u8; 8]>(self) }) + .context("write usize")?) + } + fn read(source: &mut impl Read) -> anyhow::Result<Self> { + let mut buf = [0u8; 8]; + source.read_exact(&mut buf)?; + Ok(unsafe { std::mem::transmute_copy(&buf) }) + } +} +impl Ser for isize { + fn write(&self, sink: &mut impl Write) -> anyhow::Result<()> { + Ok(sink + .write_all(&unsafe { std::mem::transmute_copy::<_, [u8; 8]>(self) }) + .context("write isize")?) + } + fn read(source: &mut impl Read) -> anyhow::Result<Self> { + let mut buf = [0u8; 8]; + source.read_exact(&mut buf)?; + Ok(unsafe { std::mem::transmute_copy(&buf) }) + } +} +impl Ser for f32 { + fn write(&self, sink: &mut impl Write) -> anyhow::Result<()> { + Ok(sink + .write_all(&unsafe { std::mem::transmute_copy::<_, [u8; 4]>(self) }) + .context("write f32")?) + } + fn read(source: &mut impl Read) -> anyhow::Result<Self> { + let mut buf = [0u8; 4]; + source.read_exact(&mut buf)?; + Ok(unsafe { std::mem::transmute_copy(&buf) }) + } +} +impl Ser for f64 { + fn write(&self, sink: &mut impl Write) -> anyhow::Result<()> { + Ok(sink + .write_all(&unsafe { std::mem::transmute_copy::<_, [u8; 8]>(self) }) + .context("write f64")?) + } + fn read(source: &mut impl Read) -> anyhow::Result<Self> { + let mut buf = [0u8; 8]; + source.read_exact(&mut buf)?; + Ok(unsafe { std::mem::transmute_copy(&buf) }) + } +} + +impl<T: Ser + Copy> Ser for Vec2<T> { + fn write(&self, sink: &mut impl std::io::Write) -> anyhow::Result<()> { + sink.put((self.x, self.y)) + } + + fn read(source: &mut impl std::io::Read) -> anyhow::Result<Self> { + let (x, y) = source.get()?; + Ok(Vec2 { x, y }) + } +} +impl<T: Ser + Copy> Ser for Mat2<T> { + fn write(&self, sink: &mut impl std::io::Write) -> anyhow::Result<()> { + sink.put((self.a, self.b, self.c, self.d)) + } + + fn read(source: &mut impl std::io::Read) -> anyhow::Result<Self> { + let (a, b, c, d) = source.get()?; + Ok(Mat2 { a, b, c, d }) + } +} + +pub struct Small<T>(pub T); +impl Ser for Small<Vec2<isize>> { + fn write(&self, sink: &mut impl std::io::Write) -> anyhow::Result<()> { + sink.put((self.0.x as i8, self.0.y as i8)) + } + + fn read(source: &mut impl std::io::Read) -> anyhow::Result<Self> { + let (x, y): (i8, i8) = source.get()?; + Ok(Small(Vec2 { + x: x as isize, + y: y as isize, + })) + } +} + +pub fn map_scalar8(v: i8) -> f32 { + match v { + 0 => 0.0, + x if x > 0 => 2f32.powf((x as f32).abs() / 2.0 - 2.0), + x => -2f32.powf((-x as f32).abs() / 2.0 - 2.0), + } +} +// const SCALAR8: [f32; 256] = gen_scalar8_lookup(); +// const fn gen_scalar8_lookup() -> [f32; 256] { +// let mut a = [0.0; 256]; +// let mut i = 0usize; +// while i < 256 { +// a[i as usize] = if i == 0 { +// 0.0 +// } else { +// let x = i as i8 as f32; +// x.signum() * 2f32.powf(x.abs() / 2.0 - 2.0) +// }; +// i += 1; +// } +// a +// } + +#[cfg(test)] +mod test { + use super::{Ser, Sink}; + use crate::format::header::Header; + use crate::{format::ser::Source, helpers::vector::Vec2}; + use std::fmt::Debug; + use std::io::Cursor; + + fn test_ser<T: PartialEq + Ser + Debug + Clone>(value: T) { + let mut buf = vec![]; + Cursor::new(&mut buf).put(value.clone()).unwrap(); + assert_eq!(value, Cursor::new(&mut buf).get().unwrap()); + } + + #[test] + fn simple() { + let mut buf = vec![]; + Cursor::new(&mut buf).put(10usize).unwrap(); + assert_eq!(10usize, Cursor::new(&mut buf).get().unwrap()); + } + #[test] + fn tuple() { + let mut buf = vec![]; + Cursor::new(&mut buf).put((10usize, 5u8, 3u16)).unwrap(); + assert_eq!((10usize, 5u8, 3u16), Cursor::new(&mut buf).get().unwrap()); + } + #[test] + fn header() { + test_ser(Header { + frame_count: 123, + resolution: Vec2 { x: 13, y: 37 }, + }); + } + #[test] + fn vec() { + test_ser(vec![1u16, 2, 3, 4]); + } + #[test] + fn array() { + test_ser([1u16, 2, 3, 4]); + } +} |