SNode.C
Loading...
Searching...
No Matches
Binary.cpp
Go to the documentation of this file.
1/*
2 * SNode.C - a slim toolkit for network communication
3 * Copyright (C) Volker Christian <me@vchrist.at>
4 * 2020, 2021, 2022, 2023, 2024, 2025
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as published
8 * by the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include "iot/mqtt-fast/types/Binary.h"
21
22#ifndef DOXYGEN_SHOULD_SKIP_THIS
23
24#include <endian.h>
25
26#endif // DOXYGEN_SHOULD_SKIP_THIS
27
28namespace iot::mqtt_fast::types {
29
30 Binary::Binary(core::socket::SocketContext* socketContext)
31 : iot::mqtt_fast::types::TypeBase(socketContext) {
32 }
33
34 void Binary::setLength(std::vector<char>::size_type length) {
35 this->length = this->needed = static_cast<std::vector<char>::size_type>(length);
36
37 binary.resize(static_cast<std::vector<char>::size_type>(length), '\0');
38 }
39
40 std::vector<char>::size_type Binary::getLength() const {
41 return length;
42 }
43
45 std::size_t consumed = 0;
46
47 consumed = read(binary.data() + length - needed, static_cast<std::size_t>(needed));
49 completed = needed == 0;
50
51 return consumed;
52 }
53
55 return binary;
56 }
57
59 uint8_t ret = 0;
60
61 if (!error && pointer + sizeof(uint8_t) <= length) {
62 ret = *reinterpret_cast<uint8_t*>(binary.data() + pointer);
63
64 pointer += sizeof(uint8_t);
65 } else {
66 error = true;
67 }
68
69 return ret;
70 }
71
73 uint16_t ret = 0;
74
75 if (!error && pointer + sizeof(uint16_t) <= length) {
76 ret = be16toh(*reinterpret_cast<uint16_t*>(binary.data() + pointer));
77
78 pointer += sizeof(uint16_t);
79 } else {
80 error = true;
81 }
82
83 return ret;
84 }
85
87 uint32_t ret = 0;
88
89 if (!error && pointer + sizeof(uint32_t) <= length) {
90 ret = be32toh(*reinterpret_cast<uint32_t*>(binary.data() + pointer));
91
92 pointer += sizeof(uint32_t);
93 } else {
94 error = true;
95 }
96
97 return ret;
98 }
99
101 uint64_t ret = 0;
102
103 if (!error && pointer + sizeof(uint64_t) <= length) {
104 ret = be64toh(*reinterpret_cast<uint64_t*>(binary.data() + pointer));
105
106 pointer += sizeof(uint64_t);
107 } else {
108 error = true;
109 }
110
111 return ret;
112 }
113
115 uint32_t value = 0;
117
118 do {
119 if (!error && pointer + sizeof(uint8_t) <= length) {
120 const uint8_t byte = *reinterpret_cast<uint8_t*>(binary.data() + pointer);
121 value += (byte & 0x7F) * multiplier;
122
123 if (multiplier > 0x80 * 0x80 * 0x80) {
124 error = true;
125 } else {
126 multiplier *= 0x80;
127 completed = (byte & 0x80) == 0;
128 }
129
130 pointer += sizeof(uint8_t);
131 } else {
132 error = true;
133 }
134 } while (!completed && !error);
135
136 return value;
137 }
138
141
142 if (!error && pointer + sizeof(uint16_t) <= length) {
143 const uint16_t stringLen = getInt16();
144
145 if (pointer + stringLen <= length) {
147
149 } else {
150 error = true;
151 }
152 } else {
153 error = true;
154 }
155
156 return string;
157 }
158
161
162 if (!error && length - pointer > 0) {
165 } else {
166 error = true;
167 }
168
169 return string;
170 }
171
174
175 if (!error && length - pointer > 0) {
176 for (; pointer < length; ++pointer) {
177 uint8List.push_back(*reinterpret_cast<uint8_t*>((binary.data() + pointer)));
178 }
179 } else {
180 error = true;
181 }
182
183 return uint8List;
184 }
185
187 binary.push_back(static_cast<char>(value));
188
189 length += sizeof(uint8_t);
190 }
191
193 binary.push_back(static_cast<char>(value >> 0x08 & 0xFF));
194 binary.push_back(static_cast<char>(value & 0xFF));
195
196 length += sizeof(uint16_t);
197 }
198
200 binary.push_back(static_cast<char>(value >> 0x18 & 0xFF));
201 binary.push_back(static_cast<char>(value >> 0x10 & 0xFF));
202 binary.push_back(static_cast<char>(value >> 0x08 & 0xFF));
203 binary.push_back(static_cast<char>(value & 0xFF));
204
205 length += sizeof(uint32_t);
206 }
207
209 binary.push_back(static_cast<char>(value >> 0x38 & 0xFF));
210 binary.push_back(static_cast<char>(value >> 0x30 & 0xFF));
211 binary.push_back(static_cast<char>(value >> 0x28 & 0xFF));
212 binary.push_back(static_cast<char>(value >> 0x20 & 0xFF));
213 binary.push_back(static_cast<char>(value >> 0x18 & 0xFF));
214 binary.push_back(static_cast<char>(value >> 0x10 & 0xFF));
215 binary.push_back(static_cast<char>(value >> 0x08 & 0xFF));
216 binary.push_back(static_cast<char>(value & 0xFF));
217
218 length += sizeof(uint64_t);
219 }
220
222 do {
223 uint8_t encodedByte = static_cast<uint8_t>(value % 0x80);
224
225 value /= 0x80;
226 if (value > 0) {
227 encodedByte |= 0x80;
228 }
229
231 } while (value > 0);
232 }
233
235 const uint16_t stringLen = static_cast<uint16_t>(string.length());
237
239 }
240
243
244 length += string.length();
245 }
246
248 for (const uint8_t value : values) {
249 putInt8(value);
250 }
251 }
252
253 void Binary::reset() {
254 pointer = 0;
255 length = 0;
256 needed = 0;
257 binary.clear();
258
260 }
261
262} // namespace iot::mqtt_fast::types
Binary(core::socket::SocketContext *socketContext=nullptr)
Definition Binary.cpp:30
TypeBase(core::socket::SocketContext *socketContext)
Definition TypeBase.cpp:30