1use crate::{Error, Packet};
2
3pub fn encode_slice(packet: &Packet, buf: &mut [u8]) -> Result<usize, Error> {
36 let mut offset = 0;
37
38 match packet {
39 Packet::Connect(connect) => connect.to_buffer(buf, &mut offset),
40 Packet::Connack(connack) => connack.to_buffer(buf, &mut offset),
41 Packet::Publish(publish) => publish.to_buffer(buf, &mut offset),
42 Packet::Puback(pid) => {
43 check_remaining(buf, &mut offset, 4)?;
44 let header: u8 = 0b01000000;
45 let length: u8 = 2;
46 write_u8(buf, &mut offset, header)?;
47 write_u8(buf, &mut offset, length)?;
48 pid.to_buffer(buf, &mut offset)?;
49 Ok(4)
50 }
51 Packet::Pubrec(pid) => {
52 check_remaining(buf, &mut offset, 4)?;
53 let header: u8 = 0b01010000;
54 let length: u8 = 2;
55 write_u8(buf, &mut offset, header)?;
56 write_u8(buf, &mut offset, length)?;
57 pid.to_buffer(buf, &mut offset)?;
58 Ok(4)
59 }
60 Packet::Pubrel(pid) => {
61 check_remaining(buf, &mut offset, 4)?;
62 let header: u8 = 0b01100010;
63 let length: u8 = 2;
64 write_u8(buf, &mut offset, header)?;
65 write_u8(buf, &mut offset, length)?;
66 pid.to_buffer(buf, &mut offset)?;
67 Ok(4)
68 }
69 Packet::Pubcomp(pid) => {
70 check_remaining(buf, &mut offset, 4)?;
71 let header: u8 = 0b01110000;
72 let length: u8 = 2;
73 write_u8(buf, &mut offset, header)?;
74 write_u8(buf, &mut offset, length)?;
75 pid.to_buffer(buf, &mut offset)?;
76 Ok(4)
77 }
78 Packet::Subscribe(subscribe) => subscribe.to_buffer(buf, &mut offset),
79 Packet::Suback(suback) => suback.to_buffer(buf, &mut offset),
80 Packet::Unsubscribe(unsub) => unsub.to_buffer(buf, &mut offset),
81 Packet::Unsuback(pid) => {
82 check_remaining(buf, &mut offset, 4)?;
83 let header: u8 = 0b10110000;
84 let length: u8 = 2;
85 write_u8(buf, &mut offset, header)?;
86 write_u8(buf, &mut offset, length)?;
87 pid.to_buffer(buf, &mut offset)?;
88 Ok(4)
89 }
90 Packet::Pingreq => {
91 check_remaining(buf, &mut offset, 2)?;
92 let header: u8 = 0b11000000;
93 let length: u8 = 0;
94 write_u8(buf, &mut offset, header)?;
95 write_u8(buf, &mut offset, length)?;
96 Ok(2)
97 }
98 Packet::Pingresp => {
99 check_remaining(buf, &mut offset, 2)?;
100 let header: u8 = 0b11010000;
101 let length: u8 = 0;
102 write_u8(buf, &mut offset, header)?;
103 write_u8(buf, &mut offset, length)?;
104 Ok(2)
105 }
106 Packet::Disconnect => {
107 check_remaining(buf, &mut offset, 2)?;
108 let header: u8 = 0b11100000;
109 let length: u8 = 0;
110 write_u8(buf, &mut offset, header)?;
111 write_u8(buf, &mut offset, length)?;
112 Ok(2)
113 }
114 }
115}
116
117pub(crate) fn check_remaining(buf: &mut [u8], offset: &mut usize, len: usize) -> Result<(), Error> {
120 if buf[*offset..].len() < len {
121 Err(Error::WriteZero)
122 } else {
123 Ok(())
124 }
125}
126
127pub(crate) fn write_length(buf: &mut [u8], offset: &mut usize, len: usize) -> Result<usize, Error> {
129 let write_len = match len {
130 0..=127 => {
131 check_remaining(buf, offset, len + 1)?;
132 len + 1
133 }
134 128..=16383 => {
135 check_remaining(buf, offset, len + 2)?;
136 len + 2
137 }
138 16384..=2097151 => {
139 check_remaining(buf, offset, len + 3)?;
140 len + 3
141 }
142 2097152..=268435455 => {
143 check_remaining(buf, offset, len + 4)?;
144 len + 4
145 }
146 _ => return Err(Error::InvalidLength),
147 };
148 let mut done = false;
149 let mut x = len;
150 while !done {
151 let mut byte = (x % 128) as u8;
152 x = x / 128;
153 if x > 0 {
154 byte = byte | 128;
155 }
156 write_u8(buf, offset, byte)?;
157 done = x <= 0;
158 }
159 Ok(write_len)
160}
161
162pub(crate) fn write_u8(buf: &mut [u8], offset: &mut usize, val: u8) -> Result<(), Error> {
163 buf[*offset] = val;
164 *offset += 1;
165 Ok(())
166}
167
168pub(crate) fn write_u16(buf: &mut [u8], offset: &mut usize, val: u16) -> Result<(), Error> {
169 write_u8(buf, offset, (val >> 8) as u8)?;
170 write_u8(buf, offset, (val & 0xFF) as u8)
171}
172
173pub(crate) fn write_bytes(buf: &mut [u8], offset: &mut usize, bytes: &[u8]) -> Result<(), Error> {
174 write_u16(buf, offset, bytes.len() as u16)?;
175
176 for &byte in bytes {
177 write_u8(buf, offset, byte)?;
178 }
179 Ok(())
180}
181
182pub(crate) fn write_string(buf: &mut [u8], offset: &mut usize, string: &str) -> Result<(), Error> {
183 write_bytes(buf, offset, string.as_bytes())
184}