From 7d6cca50bc032478b48d2cfbe9f621ea53621d59 Mon Sep 17 00:00:00 2001 From: Chris Mikkelson Date: Mon, 5 Aug 2024 00:01:41 -0600 Subject: [PATCH] metadata: read from file-like object instaed of buf --- src/metadata.rs | 66 +++++++++++++++++++++---------------------------- 1 file changed, 28 insertions(+), 38 deletions(-) diff --git a/src/metadata.rs b/src/metadata.rs index 20485a8..df08ce9 100644 --- a/src/metadata.rs +++ b/src/metadata.rs @@ -14,6 +14,8 @@ struct mtbl_metadata { */ use crate::compression::Compression; use crate::Result; +use integer_encoding::{FixedIntReader, FixedIntWriter}; +use std::io::SeekFrom; use std::mem::size_of; const MTBL_MAGIC: u32 = 0x4D54424C; @@ -31,53 +33,40 @@ pub(crate) struct Metadata { pub(crate) bytes_values: usize, } -fn try_read64(b: &mut &[u8]) -> Result { - if b.len() < size_of::() { - Err("buffer too short".into()) - } else { - let (n, rest) = b.split_at(size_of::()); - *b = rest; - Ok(u64::from_be_bytes(n.try_into()?)) - } -} - -fn write64(n: u64, mut out: impl std::io::Write) -> std::io::Result<()> { - out.write_all(n.to_be_bytes().as_slice()) -} - impl Metadata { - pub(crate) fn from_bytes(mut b: &[u8]) -> Result { - if b.len() < size_of::() { - return Err("metadata block too short".into()); - } else if u32::from_be_bytes(b[b.len() - size_of::()..].try_into()?) != MTBL_MAGIC { + pub(crate) fn read_from(mut inp: impl std::io::Read + std::io::Seek) -> Result { + inp.seek(SeekFrom::Start(512 - size_of::() as u64))?; + if inp.read_fixedint::()? != MTBL_MAGIC { return Err("bad magic".into()); } + inp.seek(SeekFrom::Current(-512))?; + Ok(Self { - index_block_offset: try_read64(&mut b)? as usize, - data_block_size: try_read64(&mut b)? as usize, - compression_algorithm: try_read64(&mut b)?.try_into()?, - count_entries: try_read64(&mut b)?, - count_data_blocks: try_read64(&mut b)?, - bytes_data_blocks: try_read64(&mut b)? as usize, - bytes_index_block: try_read64(&mut b)? as usize, - bytes_keys: try_read64(&mut b)? as usize, - bytes_values: try_read64(&mut b)? as usize, + index_block_offset: inp.read_fixedint::()? as usize, + data_block_size: inp.read_fixedint::()? as usize, + compression_algorithm: inp.read_fixedint::()?.try_into()?, + count_entries: inp.read_fixedint()?, + count_data_blocks: inp.read_fixedint()?, + bytes_data_blocks: inp.read_fixedint::()? as usize, + bytes_index_block: inp.read_fixedint::()? as usize, + bytes_keys: inp.read_fixedint::()? as usize, + bytes_values: inp.read_fixedint::()? as usize, }) } pub(crate) fn write_to(&self, mut out: impl std::io::Write) -> Result<()> { - write64(self.index_block_offset as u64, &mut out)?; - write64(self.data_block_size as u64, &mut out)?; - write64(self.compression_algorithm.into(), &mut out)?; - write64(self.count_entries, &mut out)?; - write64(self.count_data_blocks, &mut out)?; - write64(self.bytes_data_blocks as u64, &mut out)?; - write64(self.bytes_index_block as u64, &mut out)?; - write64(self.bytes_keys as u64, &mut out)?; - write64(self.bytes_values as u64, &mut out)?; + out.write_fixedint::(self.index_block_offset as u64)?; + out.write_fixedint::(self.data_block_size as u64)?; + out.write_fixedint::(self.compression_algorithm.into())?; + out.write_fixedint(self.count_entries)?; + out.write_fixedint(self.count_data_blocks)?; + out.write_fixedint::(self.bytes_data_blocks as u64)?; + out.write_fixedint::(self.bytes_index_block as u64)?; + out.write_fixedint::(self.bytes_keys as u64)?; + out.write_fixedint::(self.bytes_values as u64)?; let bytes_written = 9 * 8; out.write_all(vec![0; 512 - bytes_written - size_of::()].as_slice())?; - out.write_all(MTBL_MAGIC.to_be_bytes().as_slice())?; + out.write_fixedint(MTBL_MAGIC)?; Ok(()) } @@ -101,6 +90,7 @@ impl Metadata { #[cfg(test)] mod test { use super::Metadata; + use std::io::Cursor; #[test] fn test_metadata_default() { @@ -111,7 +101,7 @@ mod test { let mut v = Vec::::new(); m.write_to(&mut v).expect("write_to"); assert_eq!(v.len(), 512); - let m2 = Metadata::from_bytes(v.as_slice()).unwrap(); + let m2 = Metadata::read_from(Cursor::new(v)).unwrap(); assert_eq!(m2.count_entries, 1); assert_eq!(m2.bytes_keys, 1); assert_eq!(m2.bytes_values, 2); -- 2.50.1