use alloc::vec::Vec;
use zerodds_cdr::{BufferReader, BufferWriter};
use crate::error::GiopResult;
use crate::version::Version;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct FragmentHeader {
pub request_id: u32,
}
impl FragmentHeader {
pub fn encode(&self, w: &mut BufferWriter) -> GiopResult<()> {
w.write_u32(self.request_id)?;
Ok(())
}
pub fn decode(r: &mut BufferReader<'_>) -> GiopResult<Self> {
Ok(Self {
request_id: r.read_u32()?,
})
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Fragment {
pub header: Option<FragmentHeader>,
pub body: Vec<u8>,
}
impl Fragment {
pub fn encode(&self, version: Version, w: &mut BufferWriter) -> GiopResult<()> {
if version.uses_v1_2_request_layout() {
if let Some(h) = &self.header {
h.encode(w)?;
}
}
w.write_bytes(&self.body)?;
Ok(())
}
pub fn decode(version: Version, r: &mut BufferReader<'_>) -> GiopResult<Self> {
let header = if version.uses_v1_2_request_layout() {
Some(FragmentHeader::decode(r)?)
} else {
None
};
let body = r.read_bytes(r.remaining())?.to_vec();
Ok(Self { header, body })
}
}
#[cfg(test)]
#[allow(clippy::expect_used, clippy::unwrap_used, clippy::panic)]
mod tests {
use super::*;
use zerodds_cdr::Endianness;
#[test]
fn round_trip_giop_1_2_with_header() {
let f = Fragment {
header: Some(FragmentHeader { request_id: 42 }),
body: alloc::vec![1, 2, 3],
};
let mut w = BufferWriter::new(Endianness::Big);
f.encode(Version::V1_2, &mut w).unwrap();
let bytes = w.into_bytes();
let mut r = BufferReader::new(&bytes, Endianness::Big);
let decoded = Fragment::decode(Version::V1_2, &mut r).unwrap();
assert_eq!(decoded, f);
}
#[test]
fn round_trip_giop_1_1_without_header() {
let f = Fragment {
header: None,
body: alloc::vec![0xa, 0xb, 0xc, 0xd],
};
let mut w = BufferWriter::new(Endianness::Little);
f.encode(Version::V1_1, &mut w).unwrap();
let bytes = w.into_bytes();
assert_eq!(bytes, alloc::vec![0xa, 0xb, 0xc, 0xd]);
let mut r = BufferReader::new(&bytes, Endianness::Little);
let decoded = Fragment::decode(Version::V1_1, &mut r).unwrap();
assert_eq!(decoded, f);
}
}