rseip_cip/codec/
decode.rs

1// rseip
2//
3// rseip - Ethernet/IP (CIP) in pure Rust.
4// Copyright: 2021, Joylei <leingliu@gmail.com>
5// License: MIT
6
7pub mod message_reply;
8use crate::*;
9use crate::{identity::IdentityObject, socket::SocketAddr};
10use bytes::Buf;
11use core::{slice, str};
12use rseip_core::codec::{Decode, Decoder};
13use std::borrow::Cow;
14
15impl<'de> Decode<'de> for IdentityObject<'de> {
16    fn decode<D>(mut decoder: D) -> Result<Self, D::Error>
17    where
18        D: rseip_core::codec::Decoder<'de>,
19    {
20        decoder.ensure_size(33)?;
21        //let product_name_len = data[32];
22
23        let identity = IdentityObject {
24            protocol_version: decoder.decode_u16(),
25            socket_addr: {
26                let addr = decoder.buf_mut().copy_to_bytes(16);
27                SocketAddr::from_bytes::<D::Error>(addr)?
28            },
29            vendor_id: decoder.decode_u16(),
30            device_type: decoder.decode_u16(),
31            product_code: decoder.decode_u16(),
32            revision: Revision {
33                major: decoder.decode_u8(),
34                minor: decoder.decode_u8(),
35            },
36            status: decoder.decode_u16(),
37            serial_number: decoder.decode_u32(),
38            product_name: {
39                let name_len = decoder.decode_u8();
40                decoder.ensure_size(name_len as usize + 1)?;
41                let data = decoder.buf_mut().copy_to_bytes(name_len as usize);
42                unsafe {
43                    let buf = data.as_ptr();
44                    let buf = slice::from_raw_parts(buf, name_len as usize);
45                    let name = str::from_utf8_unchecked(buf);
46                    Cow::from(name)
47                }
48            },
49            state: decoder.decode_u8(),
50        };
51
52        Ok(identity)
53    }
54}
55
56impl<'de> Decode<'de> for ListServiceItem<'de> {
57    fn decode<D>(mut decoder: D) -> Result<Self, D::Error>
58    where
59        D: Decoder<'de>,
60    {
61        debug_assert!(decoder.remaining() > 4);
62
63        let item = ListServiceItem {
64            protocol_version: decoder.decode_u16(),
65            capability: decoder.decode_u16(),
66            name: {
67                const STR_LEN: usize = 16;
68                decoder.ensure_size(STR_LEN)?;
69                let data = decoder.buf_mut().copy_to_bytes(STR_LEN);
70                unsafe {
71                    let buf = data.as_ptr();
72                    let buf = slice::from_raw_parts(buf, STR_LEN);
73                    let name = str::from_utf8_unchecked(buf);
74                    Cow::from(name)
75                }
76            },
77        };
78
79        Ok(item)
80    }
81}
82
83// fn decode_c_str<'de>(data: Bytes) -> &'de str {
84//     unsafe {
85//         let buf = data.as_ptr();
86//         let len = libc::strlen(buf as *const i8);
87//         let buf = slice::from_raw_parts(buf, len);
88//         str::from_utf8_unchecked(buf)
89//     }
90// }