Branch data Line data Source code
1 : : /* SPDX-License-Identifier: GPL-2.0-only */
2 : : /*
3 : : * Copyright (c) 2022 Meta Platforms, Inc. and affiliates.
4 : : */
5 : :
6 : : #include "bpfilter/pack.h"
7 : :
8 : : #include <errno.h>
9 : :
10 : : #include "bpfilter/core/list.h"
11 : : #include "bpfilter/helper.h"
12 : : #include "bpfilter/logger.h"
13 : : #include "mpack.h"
14 : :
15 : : struct bf_wpack
16 : : {
17 : : void *data;
18 : : size_t data_len;
19 : : size_t data_cap;
20 : :
21 : : char buffer[64];
22 : : mpack_writer_t writer;
23 : : };
24 : :
25 : 14417 : static void _bf_wpack_writer_flush_cb(mpack_writer_t *writer,
26 : : const char *buffer, size_t count)
27 : : {
28 : 14417 : bf_wpack_t *pack = writer->context;
29 : : int r;
30 : :
31 [ + + ]: 14417 : if (pack->data_cap <= pack->data_len + count) {
32 [ + + ]: 4752 : size_t new_cap = pack->data_cap ?: 64;
33 : :
34 [ + + ]: 9373 : while (new_cap <= pack->data_len + count)
35 : 4621 : new_cap <<= 1;
36 : :
37 : 4752 : r = bf_realloc(&pack->data, new_cap);
38 [ + + ]: 4752 : if (r) {
39 : 1 : mpack_writer_flag_error(writer, mpack_error_memory);
40 : 1 : return;
41 : : }
42 : :
43 : 4751 : pack->data_cap = new_cap;
44 : : }
45 : :
46 : 14416 : memcpy(pack->data + pack->data_len, buffer, count);
47 : 14416 : pack->data_len += count;
48 : : }
49 : :
50 : 1540 : int bf_wpack_new(bf_wpack_t **pack)
51 : : {
52 : : bf_wpack_t *_pack = NULL;
53 : :
54 : : assert(pack);
55 : :
56 : 1540 : _pack = malloc(sizeof(*_pack));
57 [ + - ]: 1540 : if (!_pack)
58 : : return -ENOMEM;
59 : :
60 : 1540 : _pack->data = NULL;
61 : 1540 : _pack->data_cap = 0;
62 : 1540 : _pack->data_len = 0;
63 : :
64 : 1540 : mpack_writer_init(&_pack->writer, _pack->buffer, 64);
65 : :
66 : : /* Use a custom flush function so we can control the flush
67 : : * (e.g. when get_data() is called). */
68 : 1540 : mpack_writer_set_flush(&_pack->writer, _bf_wpack_writer_flush_cb);
69 : : mpack_writer_set_context(&_pack->writer, _pack);
70 : :
71 : 1540 : mpack_build_map(&_pack->writer);
72 : :
73 : 1540 : *pack = TAKE_PTR(_pack);
74 : :
75 : 1540 : return 0;
76 : : }
77 : :
78 : 1542 : void bf_wpack_free(bf_wpack_t **pack)
79 : : {
80 : : bf_wpack_t *_pack;
81 : :
82 : : assert(pack);
83 : :
84 : 1542 : _pack = *pack;
85 [ + + ]: 1542 : if (!_pack)
86 : : return;
87 : :
88 : 1540 : mpack_writer_destroy(&_pack->writer);
89 : :
90 : 1540 : BF_FREEP(&_pack->data);
91 : 1540 : BF_FREEP(pack);
92 : : }
93 : :
94 [ + + ]: 19798 : bool bf_wpack_is_valid(bf_wpack_t *pack)
95 : : {
96 : : mpack_error_t error;
97 : :
98 : : assert(pack);
99 : :
100 : : error = mpack_writer_error(&pack->writer);
101 [ + + ]: 19798 : if (error != mpack_ok)
102 : 2 : return false;
103 : :
104 : : return true;
105 : : }
106 : :
107 : 1539 : int bf_wpack_get_data(bf_wpack_t *pack, const void **data, size_t *data_len)
108 : : {
109 : : assert(pack);
110 : : assert(data);
111 : : assert(data_len);
112 : :
113 : 1539 : mpack_complete_map(&pack->writer);
114 : :
115 : 1539 : mpack_writer_flush_message(&pack->writer);
116 [ + + ]: 1539 : if (!bf_wpack_is_valid(pack))
117 : : return -EINVAL;
118 : :
119 : 1538 : *data_len = pack->data_len;
120 : 1538 : *data = pack->data;
121 : :
122 : 1538 : return 0;
123 : : }
124 : :
125 : 5145 : void bf_wpack_nil(bf_wpack_t *pack)
126 : : {
127 : 5145 : mpack_write_nil(&pack->writer);
128 : 5145 : }
129 : :
130 : 20221 : void bf_wpack_int(bf_wpack_t *pack, int value)
131 : : {
132 : 20221 : mpack_write_int(&pack->writer, value);
133 : 20221 : }
134 : :
135 : 2 : void bf_wpack_uint(bf_wpack_t *pack, unsigned int value)
136 : : {
137 : 2 : mpack_write_uint(&pack->writer, value);
138 : 2 : }
139 : :
140 : 1765 : void bf_wpack_u8(bf_wpack_t *pack, uint8_t value)
141 : : {
142 : 1765 : mpack_write_u8(&pack->writer, value);
143 : 1765 : }
144 : :
145 : 2 : void bf_wpack_u16(bf_wpack_t *pack, uint16_t value)
146 : : {
147 : 2 : mpack_write_u16(&pack->writer, value);
148 : 2 : }
149 : :
150 : 3529 : void bf_wpack_u32(bf_wpack_t *pack, uint32_t value)
151 : : {
152 : 3529 : mpack_write_u32(&pack->writer, value);
153 : 3529 : }
154 : :
155 : 14195 : void bf_wpack_u64(bf_wpack_t *pack, uint64_t value)
156 : : {
157 : 14195 : mpack_write_u64(&pack->writer, value);
158 : 14195 : }
159 : :
160 : 4795 : void bf_wpack_bool(bf_wpack_t *pack, bool value)
161 : : {
162 : 4795 : mpack_write_bool(&pack->writer, value);
163 : 4795 : }
164 : :
165 : 70208 : void bf_wpack_str(bf_wpack_t *pack, const char *value)
166 : : {
167 : 70208 : mpack_write_cstr(&pack->writer, value);
168 : 70208 : }
169 : :
170 : 3428 : void bf_wpack_bin(bf_wpack_t *pack, const void *value, size_t len)
171 : : {
172 : : assert(pack);
173 : : assert(value);
174 : :
175 : 3428 : mpack_write_bin(&pack->writer, value, len);
176 : 3428 : }
177 : :
178 : 4749 : void bf_wpack_list(bf_wpack_t *pack, const bf_list *value)
179 : : {
180 : : int r;
181 : :
182 : : assert(pack);
183 : : assert(value);
184 : :
185 : 4749 : bf_wpack_open_array(pack, NULL);
186 : 4749 : r = bf_list_pack(value, pack);
187 [ - + ]: 4749 : if (r)
188 : 0 : mpack_writer_flag_error(&pack->writer, mpack_error_invalid);
189 : 4749 : bf_wpack_close_array(pack);
190 : 4749 : }
191 : :
192 : 4749 : void bf_wpack_kv_list(bf_wpack_t *pack, const char *key, const bf_list *value)
193 : : {
194 : 4749 : bf_wpack_str(pack, key);
195 : 4749 : bf_wpack_list(pack, value);
196 : 4749 : }
197 : :
198 : 12002 : void bf_wpack_open_object(bf_wpack_t *pack, const char *key)
199 : : {
200 : : assert(pack);
201 : :
202 [ + + ]: 12002 : if (key)
203 : 6731 : mpack_write_cstr(&pack->writer, key);
204 : :
205 : 12002 : mpack_build_map(&pack->writer);
206 : 12002 : }
207 : :
208 : 12002 : void bf_wpack_close_object(bf_wpack_t *pack)
209 : : {
210 : : assert(pack);
211 : :
212 : 12002 : mpack_complete_map(&pack->writer);
213 : 12002 : }
214 : :
215 : 7151 : void bf_wpack_open_array(bf_wpack_t *pack, const char *key)
216 : : {
217 : : assert(pack);
218 : :
219 [ + + ]: 7151 : if (key)
220 : 2402 : mpack_write_cstr(&pack->writer, key);
221 : :
222 : 7151 : mpack_build_array(&pack->writer);
223 : 7151 : }
224 : :
225 : 7151 : void bf_wpack_close_array(bf_wpack_t *pack)
226 : : {
227 : : assert(pack);
228 : :
229 : 7151 : mpack_complete_array(&pack->writer);
230 : 7151 : }
231 : :
232 : : struct bf_rpack
233 : : {
234 : : const void *data;
235 : : size_t data_len;
236 : :
237 : : mpack_tree_t tree;
238 : : mpack_node_t root;
239 : : };
240 : :
241 : 5845 : int bf_rpack_new(bf_rpack_t **pack, const void *data, size_t data_len)
242 : : {
243 : 5845 : _free_bf_rpack_ bf_rpack_t *_pack = NULL;
244 : : mpack_error_t error;
245 : :
246 : : assert(pack);
247 : :
248 : 5845 : _pack = calloc(1, sizeof(*_pack));
249 [ + - ]: 5845 : if (!_pack)
250 : : return -ENOMEM;
251 : :
252 : 5845 : _pack->data = data;
253 : 5845 : _pack->data_len = data_len;
254 : :
255 : 5845 : mpack_tree_init_data(&_pack->tree, data, data_len);
256 : :
257 : 5845 : mpack_tree_parse(&_pack->tree);
258 [ + + ]: 5845 : error = mpack_tree_error(&_pack->tree);
259 [ + + ]: 5845 : if (error != mpack_ok) {
260 [ + - ]: 1 : return bf_err_r(-EINVAL, "failed to parse bf_rpack_t data: %s",
261 : : mpack_error_to_string(error));
262 : : }
263 : :
264 : 5844 : _pack->root = mpack_tree_root(&_pack->tree);
265 : :
266 : 5844 : *pack = TAKE_PTR(_pack);
267 : :
268 : 5844 : return 0;
269 : : }
270 : :
271 : 11694 : void bf_rpack_free(bf_rpack_t **pack)
272 : : {
273 : : bf_rpack_t *_pack;
274 : :
275 : : assert(pack);
276 : :
277 : 11694 : _pack = *pack;
278 [ + + ]: 11694 : if (!_pack)
279 : : return;
280 : :
281 : 5845 : mpack_tree_destroy(&_pack->tree);
282 : 5845 : BF_FREEP(pack);
283 : : }
284 : :
285 : : #define MP_NODE(node) (*(mpack_node_t *)&(node))
286 : : #define BF_NODE(node) \
287 : : ({ \
288 : : union \
289 : : { \
290 : : mpack_node_t m; \
291 : : bf_rpack_node_t b; \
292 : : } _u_ = {0}; \
293 : : _u_.m = (node); \
294 : : _u_.b; \
295 : : })
296 : :
297 : : static_assert(sizeof(bf_rpack_node_t) >= sizeof(mpack_node_t),
298 : : "bf_rpack_node_t too small for mpack_node_t");
299 : :
300 : 5847 : bf_rpack_node_t bf_rpack_root(const bf_rpack_t *pack)
301 : : {
302 : 5847 : return BF_NODE(pack->root);
303 : : }
304 : :
305 : 84813 : size_t bf_rpack_array_count(bf_rpack_node_t node)
306 : : {
307 : 84813 : return mpack_node_array_length(MP_NODE(node));
308 : : }
309 : :
310 [ + - ]: 32265 : bool bf_rpack_is_nil(bf_rpack_node_t node)
311 : : {
312 [ + - ]: 32265 : if (mpack_node_error(MP_NODE(node)) != mpack_ok)
313 : : return false;
314 : :
315 : 32265 : return mpack_node_type(MP_NODE(node)) == mpack_type_nil;
316 : : }
317 : :
318 [ + - ]: 1 : bool bf_rpack_is_array(bf_rpack_node_t node)
319 : : {
320 [ + - ]: 1 : if (mpack_node_error(MP_NODE(node)) != mpack_ok)
321 : : return false;
322 : :
323 : 1 : return mpack_node_type(MP_NODE(node)) == mpack_type_array;
324 : : }
325 : :
326 : 16646 : bf_rpack_node_t bf_rpack_array_value_at(bf_rpack_node_t node, size_t index)
327 : : {
328 : 16646 : return BF_NODE(mpack_node_array_at(MP_NODE(node), index));
329 : : }
330 : :
331 : 31394 : bool bf_rpack_kv_contains(bf_rpack_node_t node, const char *key)
332 : : {
333 : 31394 : return mpack_node_map_contains_cstr(MP_NODE(node), key);
334 : : }
335 : :
336 : 240267 : int bf_rpack_kv_node(bf_rpack_node_t node, const char *key,
337 : : bf_rpack_node_t *child)
338 : : {
339 [ + - ]: 240267 : mpack_node_t _node = MP_NODE(node);
340 : :
341 : : assert(key);
342 : : assert(child);
343 : :
344 [ + - ]: 240267 : if (mpack_node_error(_node) != mpack_ok)
345 : : return -EINVAL;
346 : :
347 [ + - ]: 240267 : if (mpack_node_type(_node) != mpack_type_map)
348 : : return -EDOM;
349 : :
350 [ + + ]: 240267 : if (!mpack_node_map_contains_cstr(_node, key))
351 : : return -ENOENT;
352 : :
353 : 240263 : *child = BF_NODE(mpack_node_map_cstr(_node, key));
354 : :
355 : 240263 : return 0;
356 : : }
357 : :
358 : 62333 : int bf_rpack_int(bf_rpack_node_t node, int *value)
359 : : {
360 : 62333 : mpack_node_t _node = MP_NODE(node);
361 : : int _value;
362 : :
363 : : /* Signed integere are sometimes stored as unsigned integer for optimization
364 : : * purposes. While not ideal, we should allow the node to be an unsigned
365 : : * integer. */
366 [ + + + - ]: 124665 : if (mpack_node_type(_node) != mpack_type_int &&
367 : 62332 : mpack_node_type(_node) != mpack_type_uint)
368 : : return -EDOM;
369 : :
370 : 62333 : _value = mpack_node_int(_node);
371 [ + - ]: 62333 : if (mpack_node_error(_node) != mpack_ok)
372 : : return -EINVAL;
373 : :
374 : 62333 : *value = _value;
375 : :
376 : 62333 : return 0;
377 : : }
378 : :
379 : 60754 : int bf_rpack_kv_int(bf_rpack_node_t node, const char *key, int *value)
380 : : {
381 : : bf_rpack_node_t child;
382 : : int r;
383 : :
384 : 60754 : r = bf_rpack_kv_node(node, key, &child);
385 [ + + ]: 60754 : if (r)
386 : : return r;
387 : :
388 : 60753 : return bf_rpack_int(child, value);
389 : : }
390 : :
391 : 2 : int bf_rpack_uint(bf_rpack_node_t node, unsigned int *value)
392 : : {
393 [ + - ]: 2 : mpack_node_t _node = MP_NODE(node);
394 : : unsigned int _value;
395 : :
396 [ + - ]: 2 : if (mpack_node_error(_node) != mpack_ok)
397 : : return -EINVAL;
398 : :
399 [ + + ]: 2 : if (mpack_node_type(_node) != mpack_type_uint)
400 : : return -EDOM;
401 : :
402 : 1 : _value = mpack_node_uint(_node);
403 [ + - ]: 1 : if (mpack_node_error(_node) != mpack_ok)
404 : : return -EINVAL;
405 : :
406 : 1 : *value = _value;
407 : :
408 : 1 : return 0;
409 : : }
410 : :
411 : 2 : int bf_rpack_kv_uint(bf_rpack_node_t node, const char *key, unsigned int *value)
412 : : {
413 : : bf_rpack_node_t child;
414 : : int r;
415 : :
416 : 2 : r = bf_rpack_kv_node(node, key, &child);
417 [ + - ]: 2 : if (r)
418 : : return r;
419 : :
420 : 2 : return bf_rpack_uint(child, value);
421 : : }
422 : :
423 : 5781 : int bf_rpack_u8(bf_rpack_node_t node, uint8_t *value)
424 : : {
425 [ + - ]: 5781 : mpack_node_t _node = MP_NODE(node);
426 : : uint8_t _value;
427 : :
428 [ + - ]: 5781 : if (mpack_node_error(_node) != mpack_ok)
429 : : return -EINVAL;
430 : :
431 [ + - ]: 5781 : if (mpack_node_type(_node) != mpack_type_uint)
432 : : return -EDOM;
433 : :
434 : 5781 : _value = mpack_node_u8(_node);
435 [ + - ]: 5781 : if (mpack_node_error(_node) != mpack_ok)
436 : : return -EINVAL;
437 : :
438 : 5781 : *value = _value;
439 : :
440 : 5781 : return 0;
441 : : }
442 : :
443 : 5782 : int bf_rpack_kv_u8(bf_rpack_node_t node, const char *key, uint8_t *value)
444 : : {
445 : : bf_rpack_node_t child;
446 : : int r;
447 : :
448 : 5782 : r = bf_rpack_kv_node(node, key, &child);
449 [ + + ]: 5782 : if (r)
450 : : return r;
451 : :
452 : 5781 : return bf_rpack_u8(child, value);
453 : : }
454 : :
455 : 1 : int bf_rpack_u16(bf_rpack_node_t node, uint16_t *value)
456 : : {
457 [ + - ]: 1 : mpack_node_t _node = MP_NODE(node);
458 : : uint16_t _value;
459 : :
460 [ + - ]: 1 : if (mpack_node_error(_node) != mpack_ok)
461 : : return -EINVAL;
462 : :
463 [ + - ]: 1 : if (mpack_node_type(_node) != mpack_type_uint)
464 : : return -EDOM;
465 : :
466 : 1 : _value = mpack_node_u16(_node);
467 [ + - ]: 1 : if (mpack_node_error(_node) != mpack_ok)
468 : : return -EINVAL;
469 : :
470 : 1 : *value = _value;
471 : :
472 : 1 : return 0;
473 : : }
474 : :
475 : 1 : int bf_rpack_kv_u16(bf_rpack_node_t node, const char *key, uint16_t *value)
476 : : {
477 : : bf_rpack_node_t child;
478 : : int r;
479 : :
480 : 1 : r = bf_rpack_kv_node(node, key, &child);
481 [ + - ]: 1 : if (r)
482 : : return r;
483 : :
484 : 1 : return bf_rpack_u16(child, value);
485 : : }
486 : :
487 : 11562 : int bf_rpack_u32(bf_rpack_node_t node, uint32_t *value)
488 : : {
489 [ + - ]: 11562 : mpack_node_t _node = MP_NODE(node);
490 : : uint32_t _value;
491 : :
492 [ + - ]: 11562 : if (mpack_node_error(_node) != mpack_ok)
493 : : return -EINVAL;
494 : :
495 [ + - ]: 11562 : if (mpack_node_type(_node) != mpack_type_uint)
496 : : return -EDOM;
497 : :
498 : 11562 : _value = mpack_node_u32(_node);
499 [ + - ]: 11562 : if (mpack_node_error(_node) != mpack_ok)
500 : : return -EINVAL;
501 : :
502 : 11562 : *value = _value;
503 : :
504 : 11562 : return 0;
505 : : }
506 : :
507 : 11562 : int bf_rpack_kv_u32(bf_rpack_node_t node, const char *key, uint32_t *value)
508 : : {
509 : : bf_rpack_node_t child;
510 : : int r;
511 : :
512 : 11562 : r = bf_rpack_kv_node(node, key, &child);
513 [ + - ]: 11562 : if (r)
514 : : return r;
515 : :
516 : 11562 : return bf_rpack_u32(child, value);
517 : : }
518 : :
519 : 51381 : int bf_rpack_u64(bf_rpack_node_t node, uint64_t *value)
520 : : {
521 [ + - ]: 51381 : mpack_node_t _node = MP_NODE(node);
522 : : uint64_t _value;
523 : :
524 [ + - ]: 51381 : if (mpack_node_error(_node) != mpack_ok)
525 : : return -EINVAL;
526 : :
527 [ + - ]: 51381 : if (mpack_node_type(_node) != mpack_type_uint)
528 : : return -EDOM;
529 : :
530 : 51381 : _value = mpack_node_u64(_node);
531 [ + - ]: 51381 : if (mpack_node_error(_node) != mpack_ok)
532 : : return -EINVAL;
533 : :
534 : 51381 : *value = _value;
535 : :
536 : 51381 : return 0;
537 : : }
538 : :
539 : 39817 : int bf_rpack_size(bf_rpack_node_t node, size_t *value)
540 : : {
541 : : uint64_t _value;
542 : : int r;
543 : :
544 : 39817 : r = bf_rpack_u64(node, &_value);
545 [ + - ]: 39817 : if (r)
546 : : return r;
547 : :
548 : : #if SIZE_MAX < UINT64_MAX
549 : : if (_value > SIZE_MAX)
550 : : return -EOVERFLOW;
551 : : #endif
552 : :
553 : 39817 : *value = _value;
554 : :
555 : 39817 : return 0;
556 : : }
557 : :
558 : 11566 : int bf_rpack_kv_u64(bf_rpack_node_t node, const char *key, uint64_t *value)
559 : : {
560 : : bf_rpack_node_t child;
561 : : int r;
562 : :
563 : 11566 : r = bf_rpack_kv_node(node, key, &child);
564 [ + + ]: 11566 : if (r)
565 : : return r;
566 : :
567 : 11564 : return bf_rpack_u64(child, value);
568 : : }
569 : :
570 : 39817 : int bf_rpack_kv_size(bf_rpack_node_t node, const char *key, size_t *value)
571 : : {
572 : : bf_rpack_node_t child;
573 : : int r;
574 : :
575 : 39817 : r = bf_rpack_kv_node(node, key, &child);
576 [ + - ]: 39817 : if (r)
577 : : return r;
578 : :
579 : 39817 : return bf_rpack_size(child, value);
580 : : }
581 : :
582 : 24949 : int bf_rpack_str(bf_rpack_node_t node, char **value)
583 : : {
584 [ + - ]: 24949 : mpack_node_t _node = MP_NODE(node);
585 : : _cleanup_free_ char *_value = NULL;
586 : :
587 [ + - ]: 24949 : if (mpack_node_error(_node) != mpack_ok)
588 : : return -EINVAL;
589 : :
590 [ + + ]: 24949 : if (mpack_node_type(_node) != mpack_type_str)
591 : : return -EDOM;
592 : :
593 : 24948 : _value = mpack_node_cstr_alloc(_node, mpack_node_strlen(_node) + 1);
594 [ + - ]: 24948 : if (mpack_node_error(_node) != mpack_ok)
595 : : return -EINVAL;
596 : :
597 : 24948 : *value = TAKE_PTR(_value);
598 : :
599 : 24948 : return 0;
600 : : }
601 : :
602 : 24752 : int bf_rpack_kv_str(bf_rpack_node_t node, const char *key, char **value)
603 : : {
604 : : bf_rpack_node_t child;
605 : : int r;
606 : :
607 : : assert(key);
608 : : assert(value);
609 : :
610 : 24752 : r = bf_rpack_kv_node(node, key, &child);
611 [ + - ]: 24752 : if (r)
612 : : return r;
613 : :
614 : 24752 : return bf_rpack_str(child, value);
615 : : }
616 : :
617 : 11627 : int bf_rpack_bool(bf_rpack_node_t node, bool *value)
618 : : {
619 [ + - ]: 11627 : mpack_node_t _node = MP_NODE(node);
620 : : bool _value;
621 : :
622 [ + - ]: 11627 : if (mpack_node_error(_node) != mpack_ok)
623 : : return -EINVAL;
624 : :
625 [ + + ]: 11627 : if (mpack_node_type(_node) != mpack_type_bool)
626 : : return -EDOM;
627 : :
628 : 11626 : _value = mpack_node_bool(_node);
629 [ + - ]: 11626 : if (mpack_node_error(_node) != mpack_ok)
630 : : return -EINVAL;
631 : :
632 : 11626 : *value = _value;
633 : :
634 : 11626 : return 0;
635 : : }
636 : :
637 : 11627 : int bf_rpack_kv_bool(bf_rpack_node_t node, const char *key, bool *value)
638 : : {
639 : : bf_rpack_node_t child;
640 : : int r;
641 : :
642 : 11627 : r = bf_rpack_kv_node(node, key, &child);
643 [ + - ]: 11627 : if (r)
644 : : return r;
645 : :
646 : 11627 : return bf_rpack_bool(child, value);
647 : : }
648 : :
649 : 6846 : int bf_rpack_bin(bf_rpack_node_t node, const void **data, size_t *data_len)
650 : : {
651 [ + - ]: 6846 : mpack_node_t _node = MP_NODE(node);
652 : : const void *_data;
653 : : size_t _data_len;
654 : :
655 [ + - ]: 6846 : if (mpack_node_error(_node) != mpack_ok)
656 : : return -EINVAL;
657 : :
658 [ + - ]: 6846 : if (mpack_node_type(_node) != mpack_type_bin)
659 : : return -EDOM;
660 : :
661 : 6846 : _data_len = mpack_node_bin_size(_node);
662 : 6846 : _data = mpack_node_bin_data(_node);
663 [ + - ]: 6846 : if (mpack_node_error(_node) != mpack_ok)
664 : : return -EINVAL;
665 : :
666 : 6846 : *data = _data;
667 : 6846 : *data_len = _data_len;
668 : :
669 : 6846 : return 0;
670 : : }
671 : :
672 : 4585 : int bf_rpack_kv_bin(bf_rpack_node_t node, const char *key, const void **data,
673 : : size_t *data_len)
674 : : {
675 : : bf_rpack_node_t child;
676 : : int r;
677 : :
678 : 4585 : r = bf_rpack_kv_node(node, key, &child);
679 [ + - ]: 4585 : if (r)
680 : : return r;
681 : :
682 : 4585 : return bf_rpack_bin(child, data, data_len);
683 : : }
684 : :
685 : 6978 : int bf_rpack_kv_obj(bf_rpack_node_t node, const char *key,
686 : : bf_rpack_node_t *child)
687 : : {
688 : : bf_rpack_node_t _child;
689 : : int r;
690 : :
691 : : assert(key);
692 : : assert(child);
693 : :
694 : 6978 : r = bf_rpack_kv_node(node, key, &_child);
695 [ + - ]: 6978 : if (r)
696 : : return r;
697 : :
698 [ + - ]: 6978 : if (mpack_node_type(MP_NODE(_child)) != mpack_type_map)
699 : : return -EDOM;
700 : :
701 : 6978 : *child = _child;
702 : :
703 : 6978 : return 0;
704 : : }
705 : :
706 : 25759 : int bf_rpack_kv_array(bf_rpack_node_t node, const char *key,
707 : : bf_rpack_node_t *child)
708 : : {
709 : : bf_rpack_node_t _child;
710 : : int r;
711 : :
712 : : assert(key);
713 : : assert(child);
714 : :
715 : 25759 : r = bf_rpack_kv_node(node, key, &_child);
716 [ + - ]: 25759 : if (r)
717 : : return r;
718 : :
719 [ + - ]: 25759 : if (mpack_node_type(MP_NODE(_child)) != mpack_type_array)
720 : : return -EDOM;
721 : :
722 : 25759 : *child = _child;
723 : :
724 : 25759 : return 0;
725 : : }
|