*/
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;
pub(crate) bytes_values: usize,
}
-fn try_read64(b: &mut &[u8]) -> Result<u64> {
- if b.len() < size_of::<u64>() {
- Err("buffer too short".into())
- } else {
- let (n, rest) = b.split_at(size_of::<u64>());
- *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<Self> {
- if b.len() < size_of::<u32>() {
- return Err("metadata block too short".into());
- } else if u32::from_be_bytes(b[b.len() - size_of::<u32>()..].try_into()?) != MTBL_MAGIC {
+ pub(crate) fn read_from(mut inp: impl std::io::Read + std::io::Seek) -> Result<Self> {
+ inp.seek(SeekFrom::Start(512 - size_of::<u32>() as u64))?;
+ if inp.read_fixedint::<u32>()? != 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::<u64>()? as usize,
+ data_block_size: inp.read_fixedint::<u64>()? as usize,
+ compression_algorithm: inp.read_fixedint::<u64>()?.try_into()?,
+ count_entries: inp.read_fixedint()?,
+ count_data_blocks: inp.read_fixedint()?,
+ bytes_data_blocks: inp.read_fixedint::<u64>()? as usize,
+ bytes_index_block: inp.read_fixedint::<u64>()? as usize,
+ bytes_keys: inp.read_fixedint::<u64>()? as usize,
+ bytes_values: inp.read_fixedint::<u64>()? 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::<u64>(self.index_block_offset as u64)?;
+ out.write_fixedint::<u64>(self.data_block_size as u64)?;
+ out.write_fixedint::<u64>(self.compression_algorithm.into())?;
+ out.write_fixedint(self.count_entries)?;
+ out.write_fixedint(self.count_data_blocks)?;
+ out.write_fixedint::<u64>(self.bytes_data_blocks as u64)?;
+ out.write_fixedint::<u64>(self.bytes_index_block as u64)?;
+ out.write_fixedint::<u64>(self.bytes_keys as u64)?;
+ out.write_fixedint::<u64>(self.bytes_values as u64)?;
let bytes_written = 9 * 8;
out.write_all(vec![0; 512 - bytes_written - size_of::<u32>()].as_slice())?;
- out.write_all(MTBL_MAGIC.to_be_bytes().as_slice())?;
+ out.write_fixedint(MTBL_MAGIC)?;
Ok(())
}
#[cfg(test)]
mod test {
use super::Metadata;
+ use std::io::Cursor;
#[test]
fn test_metadata_default() {
let mut v = Vec::<u8>::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);