fix: isystem: delete global -isystem compile option (v5.16)
[lttng-modules.git] / src / lib / msgpack / msgpack.c
1 /*
2 * msgpack.c
3 *
4 * Copyright (C) 2020 Francis Deslauriers <francis.deslauriers@efficios.com>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; only
9 * version 2.1 of the License.
10 *
11 * This library 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 GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #define _GNU_SOURCE
22 #define _LGPL_SOURCE
23
24 #define MSGPACK_FIXSTR_ID_MASK 0xA0
25 #define MSGPACK_FIXMAP_ID_MASK 0x80
26 #define MSGPACK_FIXARRAY_ID_MASK 0x90
27
28 #define MSGPACK_NIL_ID 0xC0
29 #define MSGPACK_FALSE_ID 0xC2
30 #define MSGPACK_TRUE_ID 0xC3
31 #define MSGPACK_MAP16_ID 0xDE
32 #define MSGPACK_ARRAY16_ID 0xDC
33
34 #define MSGPACK_UINT8_ID 0xCC
35 #define MSGPACK_UINT16_ID 0xCD
36 #define MSGPACK_UINT32_ID 0xCE
37 #define MSGPACK_UINT64_ID 0xCF
38
39 #define MSGPACK_INT8_ID 0xD0
40 #define MSGPACK_INT16_ID 0xD1
41 #define MSGPACK_INT32_ID 0xD2
42 #define MSGPACK_INT64_ID 0xD3
43
44 #define MSGPACK_FLOAT64_ID 0xCB
45 #define MSGPACK_STR16_ID 0xDA
46
47 #define MSGPACK_FIXINT_MAX ((1 << 7) - 1)
48 #define MSGPACK_FIXINT_MIN -(1 << 5)
49 #define MSGPACK_FIXMAP_MAX_COUNT 15
50 #define MSGPACK_FIXARRAY_MAX_COUNT 15
51 #define MSGPACK_FIXSTR_MAX_LENGTH 31
52
53 #ifdef __KERNEL__
54 #include <linux/bug.h>
55 #include <linux/string.h>
56 #include <linux/types.h>
57 #include <asm/byteorder.h>
58
59 #include <lttng/msgpack.h>
60
61 #define INT8_MIN (-128)
62 #define INT16_MIN (-32767-1)
63 #define INT32_MIN (-2147483647-1)
64 #define INT8_MAX (127)
65 #define INT16_MAX (32767)
66 #define INT32_MAX (2147483647)
67 #define UINT8_MAX (255)
68 #define UINT16_MAX (65535)
69 #define UINT32_MAX (4294967295U)
70
71 #define byteswap_host_to_be16(_tmp) cpu_to_be16(_tmp)
72 #define byteswap_host_to_be32(_tmp) cpu_to_be32(_tmp)
73 #define byteswap_host_to_be64(_tmp) cpu_to_be64(_tmp)
74
75 #define lttng_msgpack_assert(cond) WARN_ON(!(cond))
76
77 #else /* __KERNEL__ */
78
79 #include <endian.h>
80 #include <stdio.h>
81 #include <string.h>
82
83 #include "msgpack.h"
84
85 #define byteswap_host_to_be16(_tmp) htobe16(_tmp)
86 #define byteswap_host_to_be32(_tmp) htobe32(_tmp)
87 #define byteswap_host_to_be64(_tmp) htobe64(_tmp)
88
89 #define lttng_msgpack_assert(cond) ({ \
90 if (!(cond)) \
91 fprintf(stderr, "Assertion failed. %s:%d\n", __FILE__, __LINE__); \
92 })
93 #endif /* __KERNEL__ */
94
95 static inline int lttng_msgpack_append_buffer(
96 struct lttng_msgpack_writer *writer,
97 const uint8_t *buf,
98 size_t length)
99 {
100 int ret = 0;
101
102 lttng_msgpack_assert(buf);
103
104 /* Ensure we are not trying to write after the end of the buffer. */
105 if (writer->write_pos + length > writer->end_write_pos) {
106 ret = -1;
107 goto end;
108 }
109
110 memcpy(writer->write_pos, buf, length);
111 writer->write_pos += length;
112 end:
113 return ret;
114 }
115
116 static inline int lttng_msgpack_append_u8(
117 struct lttng_msgpack_writer *writer, uint8_t value)
118 {
119 return lttng_msgpack_append_buffer(writer, &value, sizeof(value));
120 }
121
122 static inline int lttng_msgpack_append_u16(
123 struct lttng_msgpack_writer *writer, uint16_t value)
124 {
125 value = byteswap_host_to_be16(value);
126
127 return lttng_msgpack_append_buffer(writer, (uint8_t *) &value, sizeof(value));
128 }
129
130 static inline int lttng_msgpack_append_u32(
131 struct lttng_msgpack_writer *writer, uint32_t value)
132 {
133 value = byteswap_host_to_be32(value);
134
135 return lttng_msgpack_append_buffer(writer, (uint8_t *) &value, sizeof(value));
136 }
137
138 static inline int lttng_msgpack_append_u64(
139 struct lttng_msgpack_writer *writer, uint64_t value)
140 {
141 value = byteswap_host_to_be64(value);
142
143 return lttng_msgpack_append_buffer(writer, (uint8_t *) &value, sizeof(value));
144 }
145
146 static inline int lttng_msgpack_append_i8(
147 struct lttng_msgpack_writer *writer, int8_t value)
148 {
149 return lttng_msgpack_append_u8(writer, (uint8_t) value);
150 }
151
152 static inline int lttng_msgpack_append_i16(
153 struct lttng_msgpack_writer *writer, int16_t value)
154 {
155 return lttng_msgpack_append_u16(writer, (uint16_t) value);
156 }
157
158 static inline int lttng_msgpack_append_i32(
159 struct lttng_msgpack_writer *writer, int32_t value)
160 {
161 return lttng_msgpack_append_u32(writer, (uint32_t) value);
162 }
163
164 static inline int lttng_msgpack_append_i64(
165 struct lttng_msgpack_writer *writer, int64_t value)
166 {
167 return lttng_msgpack_append_u64(writer, (uint64_t) value);
168 }
169
170 static inline int lttng_msgpack_encode_fixmap(
171 struct lttng_msgpack_writer *writer, uint8_t count)
172 {
173 int ret = 0;
174
175 lttng_msgpack_assert(count <= MSGPACK_FIXMAP_MAX_COUNT);
176
177 ret = lttng_msgpack_append_u8(writer, MSGPACK_FIXMAP_ID_MASK | count);
178 if (ret)
179 goto end;
180
181 end:
182 return ret;
183 }
184
185 static inline int lttng_msgpack_encode_map16(
186 struct lttng_msgpack_writer *writer, uint16_t count)
187 {
188 int ret;
189
190 lttng_msgpack_assert(count > MSGPACK_FIXMAP_MAX_COUNT);
191
192 ret = lttng_msgpack_append_u8(writer, MSGPACK_MAP16_ID);
193 if (ret)
194 goto end;
195
196 ret = lttng_msgpack_append_u16(writer, count);
197 if (ret)
198 goto end;
199
200 end:
201 return ret;
202 }
203
204 static inline int lttng_msgpack_encode_fixarray(
205 struct lttng_msgpack_writer *writer, uint8_t count)
206 {
207 int ret = 0;
208
209 lttng_msgpack_assert(count <= MSGPACK_FIXARRAY_MAX_COUNT);
210
211 ret = lttng_msgpack_append_u8(writer, MSGPACK_FIXARRAY_ID_MASK | count);
212 if (ret)
213 goto end;
214
215 end:
216 return ret;
217 }
218
219 static inline int lttng_msgpack_encode_array16(
220 struct lttng_msgpack_writer *writer, uint16_t count)
221 {
222 int ret;
223
224 lttng_msgpack_assert(count > MSGPACK_FIXARRAY_MAX_COUNT);
225
226 ret = lttng_msgpack_append_u8(writer, MSGPACK_ARRAY16_ID);
227 if (ret)
228 goto end;
229
230 ret = lttng_msgpack_append_u16(writer, count);
231 if (ret)
232 goto end;
233
234 end:
235 return ret;
236 }
237
238 static inline int lttng_msgpack_encode_fixstr(
239 struct lttng_msgpack_writer *writer,
240 const char *str,
241 uint8_t len)
242 {
243 int ret;
244
245 lttng_msgpack_assert(len <= MSGPACK_FIXSTR_MAX_LENGTH);
246
247 ret = lttng_msgpack_append_u8(writer, MSGPACK_FIXSTR_ID_MASK | len);
248 if (ret)
249 goto end;
250
251 ret = lttng_msgpack_append_buffer(writer, (uint8_t *) str, len);
252 if (ret)
253 goto end;
254
255 end:
256 return ret;
257 }
258
259 static inline int lttng_msgpack_encode_str16(
260 struct lttng_msgpack_writer *writer,
261 const char *str,
262 uint16_t len)
263 {
264 int ret;
265
266 lttng_msgpack_assert(len > MSGPACK_FIXSTR_MAX_LENGTH);
267
268 ret = lttng_msgpack_append_u8(writer, MSGPACK_STR16_ID);
269 if (ret)
270 goto end;
271
272 ret = lttng_msgpack_append_u16(writer, len);
273 if (ret)
274 goto end;
275
276 ret = lttng_msgpack_append_buffer(writer, (uint8_t *) str, len);
277 if (ret)
278 goto end;
279
280 end:
281 return ret;
282 }
283
284 int lttng_msgpack_begin_map(struct lttng_msgpack_writer *writer, size_t count)
285 {
286 int ret;
287
288 if (count >= (1 << 16)) {
289 ret = -1;
290 goto end;
291 }
292
293 if (count <= MSGPACK_FIXMAP_MAX_COUNT)
294 ret = lttng_msgpack_encode_fixmap(writer, count);
295 else
296 ret = lttng_msgpack_encode_map16(writer, count);
297
298 writer->map_nesting++;
299 end:
300 return ret;
301 }
302
303 int lttng_msgpack_end_map(struct lttng_msgpack_writer *writer)
304 {
305 lttng_msgpack_assert(writer->map_nesting > 0);
306 writer->map_nesting--;
307 return 0;
308 }
309
310 int lttng_msgpack_begin_array(
311 struct lttng_msgpack_writer *writer, size_t count)
312 {
313 int ret;
314
315 if (count >= (1 << 16)) {
316 ret = -1;
317 goto end;
318 }
319
320 if (count <= MSGPACK_FIXARRAY_MAX_COUNT)
321 ret = lttng_msgpack_encode_fixarray(writer, count);
322 else
323 ret = lttng_msgpack_encode_array16(writer, count);
324
325 writer->array_nesting++;
326 end:
327 return ret;
328 }
329
330 int lttng_msgpack_end_array(struct lttng_msgpack_writer *writer)
331 {
332 lttng_msgpack_assert(writer->array_nesting > 0);
333 writer->array_nesting--;
334 return 0;
335 }
336
337 int lttng_msgpack_write_str(struct lttng_msgpack_writer *writer,
338 const char *str)
339 {
340 int ret;
341 size_t length = strlen(str);
342
343 if (length >= (1 << 16)) {
344 ret = -1;
345 goto end;
346 }
347
348 if (length <= MSGPACK_FIXSTR_MAX_LENGTH)
349 ret = lttng_msgpack_encode_fixstr(writer, str, length);
350 else
351 ret = lttng_msgpack_encode_str16(writer, str, length);
352
353 end:
354 return ret;
355 }
356
357 int lttng_msgpack_write_nil(struct lttng_msgpack_writer *writer)
358 {
359 return lttng_msgpack_append_u8(writer, MSGPACK_NIL_ID);
360 }
361
362 int lttng_msgpack_write_true(struct lttng_msgpack_writer *writer)
363 {
364 return lttng_msgpack_append_u8(writer, MSGPACK_TRUE_ID);
365 }
366
367 int lttng_msgpack_write_false(struct lttng_msgpack_writer *writer)
368 {
369 return lttng_msgpack_append_u8(writer, MSGPACK_FALSE_ID);
370 }
371
372 int lttng_msgpack_write_unsigned_integer(
373 struct lttng_msgpack_writer *writer, uint64_t value)
374 {
375 int ret = 0;
376
377 if (value <= MSGPACK_FIXINT_MAX) {
378 ret = lttng_msgpack_append_u8(writer, (uint8_t) value);
379 if (ret)
380 goto end;
381 } else if (value <= UINT8_MAX) {
382 ret = lttng_msgpack_append_u8(writer, MSGPACK_UINT8_ID);
383 if (ret)
384 goto end;
385
386 ret = lttng_msgpack_append_u8(writer, (uint8_t) value);
387 if (ret)
388 goto end;
389 } else if (value <= UINT16_MAX) {
390 ret = lttng_msgpack_append_u8(writer, MSGPACK_UINT16_ID);
391 if (ret)
392 goto end;
393
394 ret = lttng_msgpack_append_u16(writer, (uint16_t) value);
395 if (ret)
396 goto end;
397 } else if (value <= UINT32_MAX) {
398 ret = lttng_msgpack_append_u8(writer, MSGPACK_UINT32_ID);
399 if (ret)
400 goto end;
401
402 ret = lttng_msgpack_append_u32(writer, (uint32_t) value);
403 if (ret)
404 goto end;
405 } else {
406 ret = lttng_msgpack_append_u8(writer, MSGPACK_UINT64_ID);
407 if (ret)
408 goto end;
409
410 ret = lttng_msgpack_append_u64(writer, value);
411 if (ret)
412 goto end;
413 }
414
415 end:
416 return ret;
417 }
418
419 int lttng_msgpack_write_signed_integer(struct lttng_msgpack_writer *writer, int64_t value)
420 {
421 int ret;
422
423 if (value >= MSGPACK_FIXINT_MIN && value <= MSGPACK_FIXINT_MAX){
424 ret = lttng_msgpack_append_i8(writer, (int8_t) value);
425 if (ret)
426 goto end;
427 } else if (value >= INT8_MIN && value <= INT8_MAX) {
428 ret = lttng_msgpack_append_u8(writer, MSGPACK_INT8_ID);
429 if (ret)
430 goto end;
431
432 ret = lttng_msgpack_append_i8(writer, (int8_t) value);
433 if (ret)
434 goto end;
435 } else if (value >= INT16_MIN && value <= INT16_MAX) {
436 ret = lttng_msgpack_append_u8(writer, MSGPACK_INT16_ID);
437 if (ret)
438 goto end;
439
440 ret = lttng_msgpack_append_i16(writer, (int16_t) value);
441 if (ret)
442 goto end;
443 } else if (value >= INT32_MIN && value <= INT32_MAX) {
444 ret = lttng_msgpack_append_u8(writer, MSGPACK_INT32_ID);
445 if (ret)
446 goto end;
447
448 ret = lttng_msgpack_append_i32(writer, (int32_t) value);
449 if (ret)
450 goto end;
451 } else {
452 ret = lttng_msgpack_append_u8(writer, MSGPACK_INT64_ID);
453 if (ret)
454 goto end;
455
456 ret = lttng_msgpack_append_i64(writer, value);
457 if (ret)
458 goto end;
459 }
460
461 end:
462 return ret;
463 }
464
465 void lttng_msgpack_writer_init(struct lttng_msgpack_writer *writer,
466 uint8_t *buffer, size_t size)
467 {
468 lttng_msgpack_assert(buffer);
469 lttng_msgpack_assert(size >= 0);
470
471 writer->buffer = buffer;
472 writer->write_pos = buffer;
473 writer->end_write_pos = buffer + size;
474
475 writer->array_nesting = 0;
476 writer->map_nesting = 0;
477 }
478
479 void lttng_msgpack_writer_fini(struct lttng_msgpack_writer *writer)
480 {
481 memset(writer, 0, sizeof(*writer));
482 }
This page took 0.038063 seconds and 4 git commands to generate.