rust_mqtt/utils/
buffer_writer.rs1use heapless::Vec;
26
27use crate::encoding::variable_byte_integer::{VariableByteInteger, VariableByteIntegerEncoder};
28use crate::packet::v5::property::Property;
29use crate::utils::types::{BinaryData, BufferError, EncodedString, StringPair, TopicFilter};
30
31#[derive(Debug, Clone, Copy)]
32pub struct RemLenError;
33
34pub struct BuffWriter<'a> {
37 buffer: &'a mut [u8],
38 pub position: usize,
39 len: usize,
40}
41
42impl<'a> BuffWriter<'a> {
43 pub fn new(buffer: &'a mut [u8], buff_len: usize) -> Self {
44 Self {
45 buffer,
46 position: 0,
47 len: buff_len,
48 }
49 }
50
51 fn increment_position(&mut self, increment: usize) {
52 self.position += increment;
53 }
54
55 pub fn get_n_byte(&mut self, n: usize) -> u8 {
57 if self.position >= n {
58 self.buffer[n]
59 } else {
60 0
61 }
62 }
63
64 pub fn get_rem_len(&mut self) -> Result<VariableByteInteger, RemLenError> {
66 let max = if self.position >= 5 {
67 4
68 } else {
69 self.position - 1
70 };
71 let mut i = 1;
72 let mut len: VariableByteInteger = [0; 4];
73 loop {
74 len[i - 1] = self.buffer[i];
75 if len[i - 1] & 0x80 == 0 {
76 return Ok(len);
77 }
78 if len[i - 1] & 0x80 != 0 && i == max && i != 4 {
79 return Err(RemLenError);
80 }
81 if i == max {
82 return Ok(len);
83 }
84 i += 1;
85 }
86 }
87
88 pub fn insert_ref(&mut self, len: usize, array: &[u8]) -> Result<(), BufferError> {
90 if self.position + len > self.len {
91 return Err(BufferError::InsufficientBufferSize);
92 }
93 self.buffer[self.position..self.position + len].copy_from_slice(&array[0..len]);
94 self.increment_position(len);
95 Ok(())
96 }
97
98 pub fn write_u8(&mut self, byte: u8) -> Result<(), BufferError> {
100 if self.position >= self.len {
101 Err(BufferError::InsufficientBufferSize)
102 } else {
103 self.buffer[self.position] = byte;
104 self.increment_position(1);
105 Ok(())
106 }
107 }
108
109 pub fn write_u16(&mut self, two_bytes: u16) -> Result<(), BufferError> {
111 let bytes: [u8; 2] = two_bytes.to_be_bytes();
112 self.insert_ref(2, &bytes)
113 }
114
115 pub fn write_u32(&mut self, four_bytes: u32) -> Result<(), BufferError> {
117 let bytes: [u8; 4] = four_bytes.to_be_bytes();
118 self.insert_ref(4, &bytes)
119 }
120
121 pub fn write_string_ref(&mut self, str: &EncodedString<'a>) -> Result<(), BufferError> {
123 self.write_u16(str.len)?;
124 if str.len != 0 {
125 let bytes = str.string.as_bytes();
126 let result = self.insert_ref(str.len as usize, bytes);
127 if result.is_err() {
128 self.position -= 2;
129 }
130 result
131 } else {
132 Ok(())
133 }
134 }
135
136 pub fn write_binary_ref(&mut self, bin: &BinaryData<'a>) -> Result<(), BufferError> {
138 self.write_u16(bin.len)?;
139
140 let res = self.insert_ref(bin.len as usize, bin.bin);
141 if res.is_err() {
142 self.position -= 2;
143 }
144 res
145 }
146
147 pub fn write_string_pair_ref(&mut self, str_pair: &StringPair<'a>) -> Result<(), BufferError> {
149 let starting_position = self.position;
150 self.write_string_ref(&str_pair.name)?;
151 let len_name = self.position - starting_position;
152
153 match self.write_string_ref(&str_pair.value) {
154 Ok(_) => Ok(()),
155 Err(e) => {
156 self.position -= len_name;
157 Err(e)
158 }
159 }
160 }
161
162 pub fn write_variable_byte_int(&mut self, int: u32) -> Result<(), BufferError> {
164 let x: VariableByteInteger = VariableByteIntegerEncoder::encode(int)?;
165 let len = VariableByteIntegerEncoder::len(x);
166 self.insert_ref(len, &x)
167 }
168
169 fn write_property(&mut self, property: &Property<'a>) -> Result<(), BufferError> {
170 let x: u8 = property.into();
171 self.write_u8(x)?;
172 property.encode(self)
173 }
174
175 pub fn write_properties<const LEN: usize>(
177 &mut self,
178 properties: &Vec<Property<'a>, LEN>,
179 ) -> Result<(), BufferError> {
180 let starting_position = self.position;
181 for prop in properties.iter() {
182 if let Err(e) = self.write_property(prop) {
183 self.position = starting_position;
184 return Err(e);
185 }
186 }
187 Ok(())
188 }
189
190 fn write_topic_filter_ref(
193 &mut self,
194 sub: bool,
195 topic_filter: &TopicFilter<'a>,
196 ) -> Result<(), BufferError> {
197 self.write_string_ref(&topic_filter.filter)?;
198 if sub {
199 self.write_u8(topic_filter.sub_options)?;
200 }
201 Ok(())
202 }
203
204 pub fn write_topic_filters_ref<const MAX: usize>(
207 &mut self,
208 sub: bool,
209 _len: usize,
210 filters: &Vec<TopicFilter<'a>, MAX>,
211 ) -> Result<(), BufferError> {
212 let starting_position = self.position;
213
214 for filter in filters {
215 if let Err(e) = self.write_topic_filter_ref(sub, filter) {
216 self.position = starting_position;
217 return Err(e);
218 }
219 }
220 Ok(())
221 }
222}