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