tinymqtt/
reader_writer.rs1use 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 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}