From 5d2747e26f51cc2344a6bd95f93457248fdfebd8 Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Thu, 29 Feb 2024 17:04:28 -0500 Subject: fin prob --- matrix-lang/src/binary/prim.rs | 109 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 matrix-lang/src/binary/prim.rs (limited to 'matrix-lang/src/binary/prim.rs') diff --git a/matrix-lang/src/binary/prim.rs b/matrix-lang/src/binary/prim.rs new file mode 100644 index 0000000..44e6898 --- /dev/null +++ b/matrix-lang/src/binary/prim.rs @@ -0,0 +1,109 @@ +use super::Primitive; +use std::io::{self, Read, Write}; + +macro_rules! marshal_number { + ($type:ident, $byte:expr) => { + impl Primitive for $type { + fn write(&self, write: &mut W) -> io::Result<()> { + write.write(&self.to_le_bytes())?; + Ok(()) + } + + fn read(read: &mut R) -> io::Result { + let mut bytes = [0u8; $byte]; + read.read_exact(&mut bytes)?; + Ok(Self::from_le_bytes(bytes)) + } + } + }; +} + +marshal_number!(u8, 1); +marshal_number!(u16, 2); +marshal_number!(i16, 2); +marshal_number!(u32, 4); +marshal_number!(i64, 8); +marshal_number!(f64, 8); + +impl Primitive for bool { + fn write(&self, write: &mut W) -> io::Result<()> { + if *self { + write.write(&[1u8; 1])?; + } else { + write.write(&[0u8; 1])?; + } + Ok(()) + } + + fn read(read: &mut R) -> io::Result { + let mut bytes = [0u8; 1]; + read.read_exact(&mut bytes)?; + if bytes[0] == 1 { + Ok(true) + } else { + Ok(false) + } + } +} + +impl Primitive for String { + fn write(&self, write: &mut W) -> io::Result<()> { + let bytes = self.as_bytes(); + let len = bytes.len(); + write.write(&(len as u32).to_le_bytes())?; + write.write(&bytes)?; + Ok(()) + } + + fn read(read: &mut R) -> io::Result { + let len = usize::read(read)?; + let mut bytes = vec![0u8; len]; + read.read_exact(&mut bytes)?; + Ok(String::from_utf8_lossy(bytes.as_slice()).to_string()) + } +} + +impl Primitive for usize { + fn write(&self, write: &mut W) -> io::Result<()> { + (*self as u32).write(write) + } + + fn read(read: &mut R) -> io::Result { + Ok(u32::read(read)? as usize) + } +} + +pub struct VarInt(pub usize); + +impl Primitive for VarInt { + fn write(&self, write: &mut W) -> io::Result<()> { + let mut data = self.0; + loop { + let mut byte = (data & 0x7F) as u8; + data >>= 7; + if data != 0 { + byte += 0x80; + } + write.write(&[byte; 1])?; + if data == 0 { + return Ok(()) + } + } + } + + fn read(read: &mut R) -> io::Result { + let mut buf = [0]; + let mut result = 0usize; + for count in 0..8 { + if read.read(&mut buf)? != 1 { + return Ok(Self(0)) + } + let byte = buf[0]; + result |= ((byte & 0x7F) as usize) << (7 * count); + if byte & 0x80 == 0 { + return Ok(Self(result)) + } + } + Ok(Self(0)) + } +} -- cgit v1.2.3-freya