31#include "plugins_internal.h"
45static void lyplg_type_free_union(
const struct ly_ctx *ctx,
struct lyd_value *value);
50#define LYPLG_UNION_TYPE_IDX_SIZE 1
63union_subvalue_assignment(
const void *value, uint64_t value_size_bits,
void **original, uint64_t *orig_size_bits,
70 *original = (
void *)value;
72 }
else if (value_size_bits) {
75 LY_CHECK_ERR_RET(!*original, ret =
LY_EMEM, ret);
79 *original = strdup(
"");
80 LY_CHECK_ERR_RET(!*original, ret =
LY_EMEM, ret);
82 *orig_size_bits = value_size_bits;
97lyb_union_validate(
const void *lyb_data, uint64_t lyb_data_size_bits,
const struct lysc_type_union *type_u,
100 uint32_t type_idx = 0;
110 type_idx = le32toh(type_idx);
131lyb_parse_union(
const void *lyb_data, uint64_t lyb_data_size_bits, uint32_t *type_idx,
const void **lyb_value,
132 uint64_t *lyb_value_size_bits)
136 assert(lyb_data && !(lyb_value && !lyb_value_size_bits));
145 if (lyb_value && lyb_value_size_bits && lyb_data_size_bits) {
148 *lyb_value_size_bits = 0;
169union_update_lref_err(
struct ly_err_item *err,
const struct lysc_type *type,
const void *value, uint64_t value_size_bits)
184 err->
apptag = strdup(
"instance-required");
187 valstr = strndup((
const char *)value, value_size_bits / 8);
217 struct lys_glob_unres *unres,
struct ly_err_item **err)
221 const void *value = NULL;
225 uint64_t value_size_bits = 0;
226 uint32_t opts = 0, ti;
233 if (ti != type_idx) {
241 memset(&subvalue->
value, 0,
sizeof subvalue->
value);
244 union_update_lref_err(*err, type_u->
types[ti], value, value_size_bits);
251 assert(!(value_size_bits % 8));
255 value = strndup(value, value_size_bits / 8);
263 format = subvalue->
format;
269 format = subvalue->
format;
277 type_plg = LYSC_GET_TYPE_PLG(type->
plugin_ref);
279 rc = type_plg->
store(ctx, type, value, value_size_bits, opts, format, prefix_data, subvalue->
hints,
283 memset(&subvalue->
value, 0,
sizeof subvalue->
value);
286 union_update_lref_err(*err, type, value, value_size_bits);
325 uint32_t *type_idx,
struct lys_glob_unres *unres,
struct ly_err_item **err)
330 uint32_t *prev_lo, temp_lo = 0;
331 char *
msg = NULL, *err_app_tag = NULL;
347 ret = union_store_type(ctx, type_u, u, subvalue, options,
validate_tree, ctx_node, tree, unres, &e);
358 msg_len = asprintf(&msg,
"Invalid LYB union value - no matching subtype found:\n");
360 msg_len = asprintf(&msg,
"Invalid union value \"%.*s\" - no matching subtype found:\n",
364 LY_CHECK_ERR_GOTO(!errs, ret =
LY_EMEM, cleanup);
375 if (errs[u]->apptag) {
377 err_app_tag = strdup(errs[u]->apptag);
378 LY_CHECK_ERR_GOTO(!err_app_tag, ret =
LY_EMEM, cleanup);
380 }
else if (strcmp(errs[u]->apptag, err_app_tag)) {
387 msg =
ly_realloc(msg, msg_len + 4 + strlen(type_plg->
id) + 2 + strlen(errs[u]->msg) + 2);
388 LY_CHECK_ERR_GOTO(!msg, ret =
LY_EMEM, cleanup);
389 msg_len += sprintf(msg + msg_len,
" %s: %s\n", type_plg->
id, errs[u]->msg);
392 if (!use_err_app_tag) {
398 }
else if (type_idx) {
428lyb_fill_subvalue(
const struct ly_ctx *ctx,
struct lysc_type_union *type_u,
const void *lyb_data, uint64_t lyb_data_size_bits,
429 void *prefix_data,
struct lyd_value_union *subvalue, uint32_t *options,
struct lys_glob_unres *unres,
433 uint64_t lyb_value_size_bits = 0;
435 const void *lyb_value = NULL;
437 ret = lyb_union_validate(lyb_data, lyb_data_size_bits, type_u, err);
441 lyb_parse_union(lyb_data, lyb_data_size_bits, &type_idx, &lyb_value, &lyb_value_size_bits);
444 ret = union_subvalue_assignment(lyb_data, lyb_data_size_bits, &subvalue->
original, &subvalue->
orig_size_bits, options);
459 ret = union_store_type(ctx, type_u, type_idx, subvalue, *options, 0, NULL, NULL, unres, err);
465lyplg_type_store_union(
const struct ly_ctx *ctx,
const struct lysc_type *type,
const void *value, uint64_t value_size_bits,
476 memset(storage, 0,
sizeof *storage);
478 LY_CHECK_ERR_GOTO(!subvalue, ret =
LY_EMEM, cleanup);
484 ret = lyb_fill_subvalue(ctx, type_u,
value, value_size_bits,
prefix_data, subvalue, &options, unres, err);
489 LY_CHECK_GOTO(ret, cleanup);
494 LY_CHECK_GOTO(ret, cleanup);
497 ret = union_find_type(ctx, type_u, subvalue, options & ~
LYPLG_TYPE_STORE_ONLY, 0, NULL, NULL, NULL, unres, err);
502 ret = union_find_type(ctx, type_u, subvalue, options, 0, NULL, NULL, NULL, unres, err);
509 LY_CHECK_ERR_GOTO(r, ret = r, cleanup);
517 lyplg_type_free_union(ctx, storage);
540 LY_CHECK_RET(subvalue_type_plg->
duplicate(ctx, &subvalue->
value, &orig));
541 subvalue_type_plg->
free(ctx, &subvalue->
value);
545 lyb_parse_union(subvalue->
original, 0, &type_idx, NULL, NULL);
547 if (union_store_type(ctx, type_u, type_idx, subvalue, 0, 1, ctx_node, tree, NULL, err)) {
558 rc = union_find_type(ctx, type_u, subvalue, 0, 1, ctx_node, tree, NULL, NULL, err);
561 subvalue->
value = orig;
582 &val1->subvalue->value, &val2->subvalue->value);
594 &val1->subvalue->value, &val2->subvalue->value);
607 if (type == val1->subvalue->value.
realtype) {
610 }
else if (type == val2->subvalue->value.
realtype) {
634 void *prefix_data, uint64_t *value_size_bits)
639 uint64_t pval_size_bits;
640 uint32_t num = 0, type_idx = 0;
650 r = union_find_type(ctx, type_u, subvalue, 0, 0, NULL, NULL, &type_idx, NULL, &
err);
656 prefix_data, &dynamic, &pval_size_bits);
657 LY_CHECK_RET(!pval, NULL);
662 LY_CHECK_RET(!ret, NULL);
664 num = htole32(type_idx);
677 void *prefix_data,
ly_bool *dynamic, uint64_t *value_size_bits)
682 uint64_t lyb_data_size_bits = 0;
687 if (value_size_bits) {
694 ret = lyb_union_print(ctx, type_u, subvalue, prefix_data, &lyb_data_size_bits);
695 if (value_size_bits) {
696 *value_size_bits = lyb_data_size_bits;
703 format, prefix_data, dynamic, value_size_bits);
719 memset(dup, 0,
sizeof *dup);
723 LY_CHECK_GOTO(ret, cleanup);
725 dup_val = calloc(1,
sizeof *dup_val);
726 LY_CHECK_ERR_GOTO(!dup_val,
LOGMEM(ctx); ret =
LY_EMEM, cleanup);
727 dup->subvalue = dup_val;
730 LY_CHECK_GOTO(ret, cleanup);
734 LY_CHECK_ERR_GOTO(!dup_val->original,
LOGMEM(ctx); ret =
LY_EMEM, cleanup);
737 dup_val->original = strdup(
"");
738 LY_CHECK_ERR_GOTO(!dup_val->original,
LOGMEM(ctx); ret =
LY_EMEM, cleanup);
742 dup_val->format = orig_val->
format;
743 dup_val->ctx_node = orig_val->
ctx_node;
744 dup_val->hints = orig_val->
hints;
746 LY_CHECK_GOTO(ret, cleanup);
750 lyplg_type_free_union(ctx, dup);
785 .name = LY_TYPE_UNION_STR,
787 .plugin.id =
"ly2 union",
789 .plugin.store = lyplg_type_store_union,
790 .plugin.validate_value = NULL,
791 .plugin.validate_tree = lyplg_type_validate_tree_union,
792 .plugin.compare = lyplg_type_compare_union,
793 .plugin.sort = lyplg_type_sort_union,
794 .plugin.print = lyplg_type_print_union,
795 .plugin.duplicate = lyplg_type_dup_union,
796 .plugin.free = lyplg_type_free_union,
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 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 lys_module * module
struct lysc_type * realtype
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.
#define LY_ARRAY_COUNT(ARRAY)
Get the number of records in the ARRAY.
#define LY_ARRAY_FOR(ARRAY,...)
Sized-array iterator (for-loop).
LY_VALUE_FORMAT
All kinds of supported value formats and prefix mappings to modules.
#define LY_PRI_ARRAY_COUNT_TYPE
Printing format specifier macro for LY_ARRAY_SIZE_TYPE values.
#define LY_ARRAY_COUNT_TYPE
Type (i.e. size) of the sized array's size counter.
The main libyang public header.
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.
void * ly_realloc(void *ptr, size_t size)
Wrapper for realloc() call. The only difference is that if it fails to allocate the requested memory,...
#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.