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