Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 25 additions & 21 deletions src/printer_cbor.c
Original file line number Diff line number Diff line change
Expand Up @@ -1148,15 +1148,15 @@ cbor_print_opaq(struct cborpr_ctx *pctx, const struct lyd_node_opaq *node, cbor_
}

if (first) {
key = cbor_print_member_name2(pctx, pctx->parent, node->format, &node->name, 0);
LY_CHECK_RET(!key, LY_EMEM);

if (hints & (LYD_NODEHINT_LIST | LYD_NODEHINT_LEAFLIST)) {
/* start new array, the member name is generated once the array is completed */
cbor_item_t *new_array = cbor_new_indefinite_array();

LY_CHECK_ERR_RET(!new_array, free(key), LY_EMEM);
LY_CHECK_ERR_RET(cbor_print_array_open(pctx, &node->node, new_array),
cbor_decref(&new_array); free(key), LY_EINVAL);
LY_CHECK_RET(!new_array, LY_EMEM);
LY_CHECK_ERR_RET(cbor_print_array_open(pctx, &node->node, new_array), cbor_decref(&new_array), LY_EINVAL);
} else {
key = cbor_print_member_name2(pctx, pctx->parent, node->format, &node->name, 0);
LY_CHECK_RET(!key, LY_EMEM);
}
}

Expand Down Expand Up @@ -1238,25 +1238,29 @@ cbor_print_opaq(struct cborpr_ctx *pctx, const struct lyd_node_opaq *node, cbor_
}

if (last && (hints & (LYD_NODEHINT_LIST | LYD_NODEHINT_LEAFLIST))) {
if (key) {
struct cbor_pair pair = {
.key = cbor_move(cbor_build_string(key)),
.value = cbor_move(cbor_current_array(pctx))
};
cbor_item_t *array = cbor_current_array(pctx);

free(key);

if (!cbor_map_add(parent_map, pair)) {
cbor_decref(&pair.key);
cbor_decref(&pair.value);
return LY_EMEM;
}
key = cbor_print_member_name2(pctx, pctx->parent, node->format, &node->name, 0);
if (!key) {
cbor_decref(&array);
cbor_print_array_close(pctx);
return LY_EMEM;
}
cbor_print_array_close(pctx);
}

if (key) {
/* add completed array to parent map */
struct cbor_pair pair = {
.key = cbor_move(cbor_build_string(key)),
.value = cbor_move(array)
};

free(key);

if (!cbor_map_add(parent_map, pair)) {
cbor_decref(&pair.key);
cbor_decref(&pair.value);
return LY_EMEM;
}
cbor_print_array_close(pctx);
}

return LY_SUCCESS;
Expand Down
35 changes: 35 additions & 0 deletions tests/utests/data/test_cbor.c
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,40 @@ test_opaque(void **state)
lyd_free_all(tree);
}

static void
test_opaque_list(void **state)
{
struct lyd_node *tree;
char *buffer, *json;
struct ly_out *out;
size_t i;

/* invalid leaf-list values are stored as opaque nodes, one and more instances */
const struct test_case tests[] = {
{"single", "{\"cbor-test:ll-intg32\":[\"not a number\"]}"},
{"multiple", "{\"cbor-test:ll-intg32\":[\"x\",\"y\",\"z\"]}"},
{"nested", "{\"cbor-test:list-nested\":[{\"id\":\"a\",\"inner\":[{\"iid\":1,\"vals\":[\"q\"]}]}]}"},
};

for (i = 0; i < sizeof tests / sizeof *tests; ++i) {
CHECK_PARSE_LYD_PARAM(tests[i].json, LYD_JSON, LYD_PARSE_ONLY | LYD_PARSE_OPAQ, 0, LY_SUCCESS, tree);

assert_int_equal(LY_SUCCESS, ly_out_new_memory(&buffer, 0, &out));
assert_int_equal(LY_SUCCESS, lyd_print_all(out, tree, LYD_CBOR, 0));
lyd_free_all(tree);

assert_int_equal(LY_SUCCESS, lyd_parse_data_mem_len(UTEST_LYCTX, buffer, (uint32_t)ly_out_printed(out), LYD_CBOR,
LYD_PARSE_ONLY | LYD_PARSE_OPAQ, 0, &tree));
ly_out_free(out, NULL, 0);
free(buffer);

assert_int_equal(LY_SUCCESS, lyd_print_mem(&json, tree, LYD_JSON, LYD_PRINT_SHRINK | LYD_PRINT_SIBLINGS));
assert_string_equal(json, tests[i].json);
free(json);
lyd_free_all(tree);
}
}

static void
test_attributes(void **state)
{
Expand Down Expand Up @@ -404,6 +438,7 @@ main(void)
UTEST(test_operations, setup),
UTEST(test_schema_mount, setup),
UTEST(test_opaque, setup),
UTEST(test_opaque_list, setup),
UTEST(test_attributes, setup),
};

Expand Down
Loading