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/*
21 * MIT License
22 *
23 * Permission is hereby granted, free of charge, to any person obtaining a copy
24 * of this software and associated documentation files (the "Software"), to deal
25 * in the Software without restriction, including without limitation the rights
26 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
27 * copies of the Software, and to permit persons to whom the Software is
28 * furnished to do so, subject to the following conditions:
29 *
30 * The above copyright notice and this permission notice shall be included in
31 * all copies or substantial portions of the Software.
32 *
33 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
39 * THE SOFTWARE.
40 */
41
42#include "iot/mqtt-fast/types/Binary.h"
43
44#ifndef DOXYGEN_SHOULD_SKIP_THIS
45
46#include <endian.h>
47
48#endif // DOXYGEN_SHOULD_SKIP_THIS
49
50namespace iot::mqtt_fast::types {
51
52 Binary::Binary(core::socket::SocketContext* socketContext)
53 : iot::mqtt_fast::types::TypeBase(socketContext) {
54 }
55
56 void Binary::setLength(std::vector<char>::size_type length) {
57 this->length = this->needed = static_cast<std::vector<char>::size_type>(length);
58
59 binary.resize(static_cast<std::vector<char>::size_type>(length), '\0');
60 }
61
62 std::vector<char>::size_type Binary::getLength() const {
63 return length;
64 }
65
66 std::size_t Binary::construct() {
67 std::size_t consumed = 0;
68
69 consumed = read(binary.data() + length - needed, static_cast<std::size_t>(needed));
70 needed -= consumed;
71 completed = needed == 0;
72
73 return consumed;
74 }
75
76 std::vector<char>& Binary::getValue() {
77 return binary;
78 }
79
80 uint8_t Binary::getInt8() {
81 uint8_t ret = 0;
82
83 if (!error && pointer + sizeof(uint8_t) <= length) {
84 ret = *reinterpret_cast<uint8_t*>(binary.data() + pointer);
85
86 pointer += sizeof(uint8_t);
87 } else {
88 error = true;
89 }
90
91 return ret;
92 }
93
94 uint16_t Binary::getInt16() {
95 uint16_t ret = 0;
96
97 if (!error && pointer + sizeof(uint16_t) <= length) {
98 ret = be16toh(*reinterpret_cast<uint16_t*>(binary.data() + pointer));
99
100 pointer += sizeof(uint16_t);
101 } else {
102 error = true;
103 }
104
105 return ret;
106 }
107
108 uint32_t Binary::getInt32() {
109 uint32_t ret = 0;
110
111 if (!error && pointer + sizeof(uint32_t) <= length) {
112 ret = be32toh(*reinterpret_cast<uint32_t*>(binary.data() + pointer));
113
114 pointer += sizeof(uint32_t);
115 } else {
116 error = true;
117 }
118
119 return ret;
120 }
121
122 uint64_t Binary::getInt64() {
123 uint64_t ret = 0;
124
125 if (!error && pointer + sizeof(uint64_t) <= length) {
126 ret = be64toh(*reinterpret_cast<uint64_t*>(binary.data() + pointer));
127
128 pointer += sizeof(uint64_t);
129 } else {
130 error = true;
131 }
132
133 return ret;
134 }
135
136 uint32_t Binary::getIntV() {
137 uint32_t value = 0;
138 uint32_t multiplier = 1;
139
140 do {
141 if (!error && pointer + sizeof(uint8_t) <= length) {
142 const uint8_t byte = *reinterpret_cast<uint8_t*>(binary.data() + pointer);
143 value += (byte & 0x7F) * multiplier;
144
145 if (multiplier > 0x80 * 0x80 * 0x80) {
146 error = true;
147 } else {
148 multiplier *= 0x80;
149 completed = (byte & 0x80) == 0;
150 }
151
152 pointer += sizeof(uint8_t);
153 } else {
154 error = true;
155 }
156 } while (!completed && !error);
157
158 return value;
159 }
160
161 std::string Binary::getString() {
162 std::string string;
163
164 if (!error && pointer + sizeof(uint16_t) <= length) {
165 const uint16_t stringLen = getInt16();
166
167 if (pointer + stringLen <= length) {
168 string = std::string(binary.data() + pointer, stringLen);
169
170 pointer += stringLen;
171 } else {
172 error = true;
173 }
174 } else {
175 error = true;
176 }
177
178 return string;
179 }
180
181 std::string Binary::getStringRaw() {
182 std::string string;
183
184 if (!error && length - pointer > 0) {
185 string = std::string(binary.data() + pointer, length - pointer);
187 } else {
188 error = true;
189 }
190
191 return string;
192 }
193
194 std::list<uint8_t> Binary::getUint8ListRaw() {
195 std::list<uint8_t> uint8List;
196
197 if (!error && length - pointer > 0) {
198 for (; pointer < length; ++pointer) {
199 uint8List.push_back(*reinterpret_cast<uint8_t*>((binary.data() + pointer)));
200 }
201 } else {
202 error = true;
203 }
204
205 return uint8List;
206 }
207
208 void Binary::putInt8(uint8_t value) {
209 binary.push_back(static_cast<char>(value));
210
211 length += sizeof(uint8_t);
212 }
213
214 void Binary::putInt16(uint16_t value) {
215 binary.push_back(static_cast<char>(value >> 0x08 & 0xFF));
216 binary.push_back(static_cast<char>(value & 0xFF));
217
218 length += sizeof(uint16_t);
219 }
220
221 void Binary::putInt32(uint32_t value) {
222 binary.push_back(static_cast<char>(value >> 0x18 & 0xFF));
223 binary.push_back(static_cast<char>(value >> 0x10 & 0xFF));
224 binary.push_back(static_cast<char>(value >> 0x08 & 0xFF));
225 binary.push_back(static_cast<char>(value & 0xFF));
226
227 length += sizeof(uint32_t);
228 }
229
230 void Binary::putInt64(uint64_t value) {
231 binary.push_back(static_cast<char>(value >> 0x38 & 0xFF));
232 binary.push_back(static_cast<char>(value >> 0x30 & 0xFF));
233 binary.push_back(static_cast<char>(value >> 0x28 & 0xFF));
234 binary.push_back(static_cast<char>(value >> 0x20 & 0xFF));
235 binary.push_back(static_cast<char>(value >> 0x18 & 0xFF));
236 binary.push_back(static_cast<char>(value >> 0x10 & 0xFF));
237 binary.push_back(static_cast<char>(value >> 0x08 & 0xFF));
238 binary.push_back(static_cast<char>(value & 0xFF));
239
240 length += sizeof(uint64_t);
241 }
242
243 void Binary::putIntV(uint32_t value) {
244 do {
245 uint8_t encodedByte = static_cast<uint8_t>(value % 0x80);
246
247 value /= 0x80;
248 if (value > 0) {
249 encodedByte |= 0x80;
250 }
251
252 putInt8(encodedByte);
253 } while (value > 0);
254 }
255
256 void Binary::putString(const std::string& string) {
257 const uint16_t stringLen = static_cast<uint16_t>(string.length());
258 putInt16(stringLen);
259
260 putStringRaw(string);
261 }
262
263 void Binary::putStringRaw(const std::string& string) {
264 binary.insert(binary.end(), string.begin(), string.end());
265
266 length += string.length();
267 }
268
269 void Binary::putUint8ListRaw(const std::list<uint8_t>& values) {
270 for (const uint8_t value : values) {
271 putInt8(value);
272 }
273 }
274
275 void Binary::reset() {
276 pointer = 0;
277 length = 0;
278 needed = 0;
279 binary.clear();
280
282 }
283
284} // namespace iot::mqtt_fast::types
std::vector< char >::size_type needed
Definition Binary.h:97
std::vector< char >::size_type length
Definition Binary.h:96
std::size_t construct() override
Definition Binary.cpp:66
void putUint8ListRaw(const std::list< uint8_t > &values)
Definition Binary.cpp:269
void putInt64(uint64_t value)
Definition Binary.cpp:230
std::list< uint8_t > getUint8ListRaw()
Definition Binary.cpp:194
void putStringRaw(const std::string &string)
Definition Binary.cpp:263
std::vector< char > binary
Definition Binary.h:99
void putInt8(uint8_t value)
Definition Binary.cpp:208
Binary(core::socket::SocketContext *socketContext=nullptr)
Definition Binary.cpp:52
void putInt32(uint32_t value)
Definition Binary.cpp:221
std::vector< char > & getValue()
Definition Binary.cpp:76
void putString(const std::string &string)
Definition Binary.cpp:256
std::vector< char >::size_type getLength() const
Definition Binary.cpp:62
void setLength(std::vector< char >::size_type length)
Definition Binary.cpp:56
void putIntV(uint32_t value)
Definition Binary.cpp:243
void putInt16(uint16_t value)
Definition Binary.cpp:214
std::vector< char >::size_type pointer
Definition Binary.h:95
TypeBase(core::socket::SocketContext *socketContext)
Definition TypeBase.cpp:52
std::size_t read(char *buf, std::size_t count)
Definition TypeBase.cpp:64