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