use std::io::Error;
use std::io::Read;
use std::io::Write;
use std::marker::PhantomData;
use byteorder::BigEndian;
use byteorder::ReadBytesExt;
use byteorder::WriteBytesExt;
use crate::config::CodeqConfig;
use crate::Decode;
use crate::Encode;
use crate::FixedSize;
use crate::Offset;
use crate::Size;
use crate::Span;
#[derive(Debug, Clone, Copy)]
#[derive(Default)]
#[derive(PartialEq, Eq)]
#[derive(serde::Serialize, serde::Deserialize)]
pub struct Segment<C>
where C: CodeqConfig
{
pub offset: u64,
pub size: u64,
_p: PhantomData<C>,
}
impl<C> Segment<C>
where C: CodeqConfig
{
pub fn new(offset: u64, size: u64) -> Self {
Self {
offset,
size,
_p: Default::default(),
}
}
}
impl<C> Span for Segment<C>
where C: CodeqConfig
{
fn offset(&self) -> Offset {
Offset(self.offset)
}
fn size(&self) -> Size {
Size(self.size)
}
}
impl<C> FixedSize for Segment<C>
where C: CodeqConfig
{
fn encoded_size() -> usize {
8 + 8 + 8
}
}
impl<C> Encode for Segment<C>
where C: CodeqConfig
{
fn encode<W: Write>(&self, mut w: W) -> Result<usize, Error> {
let mut n = 0;
let mut cw = C::new_writer(&mut w);
cw.write_u64::<BigEndian>(self.offset)?;
n += 8;
cw.write_u64::<BigEndian>(self.size)?;
n += 8;
n += cw.write_checksum()?;
Ok(n)
}
}
impl<C> Decode for Segment<C>
where C: CodeqConfig
{
fn decode<R: Read>(mut r: R) -> Result<Self, Error> {
let mut cr = C::new_reader(&mut r);
let offset = cr.read_u64::<BigEndian>()?;
let size = cr.read_u64::<BigEndian>()?;
cr.verify_checksum(|| "Segment::decode()")?;
Ok(Self {
offset,
size,
_p: Default::default(),
})
}
}
#[cfg(feature = "crc32fast")]
#[cfg(test)]
mod tests_crc32fast {
use crate::config::CodeqConfig;
use crate::config::Crc32fast;
use crate::testing::test_codec;
#[test]
fn test_segment_codec() -> anyhow::Result<()> {
let s = Crc32fast::segment(5, 10);
let b = vec![
0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 70, 249, 231, 4, ];
test_codec(&b, &s)?;
Ok(())
}
}
#[cfg(feature = "crc64fast-nvme")]
#[cfg(test)]
mod tests_crc64fast_nvme {
use crate::config::CodeqConfig;
use crate::config::Crc64fastNvme;
use crate::testing::test_codec;
#[test]
fn test_segment_codec() -> anyhow::Result<()> {
let s = Crc64fastNvme::segment(5, 10);
let b = vec![
0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 10, 246, 234, 165, 215, 19, 166, 38, 32, ];
test_codec(&b, &s)?;
Ok(())
}
}