30#include "plugins_internal.h"
44static void lyplg_type_free_union(
const struct ly_ctx *ctx,
struct lyd_value *value);
49#define LYPLG_UNION_TYPE_IDX_SIZE 1
62union_subvalue_assignment(
const void *value, uint64_t value_size_bits,
void **original, uint64_t *orig_size_bits,
69 *original = (
void *)value;
70 *options &= ~LYPLG_TYPE_STORE_DYNAMIC;
71 }
else if (value_size_bits) {
74 LY_CHECK_ERR_RET(!*original, ret =
LY_EMEM, ret);
78 *original = strdup(
"");
79 LY_CHECK_ERR_RET(!*original, ret =
LY_EMEM, ret);
81 *orig_size_bits = value_size_bits;
96lyb_union_validate(
const void *lyb_data, uint64_t lyb_data_size_bits,
const struct lysc_type_union *type_u,
99 uint32_t type_idx = 0;
109 type_idx = le32toh(type_idx);
112 "Invalid LYB union type index %" PRIu32
" (type count %" LYA_PRI_COUNT_T ").",
130lyb_parse_union(
const void *lyb_data, uint64_t lyb_data_size_bits, uint32_t *type_idx,
const void **lyb_value,
131 uint64_t *lyb_value_size_bits)
135 assert(lyb_data && !(lyb_value && !lyb_value_size_bits));
144 if (lyb_value && lyb_value_size_bits && lyb_data_size_bits) {
147 *lyb_value_size_bits = 0;
168union_update_lref_err(
struct ly_err_item *err,
const struct lysc_type *type,
const void *value, uint64_t value_size_bits)
183 err->
apptag = strdup(
"instance-required");
186 valstr = strndup((
const char *)value, value_size_bits / 8);
187 LY_CHECK_ERR_RET(!valstr, LOGMEM(NULL),
LY_EMEM);
193 LY_CHECK_ERR_RET(r == -1, LOGMEM(NULL),
LY_EMEM);
216 struct lys_glob_unres *unres,
struct ly_err_item **err)
220 const void *value = NULL;
224 uint64_t value_size_bits = 0;
225 uint32_t opts = 0, ti;
232 if (ti != type_idx) {
240 memset(&subvalue->
value, 0,
sizeof subvalue->
value);
243 union_update_lref_err(*err, type_u->
types[ti], value, value_size_bits);
250 assert(!(value_size_bits % 8));
254 value = strndup(value, value_size_bits / 8);
262 format = subvalue->
format;
268 format = subvalue->
format;
276 type_plg = LYSC_GET_TYPE_PLG(type->
plugin_ref);
278 rc = type_plg->
store(ctx, type, value, value_size_bits, opts, format, prefix_data, subvalue->
hints,
282 memset(&subvalue->
value, 0,
sizeof subvalue->
value);
285 union_update_lref_err(*err, type, value, value_size_bits);
324 uint32_t *type_idx,
struct lys_glob_unres *unres,
struct ly_err_item **err)
329 uint32_t *prev_lo, temp_lo = 0;
330 char *
msg = NULL, *err_app_tag = NULL;
346 ret = union_store_type(ctx, type_u, u, subvalue, options,
validate_tree, ctx_node, tree, unres, &e);
357 msg_len = asprintf(&msg,
"Invalid LYB union value - no matching subtype found:\n");
359 msg_len = asprintf(&msg,
"Invalid union value \"%.*s\" - no matching subtype found:\n",
363 LY_CHECK_ERR_GOTO(!errs, ret =
LY_EMEM, cleanup);
374 if (errs[u]->apptag) {
376 err_app_tag = strdup(errs[u]->apptag);
377 LY_CHECK_ERR_GOTO(!err_app_tag, ret =
LY_EMEM, cleanup);
379 }
else if (strcmp(errs[u]->apptag, err_app_tag)) {
386 msg = ly_realloc(msg, msg_len + 4 + strlen(type_plg->
id) + 2 + strlen(errs[u]->msg) + 2);
387 LY_CHECK_ERR_GOTO(!msg, ret =
LY_EMEM, cleanup);
388 msg_len += sprintf(msg + msg_len,
" %s: %s\n", type_plg->
id, errs[u]->msg);
391 if (!use_err_app_tag) {
397 }
else if (type_idx) {
427lyb_fill_subvalue(
const struct ly_ctx *ctx,
struct lysc_type_union *type_u,
const void *lyb_data, uint64_t lyb_data_size_bits,
428 void *prefix_data,
struct lyd_value_union *subvalue, uint32_t *options,
struct lys_glob_unres *unres,
432 uint64_t lyb_value_size_bits = 0;
434 const void *lyb_value = NULL;
436 ret = lyb_union_validate(lyb_data, lyb_data_size_bits, type_u, err);
440 lyb_parse_union(lyb_data, lyb_data_size_bits, &type_idx, &lyb_value, &lyb_value_size_bits);
443 ret = union_subvalue_assignment(lyb_data, lyb_data_size_bits, &subvalue->
original, &subvalue->
orig_size_bits, options);
458 ret = union_store_type(ctx, type_u, type_idx, subvalue, *options, 0, NULL, NULL, unres, err);
464lyplg_type_store_union(
const struct ly_ctx *ctx,
const struct lysc_type *type,
const void *value, uint64_t value_size_bits,
475 memset(storage, 0,
sizeof *storage);
477 LY_CHECK_ERR_GOTO(!subvalue, ret =
LY_EMEM, cleanup);
483 ret = lyb_fill_subvalue(ctx, type_u,
value, value_size_bits,
prefix_data, subvalue, &options, unres, err);
488 LY_CHECK_GOTO(ret, cleanup);
493 LY_CHECK_GOTO(ret, cleanup);
496 ret = union_find_type(ctx, type_u, subvalue, options & ~
LYPLG_TYPE_STORE_ONLY, 0, NULL, NULL, NULL, unres, err);
501 ret = union_find_type(ctx, type_u, subvalue, options, 0, NULL, NULL, NULL, unres, err);
508 LY_CHECK_ERR_GOTO(r, ret = r, cleanup);
516 lyplg_type_free_union(ctx, storage);
539 LY_CHECK_RET(subvalue_type_plg->
duplicate(ctx, &subvalue->
value, &orig));
540 subvalue_type_plg->
free(ctx, &subvalue->
value);
544 lyb_parse_union(subvalue->
original, 0, &type_idx, NULL, NULL);
546 if (union_store_type(ctx, type_u, type_idx, subvalue, 0, 1, ctx_node, tree, NULL, err)) {
557 rc = union_find_type(ctx, type_u, subvalue, 0, 1, ctx_node, tree, NULL, NULL, err);
560 subvalue->
value = orig;
581 &val1->subvalue->value, &val2->subvalue->value);
593 &val1->subvalue->value, &val2->subvalue->value);
606 if (type == val1->subvalue->value.
realtype) {
609 }
else if (type == val2->subvalue->value.
realtype) {
633 void *prefix_data, uint64_t *value_size_bits)
638 uint64_t pval_size_bits;
639 uint32_t num = 0, type_idx = 0;
647 ctx = subvalue->
ctx_node->module->ctx;
654 LY_CHECK_RET(subvalue_type_plg->
duplicate(ctx, &subvalue->
value, &orig), NULL);
655 subvalue_type_plg->
free(ctx, &subvalue->
value);
658 r = union_find_type(ctx, type_u, subvalue, 0, 0, NULL, NULL, &type_idx, NULL, &err);
662 r = union_find_type(ctx, type_u, subvalue,
LYPLG_TYPE_STORE_ONLY, 0, NULL, NULL, &type_idx, NULL, &err);
669 prefix_data, &dynamic, &pval_size_bits);
670 LY_CHECK_ERR_RET(!pval, subvalue->
value = orig, NULL);
675 LY_CHECK_GOTO(!ret, cleanup);
677 num = htole32(type_idx);
688 subvalue->
value = orig;
694 void *prefix_data,
ly_bool *dynamic, uint64_t *value_size_bits)
699 uint64_t lyb_data_size_bits = 0;
704 if (value_size_bits) {
711 ret = lyb_union_print(ctx, type_u, subvalue, prefix_data, &lyb_data_size_bits);
712 if (value_size_bits) {
713 *value_size_bits = lyb_data_size_bits;
720 format, prefix_data, dynamic, value_size_bits);
736 memset(dup, 0,
sizeof *dup);
740 LY_CHECK_GOTO(ret, cleanup);
742 dup_val = calloc(1,
sizeof *dup_val);
743 LY_CHECK_ERR_GOTO(!dup_val, LOGMEM(ctx); ret =
LY_EMEM, cleanup);
744 dup->subvalue = dup_val;
747 LY_CHECK_GOTO(ret, cleanup);
751 LY_CHECK_ERR_GOTO(!dup_val->original, LOGMEM(ctx); ret =
LY_EMEM, cleanup);
754 dup_val->original = strdup(
"");
755 LY_CHECK_ERR_GOTO(!dup_val->original, LOGMEM(ctx); ret =
LY_EMEM, cleanup);
759 dup_val->format = orig_val->
format;
760 dup_val->ctx_node = orig_val->
ctx_node;
761 dup_val->hints = orig_val->
hints;
763 LY_CHECK_GOTO(ret, cleanup);
767 lyplg_type_free_union(ctx, dup);
802 .name = LY_TYPE_UNION_STR,
804 .plugin.id =
"ly2 union",
806 .plugin.store = lyplg_type_store_union,
807 .plugin.validate_value = NULL,
808 .plugin.validate_tree = lyplg_type_validate_tree_union,
809 .plugin.compare = lyplg_type_compare_union,
810 .plugin.sort = lyplg_type_sort_union,
811 .plugin.print = lyplg_type_print_union,
812 .plugin.duplicate = lyplg_type_dup_union,
813 .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_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().
const char *const char * revision
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 LY_ERR LIBYANG_API_DECL void ly_err_free(void *ptr)
Destructor for the error records created with ly_err_new().
#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 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 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_ONLY
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.