29 #include "ly_common.h"
31 #include "plugins_internal.h"
45 static void lyplg_type_free_union(
const struct ly_ctx *ctx,
struct lyd_value *value);
50 #define LYPLG_UNION_TYPE_IDX_SIZE 1
63 union_subvalue_assignment(
const void *value, uint32_t value_size_bits,
void **original, uint32_t *orig_size_bits,
70 *original = (
void *)value;
71 *options &= ~LYPLG_TYPE_STORE_DYNAMIC;
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;
97 lyb_union_validate(
const void *lyb_data, uint32_t lyb_data_size_bits,
const struct lysc_type_union *type_u,
100 uint32_t type_idx = 0;
110 type_idx = le32toh(type_idx);
131 lyb_parse_union(
const void *lyb_data, uint32_t lyb_data_size_bits, uint32_t *type_idx,
const void **lyb_value,
132 uint32_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;
152 *lyb_value = (
char *)lyb_data + LYPLG_UNION_TYPE_IDX_SIZE;
169 union_update_lref_err(
struct ly_err_item *err,
const struct lysc_type *type,
const void *value, uint32_t value_size_bits)
184 err->
apptag = strdup(
"instance-required");
187 valstr = strndup((
const char *)value, value_size_bits / 8);
222 const void *value = NULL;
226 uint32_t value_size_bits, opts = 0, ti;
233 if (ti != type_idx) {
238 &subvalue->
value, unres, err);
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,
286 union_update_lref_err(*err, type, value, value_size_bits);
292 rc = type_plg->
validate_tree(ctx, type, ctx_node, tree, top_ext, &subvalue->
value, err);
331 uint32_t *prev_lo, temp_lo = 0;
332 char *
msg = NULL, *err_app_tag = NULL;
348 ret = union_store_type(ctx, type_u, u, subvalue, options, validate_tree, ctx_node, tree, top_ext, unres, &e);
359 msg_len = asprintf(&msg,
"Invalid LYB union value - no matching subtype found:\n");
361 msg_len = asprintf(&msg,
"Invalid union value \"%.*s\" - no matching subtype found:\n",
365 LY_CHECK_ERR_GOTO(!errs, ret =
LY_EMEM, cleanup);
376 if (errs[u]->apptag) {
378 err_app_tag = strdup(errs[u]->apptag);
379 LY_CHECK_ERR_GOTO(!err_app_tag, ret =
LY_EMEM, cleanup);
381 }
else if (strcmp(errs[u]->apptag, err_app_tag)) {
388 msg =
ly_realloc(msg, msg_len + 4 + strlen(type_plg->
id) + 2 + strlen(errs[u]->msg) + 2);
389 LY_CHECK_ERR_GOTO(!msg, ret =
LY_EMEM, cleanup);
390 msg_len += sprintf(msg + msg_len,
" %s: %s\n", type_plg->
id, errs[u]->
msg);
393 if (!use_err_app_tag) {
398 }
else if (type_idx) {
427 lyb_fill_subvalue(
const struct ly_ctx *ctx,
struct lysc_type_union *type_u,
const void *lyb_data, uint32_t lyb_data_size_bits,
428 void *prefix_data,
struct lyd_value_union *subvalue, uint32_t *options,
struct lys_glob_unres *unres,
432 uint32_t lyb_value_size_bits = 0, type_idx;
433 const void *lyb_value = NULL;
435 ret = lyb_union_validate(lyb_data, lyb_data_size_bits, type_u, err);
439 lyb_parse_union(lyb_data, lyb_data_size_bits, &type_idx, &lyb_value, &lyb_value_size_bits);
442 ret = union_subvalue_assignment(lyb_data, lyb_data_size_bits, &subvalue->
original, &subvalue->
orig_size_bits, options);
457 ret = union_store_type(ctx, type_u, type_idx, subvalue, *options, 0, NULL, NULL, NULL, unres, err);
463 lyplg_type_store_union(
const struct ly_ctx *ctx,
const struct lysc_type *type,
const void *value, uint32_t value_size_bits,
475 memset(storage, 0,
sizeof *storage);
477 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);
488 options &= ~LYPLG_TYPE_STORE_ONLY;
491 ret = union_subvalue_assignment(value, value_size_bits, &subvalue->
original, &subvalue->
orig_size_bits, &options);
492 LY_CHECK_GOTO(ret, cleanup);
497 LY_CHECK_GOTO(ret, cleanup);
500 ret = union_find_type(ctx, type_u, subvalue, options, 0, NULL, NULL, NULL, NULL, unres, err);
506 LY_CHECK_ERR_GOTO(r, ret = r, cleanup);
514 lyplg_type_free_union(ctx, storage);
520 lyplg_type_validate_tree_union(
const struct ly_ctx *ctx,
const struct lysc_type *type,
const struct lyd_node *ctx_node,
538 LY_CHECK_RET(subvalue_type_plg->
duplicate(ctx, &subvalue->
value, &orig));
539 subvalue_type_plg->
free(ctx, &subvalue->
value);
543 lyb_parse_union(subvalue->
original, 0, &type_idx, NULL, NULL);
545 if (union_store_type(ctx, type_u, type_idx, subvalue, 0, 1, ctx_node, tree, top_ext, NULL, err)) {
556 rc = union_find_type(ctx, type_u, subvalue, 0, 1, ctx_node, tree, top_ext, NULL, NULL, err);
559 subvalue->
value = orig;
580 &val1->subvalue->value, &val2->subvalue->value);
592 &val1->subvalue->value, &val2->subvalue->value);
605 if (type == val1->subvalue->value.
realtype) {
608 }
else if (type == val2->subvalue->value.
realtype) {
632 void *prefix_data, uint32_t *value_size_bits)
637 uint32_t num = 0, pval_size_bits, type_idx = 0;
647 r = union_find_type(ctx, type_u, subvalue, 0, 0, NULL, NULL, NULL, &type_idx, NULL, &err);
653 prefix_data, &dynamic, &pval_size_bits);
654 LY_CHECK_RET(!pval, NULL);
659 LY_CHECK_RET(!ret, NULL);
661 num = htole32(type_idx);
674 void *prefix_data,
ly_bool *dynamic, uint32_t *value_size_bits)
679 uint32_t lyb_data_size_bits = 0;
684 if (value_size_bits) {
691 ret = lyb_union_print(ctx, type_u, subvalue, prefix_data, &lyb_data_size_bits);
692 if (value_size_bits) {
693 *value_size_bits = lyb_data_size_bits;
700 format, prefix_data, dynamic, value_size_bits);
716 memset(dup, 0,
sizeof *dup);
720 LY_CHECK_GOTO(ret, cleanup);
722 dup_val = calloc(1,
sizeof *dup_val);
723 LY_CHECK_ERR_GOTO(!dup_val,
LOGMEM(ctx); ret =
LY_EMEM, cleanup);
724 dup->subvalue = dup_val;
727 LY_CHECK_GOTO(ret, cleanup);
731 LY_CHECK_ERR_GOTO(!dup_val->original,
LOGMEM(ctx); ret =
LY_EMEM, cleanup);
734 dup_val->original = strdup(
"");
735 LY_CHECK_ERR_GOTO(!dup_val->original,
LOGMEM(ctx); ret =
LY_EMEM, cleanup);
739 dup_val->format = orig_val->
format;
740 dup_val->ctx_node = orig_val->
ctx_node;
741 dup_val->hints = orig_val->
hints;
743 LY_CHECK_GOTO(ret, cleanup);
747 lyplg_type_free_union(ctx, dup);
753 lyplg_type_free_union(
const struct ly_ctx *ctx,
struct lyd_value *value)
782 .name = LY_TYPE_UNION_STR,
784 .plugin.id =
"ly2 union",
786 .plugin.store = lyplg_type_store_union,
787 .plugin.validate_value = NULL,
788 .plugin.validate_tree = lyplg_type_validate_tree_union,
789 .plugin.compare = lyplg_type_compare_union,
790 .plugin.sort = lyplg_type_sort_union,
791 .plugin.print = lyplg_type_print_union,
792 .plugin.duplicate = lyplg_type_dup_union,
793 .plugin.free = lyplg_type_free_union,
LIBYANG_API_DECL void lyplg_type_lyb_size_variable_bits(const struct lysc_type *type, enum lyplg_lyb_size_type *size_type, uint32_t *fixed_size_bits)
Implementation of lyplg_type_lyb_size_clb for a type with variable length in bits.
struct lysc_type * realtype
#define LY_PRI_ARRAY_COUNT_TYPE
Printing format specifier macro for LY_ARRAY_SIZE_TYPE values.
memset(value->fixed_mem, 0, LYD_VALUE_FIXED_MEM_SIZE)
Hold type-specific functions for various operations with the data values.
Generic structure for a data node.
YANG extension compiled instance.
LIBYANG_API_DECL uint32_t * ly_temp_log_options(uint32_t *opts)
Set temporary thread-safe logger options overwriting those set by ly_log_options().
LY_ERR
libyang's error codes returned by the libyang functions.
uint8_t ly_bool
Type to indicate boolean value.
#define LYPLG_UNION_TYPE_IDX_SIZE
Size in bytes of the used type index in the LYB Binary Format.
#define LYPLG_TYPE_STORE_DYNAMIC
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.
struct lysc_node * ctx_node
struct lysc_type ** types
LYPLG_TYPE_VAL_INLINE_DESTROY(val)
The main libyang public header.
lyplg_type_validate_tree_clb validate_tree
YANG data representation.
lyplg_type_store_clb store
Libyang full error structure.
#define LYD_VALUE_GET(value, type_val)
Get the value in format specific to the type.
LIBYANG_API_DECL LY_ERR LIBYANG_API_DECL void ly_err_free(void *ptr)
Destructor for the error records created with ly_err_new().
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.
struct lyplg_type_record plugins_union[]
Plugin information for union type implementation.
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 ...
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...
lyplg_type_dup_clb duplicate
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 LY_ARRAY_COUNT(ARRAY)
Get the number of records in the ARRAY.
LIBYANG_API_DECL void lyplg_type_prefix_data_free(LY_VALUE_FORMAT format, void *prefix_data)
Free internal prefix data.
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 LY_ARRAY_FOR(ARRAY,...)
Sized-array iterator (for-loop).
#define LY_ARRAY_COUNT_TYPE
Type (i.e. size) of the sized array's size counter.
struct lys_module * module
if((v1->size!=v2->size)||memcmp(v1->data, v2->data, v1->size))
LY_VALUE_FORMAT
All kinds of supported value formats and prefix mappings to modules.
LIBYANG_API_DECL const char * lyxp_get_expr(const struct lyxp_expr *path)
Getter for original XPath expression from a parsed expression.
#define LYPLG_TYPE_VAL_INLINE_PREPARE(storage, type_val)
Prepare value memory for storing a specific type value, may be allocated dynamically.
Special lyd_value structure for built-in union values.
API for (user) types plugins.
#define LYPLG_BITS2BYTES(bits)
Convert bits to bytes.
struct lysc_ext_instance * top_ext
#define LYPLG_TYPE_STORE_ONLY
assert(!value->_canonical)