1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
use crate::{decoder::*, encoder::*, *};
#[derive(Debug, Clone, PartialEq)]
pub struct Publish<'a> {
pub dup: bool,
pub qospid: QosPid,
pub retain: bool,
pub topic_name: &'a str,
pub payload: &'a [u8],
}
impl<'a> Publish<'a> {
pub(crate) fn from_buffer(
header: &Header,
remaining_len: usize,
buf: &'a [u8],
offset: &mut usize,
) -> Result<Self, Error> {
let payload_end = *offset + remaining_len;
let topic_name = read_str(buf, offset)?;
let qospid = match header.qos {
QoS::AtMostOnce => QosPid::AtMostOnce,
QoS::AtLeastOnce => QosPid::AtLeastOnce(Pid::from_buffer(buf, offset)?),
QoS::ExactlyOnce => QosPid::ExactlyOnce(Pid::from_buffer(buf, offset)?),
};
Ok(Publish {
dup: header.dup,
qospid,
retain: header.retain,
topic_name,
payload: &buf[*offset..payload_end],
})
}
pub(crate) fn to_buffer(&self, buf: &mut [u8], offset: &mut usize) -> Result<usize, Error> {
let mut header: u8 = match self.qospid {
QosPid::AtMostOnce => 0b00110000,
QosPid::AtLeastOnce(_) => 0b00110010,
QosPid::ExactlyOnce(_) => 0b00110100,
};
if self.dup {
header |= 0b00001000 as u8;
};
if self.retain {
header |= 0b00000001 as u8;
};
check_remaining(buf, offset, 1)?;
write_u8(buf, offset, header)?;
let length = self.topic_name.len()
+ match self.qospid {
QosPid::AtMostOnce => 2,
_ => 4,
}
+ self.payload.len();
let write_len = write_length(buf, offset, length)? + 1;
write_string(buf, offset, self.topic_name)?;
match self.qospid {
QosPid::AtMostOnce => (),
QosPid::AtLeastOnce(pid) => pid.to_buffer(buf, offset)?,
QosPid::ExactlyOnce(pid) => pid.to_buffer(buf, offset)?,
}
for &byte in self.payload {
write_u8(buf, offset, byte)?;
}
Ok(write_len)
}
}