2020-08-10 20:12:10 +05:30
|
|
|
use anyhow::{anyhow, Result};
|
|
|
|
use nom::{number::complete::*, IResult};
|
2020-08-19 19:01:01 +05:30
|
|
|
use byteorder::{LittleEndian, WriteBytesExt};
|
2020-08-10 20:12:10 +05:30
|
|
|
|
|
|
|
//------------------------------------------
|
|
|
|
|
|
|
|
pub trait Unpack {
|
|
|
|
// The size of the value when on disk.
|
|
|
|
fn disk_size() -> u32;
|
|
|
|
fn unpack(data: &[u8]) -> IResult<&[u8], Self>
|
|
|
|
where
|
|
|
|
Self: std::marker::Sized;
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn unpack<U: Unpack>(data: &[u8]) -> Result<U> {
|
|
|
|
match U::unpack(data) {
|
|
|
|
Err(_e) => Err(anyhow!("couldn't parse SMRoot")),
|
|
|
|
Ok((_i, v)) => Ok(v),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------
|
|
|
|
|
2020-08-19 19:01:01 +05:30
|
|
|
pub trait Pack {
|
|
|
|
fn pack<W: WriteBytesExt>(&self, data: &mut W) -> Result<()>;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------
|
|
|
|
|
2020-08-10 20:12:10 +05:30
|
|
|
impl Unpack for u64 {
|
|
|
|
fn disk_size() -> u32 {
|
|
|
|
8
|
|
|
|
}
|
|
|
|
|
|
|
|
fn unpack(i: &[u8]) -> IResult<&[u8], u64> {
|
|
|
|
le_u64(i)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-19 19:01:01 +05:30
|
|
|
impl Pack for u64 {
|
|
|
|
fn pack<W: WriteBytesExt>(&self, out: &mut W) -> Result<()> {
|
|
|
|
out.write_u64::<LittleEndian>(*self)?;
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-10 20:12:10 +05:30
|
|
|
impl Unpack for u32 {
|
|
|
|
fn disk_size() -> u32 {
|
|
|
|
4
|
|
|
|
}
|
|
|
|
|
|
|
|
fn unpack(i: &[u8]) -> IResult<&[u8], u32> {
|
|
|
|
le_u32(i)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-19 19:01:01 +05:30
|
|
|
impl Pack for u32 {
|
|
|
|
fn pack<W: WriteBytesExt>(&self, out: &mut W) -> Result<()> {
|
|
|
|
out.write_u32::<LittleEndian>(*self)?;
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-10 20:12:10 +05:30
|
|
|
//------------------------------------------
|