28 #include "ly_common.h"
30 #include "plugins_internal.h"
44 static void lyplg_type_free_union(
const struct ly_ctx *ctx,
struct lyd_value *value);
49 #define LYPLG_UNION_TYPE_IDX_SIZE 1
61 union_validate_value_lyb(
const void *lyb_data, uint64_t lyb_data_size_bits,
const struct lysc_type_union *type_u,
64 uint32_t type_idx = 0;
74 type_idx = le32toh(type_idx);
77 "Invalid LYB union type index %" PRIu32
" (type count %" LYA_PRI_COUNT_T ").",
95 union_parse_value_lyb(
const void *lyb_data, uint64_t lyb_data_size_bits, uint32_t *type_idx,
const void **lyb_value,
96 uint64_t *lyb_value_size_bits)
109 if (lyb_value && lyb_value_size_bits && lyb_data_size_bits) {
112 *lyb_value_size_bits = 0;
134 union_create_value_lyb(
const struct ly_ctx *ctx, uint32_t type_idx,
const struct lyd_value *value,
void **lyb_value,
139 const void *pval = NULL;
140 uint64_t pval_size_bits, lyb_bits = 0;
163 num = htole32(type_idx);
173 *lyb_size_bits = lyb_bits;
190 union_update_lref_err(
struct ly_err_item *err,
const struct lysc_type *type,
const void *value, uint64_t value_size_bits)
205 err->
apptag = strdup(
"instance-required");
208 valstr = strndup((
const char *)value, value_size_bits / 8);
209 LY_CHECK_ERR_RET(!valstr, LOGMEM(NULL),
LY_EMEM);
215 LY_CHECK_ERR_RET(r == -1, LOGMEM(NULL),
LY_EMEM);
238 union_subvalue_get_input_value(
const struct ly_ctx *ctx,
const struct lysc_type_union *type_u, uint32_t type_idx,
248 *value_size_bits = 0;
256 if (ti != type_idx) {
263 union_update_lref_err(*err, type_u->
types[ti], *value, *value_size_bits);
271 assert(!(*value_size_bits % 8));
275 *value = strndup(*value, *value_size_bits / 8);
278 type_plg->
free(ctx, &storage);
283 *format = subvalue->
format;
289 *format = subvalue->
format;
317 union_store_type(
const struct ly_ctx *ctx,
const struct lysc_type *type,
const void *value, uint64_t value_size_bits,
327 type_plg = LYSC_GET_TYPE_PLG(type->
plugin_ref);
335 rc = type_plg->
store(ctx, type, value, value_size_bits, options, format, prefix_data, hints, ctx_snode, storage,
340 union_update_lref_err(*err, type, value, value_size_bits);
343 memset(storage, 0,
sizeof *storage);
370 union_read_store_type(
const struct ly_ctx *ctx,
const struct lysc_type_union *type_u, uint32_t type_idx,
376 uint64_t value_size_bits;
383 r = union_subvalue_get_input_value(ctx, type_u, type_idx, subvalue, &value, &value_size_bits, &dynamic, &format,
397 rc = union_store_type(ctx, type_u->
types[type_idx], value, value_size_bits, options, format, prefix_data,
410 memset(&subvalue->
value, 0,
sizeof subvalue->
value);
436 uint32_t options,
const struct lyd_node *ctx_node,
const struct lyd_node *tree,
const struct ly_ht *unres_ht,
437 uint32_t *type_idx,
struct lys_glob_unres *unres,
struct ly_err_item **err)
442 uint32_t *prev_lo, temp_lo = 0;
443 char *
msg = NULL, *err_app_tag = NULL;
444 uint32_t msg_size = 0, msg_len = 0;
459 rc = union_read_store_type(ctx, type_u, u, subvalue, options, ctx_node, tree, unres_ht, unres, &e);
471 r = ly_append_str(&msg, &msg_size, &msg_len,
"Invalid LYB union value - no matching subtype found:\n");
473 r = ly_append_str(&msg, &msg_size, &msg_len,
"Invalid union value \"%.*s\" - no matching subtype found:\n",
476 LY_CHECK_ERR_GOTO(r, rc =
LY_EMEM, cleanup);
484 if (errs[u]->apptag) {
486 err_app_tag = strdup(errs[u]->apptag);
487 LY_CHECK_ERR_GOTO(!err_app_tag, rc =
LY_EMEM, cleanup);
489 }
else if (strcmp(errs[u]->apptag, err_app_tag)) {
496 r = ly_append_str(&msg, &msg_size, &msg_len,
" %s: %s\n", type_plg->
id, errs[u]->msg);
497 LY_CHECK_ERR_GOTO(r, rc =
LY_EMEM, cleanup);
500 if (!use_err_app_tag) {
506 }
else if (type_idx) {
540 union_prepare_subvalue(
const struct ly_ctx *ctx,
const struct lysc_type *type,
const void *value, uint64_t value_size_bits,
547 memset(storage, 0,
sizeof *storage);
552 (*subvalue)->hints = hints;
553 (*subvalue)->ctx_node = ctx_node;
557 (*subvalue)->original = (
void *)value;
559 }
else if (value_size_bits) {
564 (*subvalue)->original = strdup(
"");
567 (*subvalue)->orig_size_bits = value_size_bits;
572 (format ==
LY_VALUE_LYB) ? NULL : prefix_data, &(*subvalue)->format, &(*subvalue)->prefix_data);
576 lyplg_type_store_union(
const struct ly_ctx *ctx,
const struct lysc_type *type,
const void *value, uint64_t value_size_bits,
583 uint32_t type_idx = 0;
590 rc = union_prepare_subvalue(ctx, type, value, value_size_bits, &options, format, prefix_data, hints,
591 ctx_node, storage, &subvalue, err);
592 LY_CHECK_GOTO(rc, cleanup);
596 rc = union_validate_value_lyb(value, value_size_bits, type_u, err);
597 LY_CHECK_GOTO(rc, cleanup);
598 union_parse_value_lyb(value, 0, &type_idx, NULL, NULL);
601 rc = union_read_store_type(ctx, type_u, type_idx, subvalue, options, NULL, NULL, NULL, unres, err);
605 rc = union_find_type(ctx, type_u, subvalue, options & ~
LYPLG_TYPE_STORE_ONLY, NULL, NULL, NULL, NULL, unres, err);
609 rc = union_find_type(ctx, type_u, subvalue, options, NULL, NULL, NULL, NULL, unres, err);
616 LY_CHECK_ERR_GOTO(r, rc = r, cleanup);
624 lyplg_type_free_union(ctx, storage);
631 const void *value, uint64_t value_size_bits, uint32_t options,
LY_VALUE_FORMAT format,
void *prefix_data,
638 uint64_t lyb_size_bits;
643 memset(storage, 0,
sizeof *storage);
647 LY_CHECK_ERR_GOTO(!subvalue, rc =
LY_EMEM, cleanup);
655 r = union_create_value_lyb(ctx, type_idx, &subvalue->
value, &lyb, &lyb_size_bits, err);
656 LY_CHECK_ERR_GOTO(r, rc = r, cleanup);
667 LY_CHECK_ERR_GOTO(r, rc = r, cleanup);
676 lyplg_type_free_union(ctx, storage);
677 memset(storage, 0,
sizeof *storage);
700 LY_CHECK_RET(realtype_plg->
duplicate(ctx, &subvalue->
value, &orig));
701 realtype_plg->
free(ctx, &subvalue->
value);
705 union_parse_value_lyb(subvalue->
original, 0, &type_idx, NULL, NULL);
707 if (union_read_store_type(ctx, type_u, type_idx, subvalue, 0, ctx_node, tree, unres_ht, NULL, err)) {
718 rc = union_find_type(ctx, type_u, subvalue, 0, ctx_node, tree, unres_ht, NULL, NULL, err);
719 LY_CHECK_GOTO(rc, cleanup);
730 subvalue->
value = orig;
745 &val1->subvalue->value, &val2->subvalue->value);
757 &val1->subvalue->value, &val2->subvalue->value);
770 if (type == val1->subvalue->value.
realtype) {
773 }
else if (type == val2->subvalue->value.
realtype) {
795 uint64_t *value_size_bits)
800 uint32_t type_idx = 0;
813 LY_CHECK_RET(realtype_plg->
duplicate(ctx, &subvalue->
value, &orig), NULL);
814 realtype_plg->
free(ctx, &subvalue->
value);
817 r = union_find_type(ctx, type_u, subvalue, 0, NULL, NULL, NULL, &type_idx, NULL, &err);
821 r = union_find_type(ctx, type_u, subvalue,
LYPLG_TYPE_STORE_ONLY, NULL, NULL, NULL, &type_idx, NULL, &err);
827 r = union_create_value_lyb(NULL, type_idx, &subvalue->
value, &ret, value_size_bits, &err);
829 LY_CHECK_ERR_RET(r, subvalue->
value = orig, NULL);
833 realtype_plg->
free(ctx, &subvalue->
value);
834 subvalue->
value = orig;
840 void *prefix_data,
ly_bool *dynamic, uint64_t *value_size_bits)
845 uint64_t lyb_data_size_bits = 0;
850 if (value_size_bits) {
857 ret = union_print_value_lyb(ctx, type_u, subvalue, &lyb_data_size_bits);
858 if (value_size_bits) {
859 *value_size_bits = lyb_data_size_bits;
866 format, prefix_data, dynamic, value_size_bits);
882 memset(dup, 0,
sizeof *dup);
886 LY_CHECK_GOTO(ret, cleanup);
888 dup_val = calloc(1,
sizeof *dup_val);
889 LY_CHECK_ERR_GOTO(!dup_val, LOGMEM(ctx); ret =
LY_EMEM, cleanup);
890 dup->subvalue = dup_val;
893 LY_CHECK_GOTO(ret, cleanup);
897 LY_CHECK_ERR_GOTO(!dup_val->original, LOGMEM(ctx); ret =
LY_EMEM, cleanup);
900 dup_val->original = strdup(
"");
901 LY_CHECK_ERR_GOTO(!dup_val->original, LOGMEM(ctx); ret =
LY_EMEM, cleanup);
905 dup_val->format = orig_val->
format;
906 dup_val->ctx_node = orig_val->
ctx_node;
907 dup_val->hints = orig_val->
hints;
909 LY_CHECK_GOTO(ret, cleanup);
913 lyplg_type_free_union(ctx, dup);
948 .name = LY_TYPE_UNION_STR,
950 .plugin.id =
"ly2 union",
952 .plugin.store = lyplg_type_store_union,
953 .plugin.validate_value = NULL,
954 .plugin.validate_tree = lyplg_type_validate_tree_union,
955 .plugin.compare = lyplg_type_compare_union,
956 .plugin.sort = lyplg_type_sort_union,
957 .plugin.print = lyplg_type_print_union,
958 .plugin.duplicate = lyplg_type_dup_union,
959 .plugin.free = lyplg_type_free_union,
#define LYA_PRI_COUNT_T
Printing format specifier macro for LYA_COUNT_T values.
#define LYA_COUNT(ARRAY)
Get the number of records in the ARRAY.
#define LYA_FOR(ARRAY, INDEX)
Helper macro to go through sized-arrays with a numeric iterator.
#define LYA_COUNT_T
Type (i.e. size) of the sized array's size counter.
LIBYANG_API_DECL LY_ERR lydict_dup(const struct ly_ctx *ctx, const char *value, const char **str_p)
Duplicate string in dictionary. Only a reference counter is incremented.
LIBYANG_API_DECL LY_ERR lydict_insert(const struct ly_ctx *ctx, const char *value, size_t len, const char **str_p)
Insert string into dictionary. If the string is already present, only a reference counter is incremen...
LIBYANG_API_DECL LY_ERR lydict_remove(const struct ly_ctx *ctx, const char *value)
Remove specified string from the dictionary. It decrement reference counter for the string and if it ...
LY_ERR
libyang's error codes returned by the libyang functions.
Libyang full error structure.
LIBYANG_API_DECL uint32_t * ly_temp_log_options(uint32_t *opts)
Set temporary thread-safe (thread-specific) logger options overwriting those set by ly_log_options().
lyplg_type_store_clb store
lyplg_type_dup_clb duplicate
lyplg_type_validate_tree_clb validate_tree
#define LYPLG_TYPE_VAL_INLINE_PREPARE(storage, type_val)
Prepare value memory for storing a specific type value, may be allocated dynamically.
LIBYANG_API_DECL void ly_err_free(void *ptr)
Destructor for the error records created with ly_err_new().
LIBYANG_API_DEF LY_ERR lyplg_type_store_union_idx(const struct ly_ctx *ctx, const struct lysc_type *type, uint32_t type_idx, const void *value, uint64_t value_size_bits, uint32_t options, LY_VALUE_FORMAT format, void *prefix_data, uint32_t hints, const struct lysc_node *ctx_node, struct lyd_value *storage, struct ly_err_item **err)
Store a union value with a specific member type index, keeping that member resolved (pinned),...
#define LYPLG_TYPE_VAL_INLINE_DESTROY(type_val)
Destroy a prepared value.
LIBYANG_API_DECL LY_ERR lyplg_type_prefix_data_new(const struct ly_ctx *ctx, const void *value, uint32_t value_size, LY_VALUE_FORMAT format, const void *prefix_data, LY_VALUE_FORMAT *format_p, void **prefix_data_p)
Store used prefixes in a string into an internal libyang structure used in lyd_value.
LIBYANG_API_DECL LY_ERR ly_err_new(struct ly_err_item **err, LY_ERR ecode, LY_VECODE vecode, char *data_path, char *apptag, const char *err_format,...) _FORMAT_PRINTF(6
Create and fill an error structure.
LIBYANG_API_DECL LY_ERR lyplg_type_prefix_data_dup(const struct ly_ctx *ctx, LY_VALUE_FORMAT format, const void *orig, void **dup)
Duplicate prefix data.
#define LYPLG_BITS2BYTES(bits)
Convert bits to bytes.
LIBYANG_API_DECL LY_ERR LIBYANG_API_DECL LY_ERR ly_err_new_no_mem(struct ly_err_item **err)
Create and fill an error structure with a no-memory error.
LIBYANG_API_DECL void lyplg_type_prefix_data_free(LY_VALUE_FORMAT format, void *prefix_data)
Free internal prefix data.
Hold type-specific functions for various operations with the data values.
LIBYANG_API_DECL void lyplg_type_lyb_size_variable_bits(const struct lysc_type *type, enum lyplg_lyb_size_type *size_type, uint64_t *fixed_size_bits)
Implementation of lyplg_type_lyb_size_clb for a type with variable length in bits.
#define LYPLG_TYPE_STORE_DYNAMIC
#define LYPLG_TYPE_STORE_IMPLEMENT
#define LYPLG_TYPE_STORE_ONLY
struct lys_module * module
struct lysc_type ** types
LIBYANG_API_DECL const char * lyxp_get_expr(const struct lyxp_expr *path)
Getter for original XPath expression from a parsed expression.
uint8_t ly_bool
Type to indicate boolean value.
API for (user) types plugins.
const struct lysc_type * realtype
#define LYD_VALUE_GET(value, type_val)
Get the value in format specific to the type.
const struct lysc_node * ctx_node
Generic structure for a data node.
YANG data representation.
Special lyd_value structure for built-in union values.
#define LYPLG_UNION_TYPE_IDX_SIZE
Size in bytes of the used type index in the LYB Binary Format.
const struct lyplg_type_record plugins_union[]
Plugin information for union type implementation.
LY_VALUE_FORMAT
All kinds of supported value formats and prefix mappings to modules.