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 = 0, 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) {
 
  399     } 
else if (type_idx) {
 
  429 lyb_fill_subvalue(
const struct ly_ctx *ctx, 
struct lysc_type_union *type_u, 
const void *lyb_data, uint32_t lyb_data_size_bits,
 
  430         void *prefix_data, 
struct lyd_value_union *subvalue, uint32_t *options, 
struct lys_glob_unres *unres,
 
  434     uint32_t lyb_value_size_bits = 0, type_idx;
 
  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, NULL, unres, err);
 
  465 lyplg_type_store_union(
const struct ly_ctx *ctx, 
const struct lysc_type *type, 
const void *value, uint32_t value_size_bits,
 
  477     memset(storage, 0, 
sizeof *storage);
 
  479     LY_CHECK_ERR_GOTO(!subvalue, ret = 
LY_EMEM, cleanup);
 
  486         ret = lyb_fill_subvalue(ctx, type_u, value, value_size_bits, prefix_data, subvalue, &options, unres, err);
 
  490         ret = union_subvalue_assignment(value, value_size_bits, &subvalue->
original, &subvalue->
orig_size_bits, &options);
 
  491         LY_CHECK_GOTO(ret, cleanup);
 
  496         LY_CHECK_GOTO(ret, cleanup);
 
  499         ret = union_find_type(ctx, type_u, subvalue, options & ~LYPLG_TYPE_STORE_ONLY, 0, NULL, NULL, NULL, NULL, unres,
 
  501         if (ret && (ret != 
LY_EINCOMPLETE) && (options & LYPLG_TYPE_STORE_ONLY)) {
 
  505             ret = union_find_type(ctx, type_u, subvalue, options, 0, NULL, NULL, NULL, NULL, unres, err);
 
  512     LY_CHECK_ERR_GOTO(r, ret = r, cleanup);
 
  520         lyplg_type_free_union(ctx, storage);
 
  526 lyplg_type_validate_tree_union(
const struct ly_ctx *ctx, 
const struct lysc_type *type, 
const struct lyd_node *ctx_node,
 
  544     LY_CHECK_RET(subvalue_type_plg->
duplicate(ctx, &subvalue->
value, &orig));
 
  545     subvalue_type_plg->
free(ctx, &subvalue->
value);
 
  549         lyb_parse_union(subvalue->
original, 0, &type_idx, NULL, NULL);
 
  551         if (union_store_type(ctx, type_u, type_idx, subvalue, 0, 1, ctx_node, tree, top_ext, NULL, err)) {
 
  562         rc = union_find_type(ctx, type_u, subvalue, 0, 1, ctx_node, tree, top_ext, NULL, NULL, err);
 
  565             subvalue->
value = orig;
 
  586             &val1->subvalue->value, &val2->subvalue->value);
 
  598                 &val1->subvalue->value, &val2->subvalue->value);
 
  611         if (type == val1->subvalue->value.
realtype) {
 
  614         } 
else if (type == val2->subvalue->value.
realtype) {
 
  638         void *prefix_data, uint32_t *value_size_bits)
 
  643     uint32_t num = 0, pval_size_bits, type_idx = 0;
 
  653     r = union_find_type(ctx, type_u, subvalue, 0, 0, NULL, NULL, NULL, &type_idx, NULL, &err);
 
  659             prefix_data, &dynamic, &pval_size_bits);
 
  660     LY_CHECK_RET(!pval, NULL);
 
  665     LY_CHECK_RET(!ret, NULL);
 
  667     num = htole32(type_idx);
 
  680         void *prefix_data, 
ly_bool *dynamic, uint32_t *value_size_bits)
 
  685     uint32_t lyb_data_size_bits = 0;
 
  690         if (value_size_bits) {
 
  697         ret = lyb_union_print(ctx, type_u, subvalue, prefix_data, &lyb_data_size_bits);
 
  698         if (value_size_bits) {
 
  699             *value_size_bits = lyb_data_size_bits;
 
  706             format, prefix_data, dynamic, value_size_bits);
 
  722     memset(dup, 0, 
sizeof *dup);
 
  726     LY_CHECK_GOTO(ret, cleanup);
 
  728     dup_val = calloc(1, 
sizeof *dup_val);
 
  729     LY_CHECK_ERR_GOTO(!dup_val, 
LOGMEM(ctx); ret = 
LY_EMEM, cleanup);
 
  730     dup->subvalue = dup_val;
 
  733     LY_CHECK_GOTO(ret, cleanup);
 
  737         LY_CHECK_ERR_GOTO(!dup_val->original, 
LOGMEM(ctx); ret = 
LY_EMEM, cleanup);
 
  740         dup_val->original = strdup(
"");
 
  741         LY_CHECK_ERR_GOTO(!dup_val->original, 
LOGMEM(ctx); ret = 
LY_EMEM, cleanup);
 
  745     dup_val->format = orig_val->
format;
 
  746     dup_val->ctx_node = orig_val->
ctx_node;
 
  747     dup_val->hints = orig_val->
hints;
 
  749     LY_CHECK_GOTO(ret, cleanup);
 
  753         lyplg_type_free_union(ctx, dup);
 
  759 lyplg_type_free_union(
const struct ly_ctx *ctx, 
struct lyd_value *value)
 
  788         .name = LY_TYPE_UNION_STR,
 
  790         .plugin.id = 
"ly2 union",
 
  792         .plugin.store = lyplg_type_store_union,
 
  793         .plugin.validate_value = NULL,
 
  794         .plugin.validate_tree = lyplg_type_validate_tree_union,
 
  795         .plugin.compare = lyplg_type_compare_union,
 
  796         .plugin.sort = lyplg_type_sort_union,
 
  797         .plugin.print = lyplg_type_print_union,
 
  798         .plugin.duplicate = lyplg_type_dup_union,
 
  799         .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)