zenoh_codec/zenoh/
del.rs

1//
2// Copyright (c) 2022 ZettaScale Technology
3//
4// This program and the accompanying materials are made available under the
5// terms of the Eclipse Public License 2.0 which is available at
6// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
7// which is available at https://www.apache.org/licenses/LICENSE-2.0.
8//
9// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
10//
11// Contributors:
12//   ZettaScale Zenoh Team, <zenoh@zettascale.tech>
13//
14use alloc::vec::Vec;
15
16use zenoh_buffers::{
17    reader::{DidntRead, Reader},
18    writer::{DidntWrite, Writer},
19};
20use zenoh_protocol::{
21    common::{iext, imsg},
22    zenoh::{
23        del::{ext, flag, Del},
24        id,
25    },
26};
27
28use crate::{common::extension, RCodec, WCodec, Zenoh080, Zenoh080Header};
29
30impl<W> WCodec<&Del, &mut W> for Zenoh080
31where
32    W: Writer,
33{
34    type Output = Result<(), DidntWrite>;
35
36    fn write(self, writer: &mut W, x: &Del) -> Self::Output {
37        let Del {
38            timestamp,
39            ext_sinfo,
40            ext_attachment,
41            ext_unknown,
42        } = x;
43
44        // Header
45        let mut header = id::DEL;
46        if timestamp.is_some() {
47            header |= flag::T;
48        }
49        let mut n_exts = (ext_sinfo.is_some()) as u8
50            + (ext_attachment.is_some()) as u8
51            + (ext_unknown.len() as u8);
52        if n_exts != 0 {
53            header |= flag::Z;
54        }
55        self.write(&mut *writer, header)?;
56
57        // Body
58        if let Some(ts) = timestamp.as_ref() {
59            self.write(&mut *writer, ts)?;
60        }
61
62        // Extensions
63        if let Some(sinfo) = ext_sinfo.as_ref() {
64            n_exts -= 1;
65            self.write(&mut *writer, (sinfo, n_exts != 0))?;
66        }
67        if let Some(att) = ext_attachment.as_ref() {
68            n_exts -= 1;
69            self.write(&mut *writer, (att, n_exts != 0))?;
70        }
71        for u in ext_unknown.iter() {
72            n_exts -= 1;
73            self.write(&mut *writer, (u, n_exts != 0))?;
74        }
75
76        Ok(())
77    }
78}
79
80impl<R> RCodec<Del, &mut R> for Zenoh080
81where
82    R: Reader,
83{
84    type Error = DidntRead;
85
86    fn read(self, reader: &mut R) -> Result<Del, Self::Error> {
87        let header: u8 = self.read(&mut *reader)?;
88        let codec = Zenoh080Header::new(header);
89        codec.read(reader)
90    }
91}
92
93impl<R> RCodec<Del, &mut R> for Zenoh080Header
94where
95    R: Reader,
96{
97    type Error = DidntRead;
98
99    fn read(self, reader: &mut R) -> Result<Del, Self::Error> {
100        if imsg::mid(self.header) != id::DEL {
101            return Err(DidntRead);
102        }
103
104        // Body
105        let mut timestamp: Option<uhlc::Timestamp> = None;
106        if imsg::has_flag(self.header, flag::T) {
107            timestamp = Some(self.codec.read(&mut *reader)?);
108        }
109
110        // Extensions
111        let mut ext_sinfo: Option<ext::SourceInfoType> = None;
112        let mut ext_attachment: Option<ext::AttachmentType> = None;
113        let mut ext_unknown = Vec::new();
114
115        let mut has_ext = imsg::has_flag(self.header, flag::Z);
116        while has_ext {
117            let ext: u8 = self.codec.read(&mut *reader)?;
118            let eodec = Zenoh080Header::new(ext);
119            match iext::eid(ext) {
120                ext::SourceInfo::ID => {
121                    let (s, ext): (ext::SourceInfoType, bool) = eodec.read(&mut *reader)?;
122                    ext_sinfo = Some(s);
123                    has_ext = ext;
124                }
125                ext::Attachment::ID => {
126                    let (a, ext): (ext::AttachmentType, bool) = eodec.read(&mut *reader)?;
127                    ext_attachment = Some(a);
128                    has_ext = ext;
129                }
130                _ => {
131                    let (u, ext) = extension::read(reader, "Del", ext)?;
132                    ext_unknown.push(u);
133                    has_ext = ext;
134                }
135            }
136        }
137
138        Ok(Del {
139            timestamp,
140            ext_sinfo,
141            ext_attachment,
142            ext_unknown,
143        })
144    }
145}