hdds_micro/rtps/
header.rs1use super::types::{GuidPrefix, ProtocolVersion, VendorId};
7use crate::error::{Error, Result};
8
9pub const RTPS_MAGIC: [u8; 4] = *b"RTPS";
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
21pub struct RtpsHeader {
22 pub protocol_version: ProtocolVersion,
24 pub vendor_id: VendorId,
26 pub guid_prefix: GuidPrefix,
28}
29
30impl RtpsHeader {
31 pub const SIZE: usize = 20;
33
34 pub const fn new(
36 protocol_version: ProtocolVersion,
37 vendor_id: VendorId,
38 guid_prefix: GuidPrefix,
39 ) -> Self {
40 Self {
41 protocol_version,
42 vendor_id,
43 guid_prefix,
44 }
45 }
46
47 pub fn encode(&self, buf: &mut [u8]) -> Result<usize> {
57 if buf.len() < Self::SIZE {
58 return Err(Error::BufferTooSmall);
59 }
60
61 buf[0..4].copy_from_slice(&RTPS_MAGIC);
63
64 buf[4] = self.protocol_version.major;
66 buf[5] = self.protocol_version.minor;
67
68 buf[6..8].copy_from_slice(&self.vendor_id.0);
70
71 buf[8..20].copy_from_slice(self.guid_prefix.as_bytes());
73
74 Ok(Self::SIZE)
75 }
76
77 pub fn decode(buf: &[u8]) -> Result<Self> {
87 if buf.len() < Self::SIZE {
88 return Err(Error::BufferTooSmall);
89 }
90
91 if buf[0..4] != RTPS_MAGIC {
93 return Err(Error::InvalidHeader);
94 }
95
96 let protocol_version = ProtocolVersion::new(buf[4], buf[5]);
98
99 let vendor_id = VendorId::new([buf[6], buf[7]]);
101
102 let mut guid_prefix_bytes = [0u8; 12];
104 guid_prefix_bytes.copy_from_slice(&buf[8..20]);
105 let guid_prefix = GuidPrefix::new(guid_prefix_bytes);
106
107 Ok(Self {
108 protocol_version,
109 vendor_id,
110 guid_prefix,
111 })
112 }
113}
114
115#[cfg(test)]
116mod tests {
117 use super::*;
118
119 #[test]
120 fn test_rtps_header_encode_decode() {
121 let header = RtpsHeader::new(
122 ProtocolVersion::RTPS_2_5,
123 VendorId::HDDS,
124 GuidPrefix::new([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]),
125 );
126
127 let mut buf = [0u8; 64];
128 let written = header.encode(&mut buf).unwrap();
129 assert_eq!(written, RtpsHeader::SIZE);
130
131 assert_eq!(&buf[0..4], b"RTPS");
133
134 let decoded = RtpsHeader::decode(&buf).unwrap();
136 assert_eq!(decoded, header);
137 }
138
139 #[test]
140 fn test_rtps_header_invalid_magic() {
141 let mut buf = [0u8; 20];
142 buf[0..4].copy_from_slice(b"XXXX"); let result = RtpsHeader::decode(&buf);
145 assert_eq!(result, Err(Error::InvalidHeader));
146 }
147
148 #[test]
149 fn test_rtps_header_buffer_too_small() {
150 let header = RtpsHeader::default();
151 let mut buf = [0u8; 10]; let result = header.encode(&mut buf);
154 assert_eq!(result, Err(Error::BufferTooSmall));
155 }
156}