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 return self.insert_ref(str.len as usize, bytes);
127 }
128 Ok(())
129 }
130
131 pub fn write_binary_ref(&mut self, bin: &BinaryData<'a>) -> Result<(), BufferError> {
133 self.write_u16(bin.len)?;
134 self.insert_ref(bin.len as usize, bin.bin)
135 }
136
137 pub fn write_string_pair_ref(&mut self, str_pair: &StringPair<'a>) -> Result<(), BufferError> {
139 self.write_string_ref(&str_pair.name)?;
140 self.write_string_ref(&str_pair.value)
141 }
142
143 pub fn write_variable_byte_int(&mut self, int: u32) -> Result<(), BufferError> {
145 let x: VariableByteInteger = VariableByteIntegerEncoder::encode(int)?;
146 let len = VariableByteIntegerEncoder::len(x);
147 self.insert_ref(len, &x)
148 }
149
150 fn write_property(&mut self, property: &Property<'a>) -> Result<(), BufferError> {
151 let x: u8 = property.into();
152 self.write_u8(x)?;
153 property.encode(self)
154 }
155
156 pub fn write_properties<const LEN: usize>(
158 &mut self,
159 properties: &Vec<Property<'a>, LEN>,
160 ) -> Result<(), BufferError> {
161 for prop in properties.iter() {
162 self.write_property(prop)?;
163 }
164 Ok(())
165 }
166
167 fn write_topic_filter_ref(
170 &mut self,
171 sub: bool,
172 topic_filter: &TopicFilter<'a>,
173 ) -> Result<(), BufferError> {
174 self.write_string_ref(&topic_filter.filter)?;
175 if sub {
176 self.write_u8(topic_filter.sub_options)?;
177 }
178 Ok(())
179 }
180
181 pub fn write_topic_filters_ref<const MAX: usize>(
184 &mut self,
185 sub: bool,
186 _len: usize,
187 filters: &Vec<TopicFilter<'a>, MAX>,
188 ) -> Result<(), BufferError> {
189 for filter in filters {
190 self.write_topic_filter_ref(sub, filter)?;
191 }
192 Ok(())
193 }
194}