diff --git a/Cargo.toml b/Cargo.toml index 45c94ef..55b17a9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [workspace] -members = ["accumulator", "network"] -default-members = ["accumulator", "network"] +members = ["accumulator", "hintfile", "network"] +default-members = ["accumulator", "hintfile", "network"] resolver = "3" [workspace.dependencies] diff --git a/hintfile/Cargo.toml b/hintfile/Cargo.toml new file mode 100644 index 0000000..fc0e009 --- /dev/null +++ b/hintfile/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "hintfile" +version = "0.1.0" +edition = "2024" + +[dependencies] diff --git a/hintfile/src/lib.rs b/hintfile/src/lib.rs new file mode 100644 index 0000000..fefd188 --- /dev/null +++ b/hintfile/src/lib.rs @@ -0,0 +1,65 @@ +use std::io::{self, Read, Write}; + +pub fn write_compact_size(value: u64, writer: &mut W) -> Result<(), io::Error> { + match value { + 0..=0xFC => { + writer.write_all(&[value as u8]) // Cast ok because of match. + } + 0xFD..=0xFFFF => { + let v = (value as u16).to_le_bytes(); // Cast ok because of match. + writer.write_all(&[0xFD, v[0], v[1]]) + } + 0x10000..=0xFFFFFFFF => { + let v = (value as u32).to_le_bytes(); // Cast ok because of match. + writer.write_all(&[0xFE, v[0], v[1], v[2], v[3]]) + } + _ => panic!("unexpected large offset"), + } +} + +pub fn read_compact_size(reader: &mut R) -> Result { + let mut buf: [u8; 1] = [0; 1]; + reader.read_exact(&mut buf)?; + let prefix = buf[0]; + match prefix { + 0xFD => { + let mut buf: [u8; 2] = [0; 2]; + reader.read_exact(&mut buf)?; + Ok(u16::from_le_bytes(buf) as u64) + } + 0xFE => { + let mut buf: [u8; 4] = [0; 4]; + reader.read_exact(&mut buf)?; + Ok(u32::from_le_bytes(buf) as u64) + } + 0..=0xFC => Ok(prefix as u64), + _ => panic!("unexpected large offset"), + } +} + +#[cfg(test)] +mod tests { + use crate::{read_compact_size, write_compact_size}; + + #[test] + fn deser_roundtrip() { + let mut buf = Vec::new(); + let less: u8 = 0xFB; + write_compact_size(less as u64, &mut buf).unwrap(); + let read_cs = read_compact_size(&mut buf.as_slice()).unwrap(); + let cast_less = read_cs as u8; + assert_eq!(less, cast_less); + let mut buf = Vec::new(); + let median: u16 = 0xFFF; + write_compact_size(median as u64, &mut buf).unwrap(); + let read_cs = read_compact_size(&mut buf.as_slice()).unwrap(); + let cast_median = read_cs as u16; + assert_eq!(median, cast_median); + let mut buf = Vec::new(); + let more: u32 = 0xFFFFF; + write_compact_size(more as u64, &mut buf).unwrap(); + let read_cs = read_compact_size(&mut buf.as_slice()).unwrap(); + let cast_more = read_cs as u32; + assert_eq!(more, cast_more); + } +}