rseip_cip/codec/encode/
message.rs

1// rseip
2//
3// rseip - Ethernet/IP (CIP) in pure Rust.
4// Copyright: 2021, Joylei <leingliu@gmail.com>
5// License: MIT
6
7use crate::MessageRequest;
8use bytes::BufMut;
9use rseip_core::codec::{Encode, Encoder};
10
11impl<P: Encode, D: Encode> Encode for MessageRequest<P, D> {
12    #[inline]
13    fn encode<A: Encoder>(self, buf: &mut bytes::BytesMut, encoder: &mut A) -> Result<(), A::Error>
14    where
15        Self: Sized,
16    {
17        // service code
18        buf.put_u8(self.service_code);
19
20        let path_len = self.path.bytes_count();
21        debug_assert!(path_len <= u8::MAX as usize && path_len % 2 == 0);
22        buf.put_u8((path_len / 2) as u8);
23
24        self.path.encode(buf, encoder)?;
25        self.data.encode(buf, encoder)?;
26        Ok(())
27    }
28
29    #[inline]
30    fn encode_by_ref<A: Encoder>(
31        &self,
32        buf: &mut bytes::BytesMut,
33        encoder: &mut A,
34    ) -> Result<(), A::Error> {
35        // service code
36        buf.put_u8(self.service_code);
37
38        let path_len = self.path.bytes_count();
39        debug_assert!(path_len <= u8::MAX as usize && path_len % 2 == 0);
40        buf.put_u8((path_len / 2) as u8);
41
42        self.path.encode_by_ref(buf, encoder)?;
43        self.data.encode_by_ref(buf, encoder)?;
44        Ok(())
45    }
46
47    #[inline]
48    fn bytes_count(&self) -> usize {
49        2 + self.path.bytes_count() + self.data.bytes_count()
50    }
51}
52
53#[cfg(test)]
54mod test {
55    use super::*;
56    use crate::{epath::EPath, MessageRequest};
57    use bytes::Bytes;
58    use rseip_core::tests::EncodeExt;
59
60    #[test]
61    fn test_encode_message_router_request() {
62        let mr = MessageRequest::new(
63            0x52,
64            EPath::default().with_class(0x06).with_instance(0x01),
65            Bytes::from_static(&[0x10, 0x00]),
66        );
67        assert_eq!(mr.bytes_count(), 8);
68        let buf = mr.try_into_bytes().unwrap();
69        assert_eq!(
70            &buf[..],
71            &[
72                0x52, // service code
73                0x02, 0x20, 0x06, 0x24, 0x01, // epath
74                0x010, 0x00 // data
75            ]
76        );
77    }
78}