tinymqtt/
reader_writer.rs

1use super::flags::Flags;
2
3pub struct MqttMessageWriter<'a> {
4    buffer: &'a mut [u8],
5    cursor: usize,
6}
7
8impl<'a> MqttMessageWriter<'a> {
9    pub fn new(buffer: &'a mut [u8]) -> Self {
10        Self { buffer, cursor: 0 }
11    }
12
13    pub fn write_u8(&mut self, value: u8) {
14        self.buffer[self.cursor] = value;
15        self.cursor += 1;
16    }
17
18    pub fn write_flags(&mut self, value: Flags) {
19        self.write_u8(value.value);
20    }
21
22    pub fn write_u16(&mut self, value: u16) {
23        self.buffer[self.cursor] = (value >> 8) as u8;
24        self.buffer[self.cursor + 1] = value as u8;
25        self.cursor += 2;
26    }
27
28    pub fn write_string(&mut self, value: &str) {
29        self.write_u16(value.len() as u16);
30        for byte in value.bytes() {
31            self.buffer[self.cursor] = byte;
32            self.cursor += 1;
33        }
34    }
35
36    pub fn write_bytes(&mut self, value: &[u8]) {
37        self.write_u16(value.len() as u16);
38        self.write_bytes_raw(value);
39    }
40
41    pub fn write_bytes_raw(&mut self, value: &[u8]) {
42        for byte in value {
43            self.buffer[self.cursor] = *byte;
44            self.cursor += 1;
45        }
46    }
47
48    pub fn write_variable_int(&mut self, mut value: u32) {
49        loop {
50            // Successively take the last 7 bits, check if anything remaining (i.e. > 0),
51            // and repeat
52            let mut byte = (value & 0x7F) as u8;
53            value >>= 7;
54            if value > 0 {
55                byte |= 0x80;
56            }
57            self.buffer[self.cursor] = byte;
58            self.cursor += 1;
59            if value == 0 {
60                break;
61            }
62        }
63    }
64
65    pub fn len(&self) -> usize {
66        self.cursor
67    }
68}
69
70pub struct MqttMessageReader<'a> {
71    buffer: &'a [u8],
72    cursor: usize,
73    mark: usize,
74}
75
76impl<'a> MqttMessageReader<'a> {
77    pub fn new(buffer: &'a [u8]) -> Self {
78        Self {
79            buffer,
80            cursor: 0,
81            mark: 0,
82        }
83    }
84
85    pub fn read_u8(&mut self) -> u8 {
86        let value = self.buffer[self.cursor];
87        self.cursor += 1;
88        value
89    }
90
91    pub fn read_u16(&mut self) -> u16 {
92        let value = ((self.buffer[self.cursor] as u16) << 8) | self.buffer[self.cursor + 1] as u16;
93        self.cursor += 2;
94        value
95    }
96
97    pub fn read_string(&mut self) -> &'a str {
98        let length = self.read_u16() as usize;
99        let start = self.cursor;
100        self.cursor += length;
101        core::str::from_utf8(&self.buffer[start..self.cursor]).unwrap()
102    }
103
104    pub fn read_bytes(&mut self) -> &'a [u8] {
105        let length = self.read_u16() as usize;
106        self.read_bytes_raw(length)
107    }
108
109    pub fn read_bytes_raw(&mut self, length: usize) -> &'a [u8] {
110        let start = self.cursor;
111        self.cursor += length;
112        &self.buffer[start..self.cursor]
113    }
114
115    pub fn read_variable_int(&mut self) -> u32 {
116        let mut value = 0;
117        let mut shift = 0;
118        loop {
119            let byte = self.buffer[self.cursor];
120            self.cursor += 1;
121            value |= ((byte & 0x7F) as u32) << shift;
122            shift += 7;
123            if byte & 0x80 == 0 {
124                break;
125            }
126        }
127        value
128    }
129
130    pub fn remaining(&self) -> usize {
131        self.buffer.len() - self.cursor
132    }
133
134    pub fn skip(&mut self, length: usize) {
135        self.cursor += length;
136    }
137
138    pub fn mark(&mut self) {
139        self.mark = self.cursor;
140    }
141
142    pub fn skip_to(&mut self, position: usize) {
143        self.cursor = self.mark + position;
144    }
145
146    pub fn distance_from_mark(&self) -> usize {
147        self.cursor - self.mark
148    }
149}