use std::io;
use bytes::Bytes;
use speedy::{Context, Readable, Writable, Writer};
use byteorder::ReadBytesExt;
use log::warn;
#[derive(Debug, PartialEq, Eq, Clone, Copy, Readable, Writable)]
pub struct RepresentationIdentifier {
bytes: [u8; 2],
}
impl RepresentationIdentifier {
pub const CDR_BE: Self = Self {
bytes: [0x00, 0x00],
};
pub const CDR_LE: Self = Self {
bytes: [0x00, 0x01],
};
pub const PL_CDR_BE: Self = Self {
bytes: [0x00, 0x02],
};
pub const PL_CDR_LE: Self = Self {
bytes: [0x00, 0x03],
};
pub const CDR2_BE: Self = Self {
bytes: [0x00, 0x10],
};
pub const CDR2_LE: Self = Self {
bytes: [0x00, 0x11],
};
pub const PL_CDR2_BE: Self = Self {
bytes: [0x00, 0x12],
};
pub const PL_CDR2_LE: Self = Self {
bytes: [0x00, 0x13],
};
pub const D_CDR_BE: Self = Self {
bytes: [0x00, 0x14],
};
pub const D_CDR_LE: Self = Self {
bytes: [0x00, 0x15],
};
pub const XML: Self = Self {
bytes: [0x00, 0x04],
};
pub fn from_bytes(bytes: &[u8]) -> io::Result<Self> {
let mut reader = io::Cursor::new(bytes);
Ok(Self {
bytes: [reader.read_u8()?, reader.read_u8()?],
})
}
pub fn to_bytes(self) -> [u8; 2] {
self.bytes
}
}
#[derive(Debug, PartialEq, Clone)]
pub struct SerializedPayload {
pub representation_identifier: RepresentationIdentifier,
pub representation_options: [u8; 2], pub value: Bytes,
}
impl SerializedPayload {
pub fn new(rep_id: RepresentationIdentifier, payload: Vec<u8>) -> Self {
Self {
representation_identifier: rep_id,
representation_options: [0, 0],
value: Bytes::from(payload),
}
}
pub fn new_from_bytes(rep_id: RepresentationIdentifier, payload: Bytes) -> Self {
Self {
representation_identifier: rep_id,
representation_options: [0, 0],
value: payload,
}
}
pub fn from_bytes(bytes: &Bytes) -> io::Result<Self> {
let mut reader = io::Cursor::new(&bytes);
let representation_identifier = RepresentationIdentifier {
bytes: [reader.read_u8()?, reader.read_u8()?],
};
let representation_options = [reader.read_u8()?, reader.read_u8()?];
let value = if bytes.len() >= 4 {
bytes.slice(4..) } else {
warn!(
"DATA submessage was smaller than submessage header: {:?}",
bytes
);
return Err(io::Error::new(
io::ErrorKind::Other,
"Too short DATA submessage.",
));
};
Ok(Self {
representation_identifier,
representation_options,
value,
})
}
}
impl<C: Context> Writable<C> for SerializedPayload {
fn write_to<T: ?Sized + Writer<C>>(&self, writer: &mut T) -> Result<(), C::Error> {
writer.write_u8(self.representation_identifier.bytes[0])?;
writer.write_u8(self.representation_identifier.bytes[1])?;
writer.write_u8(self.representation_options[0])?;
writer.write_u8(self.representation_options[1])?;
writer.write_bytes(&self.value)?;
Ok(())
}
}