28 #include "ly_common.h"
29 #include "plugins_internal.h"
46 #define TYPE_IDX_SIZE 4
59 union_subvalue_assignment(
const void *value,
size_t value_len,
void **original,
size_t *orig_len, uint32_t *options)
65 *original = (
void *)value;
66 *options &= ~LYPLG_TYPE_STORE_DYNAMIC;
67 }
else if (value_len) {
69 *original = calloc(1, value_len);
70 LY_CHECK_ERR_RET(!*original, ret =
LY_EMEM, ret);
71 memcpy(*original, value, value_len);
74 *original = strdup(
"");
75 LY_CHECK_ERR_RET(!*original, ret =
LY_EMEM, ret);
77 *orig_len = value_len;
95 uint64_t type_idx = 0;
106 type_idx = le64toh(type_idx);
128 lyb_parse_union(
const void *lyb_data,
size_t lyb_data_len, uint32_t *type_idx,
const void **lyb_value,
size_t *lyb_value_len)
132 assert(lyb_data && !(lyb_value && !lyb_value_len));
141 if (lyb_value && lyb_value_len && lyb_data_len) {
148 *lyb_value = (
char *)lyb_data + TYPE_IDX_SIZE;
171 struct lys_glob_unres *unres,
struct ly_err_item **err)
175 const void *value = NULL;
176 size_t value_len = 0;
180 uint32_t opts = 0, ti;
185 lyb_parse_union(subvalue->
original, subvalue->
orig_len, &ti, &value, &value_len);
186 if (ti != type_idx) {
201 value = strndup(value, value_len);
209 format = subvalue->
format;
215 format = subvalue->
format;
226 rc = type->
plugin->
store(ctx, type, value, value_len, opts, format, prefix_data, subvalue->
hints,
264 uint32_t *type_idx,
struct lys_glob_unres *unres,
struct ly_err_item **err)
269 uint32_t *prev_lo, temp_lo = 0;
284 ret = union_store_type(ctx, type_u, u, subvalue, options, resolve, ctx_node, tree, unres, &e);
295 msg_len = asprintf(&msg,
"Invalid LYB union value - no matching subtype found:\n");
297 msg_len = asprintf(&msg,
"Invalid union value \"%.*s\" - no matching subtype found:\n",
301 LY_CHECK_ERR_GOTO(!errs, ret =
LY_EMEM, cleanup);
310 LY_CHECK_ERR_GOTO(!msg, ret =
LY_EMEM, cleanup);
311 msg_len += sprintf(msg + msg_len,
" %s: %s\n", type_u->
types[u]->
plugin->
id, errs[u]->
msg);
315 }
else if (type_idx) {
344 lyb_fill_subvalue(
const struct ly_ctx *ctx,
struct lysc_type_union *type_u,
const void *lyb_data,
size_t lyb_data_len,
345 void *prefix_data,
struct lyd_value_union *subvalue, uint32_t *options,
struct lys_glob_unres *unres,
350 const void *lyb_value = NULL;
351 size_t lyb_value_len = 0;
353 ret = lyb_union_validate(lyb_data, lyb_data_len, type_u, err);
357 lyb_parse_union(lyb_data, lyb_data_len, &type_idx, &lyb_value, &lyb_value_len);
361 ret = union_subvalue_assignment(lyb_data, lyb_data_len, &subvalue->
original, &subvalue->
orig_len, options);
376 ret = union_store_type(ctx, type_u, type_idx, subvalue, *options, 0, NULL, NULL, unres, err);
393 memset(storage, 0,
sizeof *storage);
395 LY_CHECK_ERR_GOTO(!subvalue, ret =
LY_EMEM, cleanup);
401 ret = lyb_fill_subvalue(ctx, type_u, value, value_len, prefix_data, subvalue, &options, unres, err);
405 options &= ~LYPLG_TYPE_STORE_ONLY;
408 ret = union_subvalue_assignment(value, value_len, &subvalue->
original, &subvalue->
orig_len, &options);
409 LY_CHECK_GOTO(ret, cleanup);
414 LY_CHECK_GOTO(ret, cleanup);
417 ret = union_find_type(ctx, type_u, subvalue, options, 0, NULL, NULL, NULL, unres, err);
423 LY_CHECK_ERR_GOTO(r, ret = r, cleanup);
457 lyb_parse_union(subvalue->
original, 0, &type_idx, NULL, NULL);
459 if (union_store_type(ctx, type_u, type_idx, subvalue, 0, 1, ctx_node, tree, NULL, err)) {
470 rc = union_find_type(ctx, type_u, subvalue, 0, 1, ctx_node, tree, NULL, NULL, err);
473 subvalue->
value = orig;
493 return val1->subvalue->value.
realtype->
plugin->
compare(ctx, &val1->subvalue->value, &val2->subvalue->value);
504 return val1->subvalue->value.
realtype->
plugin->
sort(ctx, &val1->subvalue->value, &val2->subvalue->value);
510 if (types[u] == val1->subvalue->value.
realtype) {
513 }
else if (types[u] == val2->subvalue->value.
realtype) {
537 void *prefix_data,
size_t *value_len)
543 uint32_t type_idx = 0;
557 r = union_find_type(ctx, type_u, subvalue, 0, 0, NULL, NULL, &type_idx, NULL, &err);
564 LY_CHECK_RET(!pval, NULL);
568 ret = malloc(*value_len);
569 LY_CHECK_RET(!ret, NULL);
583 LIBYANG_API_DEF
const void *
585 void *prefix_data,
ly_bool *dynamic,
size_t *value_len)
590 size_t lyb_data_len = 0;
602 ret = lyb_union_print(ctx, type_u, subvalue, prefix_data, &lyb_data_len);
604 *value_len = lyb_data_len;
626 memset(dup, 0,
sizeof *dup);
630 LY_CHECK_GOTO(ret, cleanup);
632 dup_val = calloc(1,
sizeof *dup_val);
633 LY_CHECK_ERR_GOTO(!dup_val,
LOGMEM(ctx); ret =
LY_EMEM, cleanup);
634 dup->subvalue = dup_val;
637 LY_CHECK_GOTO(ret, cleanup);
640 dup_val->original = calloc(1, orig_val->
orig_len);
641 LY_CHECK_ERR_GOTO(!dup_val->original,
LOGMEM(ctx); ret =
LY_EMEM, cleanup);
644 dup_val->original = strdup(
"");
645 LY_CHECK_ERR_GOTO(!dup_val->original,
LOGMEM(ctx); ret =
LY_EMEM, cleanup);
647 dup_val->orig_len = orig_val->
orig_len;
649 dup_val->format = orig_val->
format;
650 dup_val->ctx_node = orig_val->
ctx_node;
651 dup_val->hints = orig_val->
hints;
653 LY_CHECK_GOTO(ret, cleanup);
692 .name = LY_TYPE_UNION_STR,
694 .plugin.id =
"libyang 2 - union,version 1",
702 .plugin.lyb_data_len = -1,
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)
struct lyplg_type * plugin
Generic structure for a data node.
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().
uint8_t ly_bool
Type to indicate boolean value.
LIBYANG_API_DECL const void * lyplg_type_print_union(const struct ly_ctx *ctx, const struct lyd_value *value, LY_VALUE_FORMAT format, void *prefix_data, ly_bool *dynamic, size_t *value_len)
Implementation of lyplg_type_print_clb for the built-in union type.
#define LYPLG_TYPE_STORE_DYNAMIC
LIBYANG_API_DECL void lyplg_type_free_union(const struct ly_ctx *ctx, struct lyd_value *value)
Implementation of lyplg_type_free_clb for the built-in union type.
struct lysc_node * ctx_node
struct lysc_type ** types
LYPLG_TYPE_VAL_INLINE_DESTROY(val)
The main libyang public header.
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 lyplg_type_prefix_data_new(const struct ly_ctx *ctx, const void *value, size_t value_len, 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 lyplg_type_store_union(const struct ly_ctx *ctx, const struct lysc_type *type, const void *value, size_t value_len, uint32_t options, LY_VALUE_FORMAT format, void *prefix_data, uint32_t hints, const struct lysc_node *ctx_node, struct lyd_value *storage, struct lys_glob_unres *unres, struct ly_err_item **err)
Implementation of lyplg_type_store_clb for the built-in union type.
LIBYANG_API_DECL LY_ERR lyplg_type_compare_union(const struct ly_ctx *ctx, const struct lyd_value *val1, const struct lyd_value *val2)
Implementation of lyplg_type_compare_clb for the built-in union type.
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 int lyplg_type_sort_union(const struct ly_ctx *ctx, const struct lyd_value *val1, const struct lyd_value *val2)
Implementation of lyplg_type_sort_clb for the built-in union type.
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.
lyplg_type_print_clb print
lyplg_type_validate_clb validate
#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 lyplg_type_validate_union(const struct ly_ctx *ctx, const struct lysc_type *type, const struct lyd_node *ctx_node, const struct lyd_node *tree, struct lyd_value *storage, struct ly_err_item **err)
Implementation of lyplg_type_validate_clb for the built-in union type.
#define TYPE_IDX_SIZE
Size in bytes of the used type index in the LYB Binary Format.
lyplg_type_compare_clb compare
Special lyd_value structure for built-in union values.
API for (user) types plugins.
LIBYANG_API_DECL LY_ERR lyplg_type_dup_union(const struct ly_ctx *ctx, const struct lyd_value *original, struct lyd_value *dup)
Implementation of lyplg_type_dup_clb for the built-in union type.
LY_ERR
libyang's error codes returned by the libyang functions.
#define LYPLG_TYPE_STORE_ONLY
assert(!value->_canonical)