libyang  2.0.112
libyang is YANG data modelling language parser and toolkit written (and providing API) in C.
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
union.c
Go to the documentation of this file.
1 
15 #define _GNU_SOURCE /* strdup */
16 
17 #include "plugins_types.h"
18 
19 #include <assert.h>
20 #include <stdint.h>
21 #include <stdlib.h>
22 #include <string.h>
23 
24 #include "libyang.h"
25 
26 /* additional internal headers for some useful simple macros */
27 #include "common.h"
28 #include "compat.h"
29 #include "plugins_internal.h" /* LY_TYPE_*_STR */
30 
46 #define IDX_SIZE 4
47 
58 static LY_ERR
59 union_subvalue_assignment(const void *value, size_t value_len, void **original, size_t *orig_len, uint32_t *options)
60 {
61  LY_ERR ret = LY_SUCCESS;
62 
63  if (*options & LYPLG_TYPE_STORE_DYNAMIC) {
64  /* The allocated value is stored and spend. */
65  *original = (void *)value;
66  *options &= ~LYPLG_TYPE_STORE_DYNAMIC;
67  } else if (value_len) {
68  /* Make copy of the value. */
69  *original = calloc(1, value_len);
70  LY_CHECK_ERR_RET(!*original, ret = LY_EMEM, ret);
71  memcpy(*original, value, value_len);
72  } else {
73  /* Empty value. */
74  *original = strdup("");
75  LY_CHECK_ERR_RET(!*original, ret = LY_EMEM, ret);
76  }
77  *orig_len = value_len;
78 
79  return ret;
80 }
81 
91 static LY_ERR
92 lyb_union_validate(const void *lyb_data, size_t lyb_data_len, const struct lysc_type_union *type_u, struct ly_err_item **err)
93 {
94  LY_ERR ret = LY_SUCCESS;
95  uint64_t type_idx = 0;
96 
97  /* Basic validation. */
98  if (lyb_data_len < IDX_SIZE) {
99  ret = ly_err_new(err, LY_EVALID, LYVE_DATA, NULL, NULL, "Invalid LYB union value size %zu (expected at least 4).",
100  lyb_data_len);
101  return ret;
102  }
103 
104  /* Get index in correct byte order. */
105  memcpy(&type_idx, lyb_data, IDX_SIZE);
106  type_idx = le64toh(type_idx);
107  if (type_idx >= LY_ARRAY_COUNT(type_u->types)) {
108  ret = ly_err_new(err, LY_EVALID, LYVE_DATA, NULL, NULL,
109  "Invalid LYB union type index %" PRIu64 " (type count %" LY_PRI_ARRAY_COUNT_TYPE ").",
110  type_idx, LY_ARRAY_COUNT(type_u->types));
111  return ret;
112  }
113 
114  return ret;
115 }
116 
127 static void
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)
129 {
130  uint64_t num = 0;
131 
132  assert(lyb_data && !(lyb_value && !lyb_value_len));
133 
134  if (type_idx) {
135  memcpy(&num, lyb_data, IDX_SIZE);
136  num = le64toh(num);
137 
138  *type_idx = num;
139  }
140 
141  if (lyb_value && lyb_value_len && lyb_data_len) {
142  /* Get lyb_value and its length. */
143  if (lyb_data_len == IDX_SIZE) {
144  *lyb_value_len = 0;
145  *lyb_value = "";
146  } else {
147  *lyb_value_len = lyb_data_len - IDX_SIZE;
148  *lyb_value = (char *)lyb_data + IDX_SIZE;
149  }
150  }
151 }
152 
166 static LY_ERR
167 union_store_type(const struct ly_ctx *ctx, struct lysc_type *type, struct lyd_value_union *subvalue,
168  ly_bool resolve, const struct lyd_node *ctx_node, const struct lyd_node *tree, struct lys_glob_unres *unres,
169  struct ly_err_item **err)
170 {
171  LY_ERR ret;
172  const void *value = NULL;
173  size_t value_len = 0;
174 
175  if (subvalue->format == LY_VALUE_LYB) {
176  lyb_parse_union(subvalue->original, subvalue->orig_len, NULL, &value, &value_len);
177  } else {
178  value = subvalue->original;
179  value_len = subvalue->orig_len;
180  }
181 
182  ret = type->plugin->store(ctx, type, value, value_len, 0, subvalue->format, subvalue->prefix_data, subvalue->hints,
183  subvalue->ctx_node, &subvalue->value, unres, err);
184  if ((ret != LY_SUCCESS) && (ret != LY_EINCOMPLETE)) {
185  /* clear any leftover/freed garbage */
186  memset(&subvalue->value, 0, sizeof subvalue->value);
187  return ret;
188  }
189 
190  if (resolve && (ret == LY_EINCOMPLETE)) {
191  /* we need the value resolved */
192  ret = subvalue->value.realtype->plugin->validate(ctx, type, ctx_node, tree, &subvalue->value, err);
193  if (ret) {
194  /* resolve failed, we need to free the stored value */
195  type->plugin->free(ctx, &subvalue->value);
196  }
197  }
198 
199  return ret;
200 }
201 
216 static LY_ERR
217 union_find_type(const struct ly_ctx *ctx, struct lysc_type **types, struct lyd_value_union *subvalue,
218  ly_bool resolve, const struct lyd_node *ctx_node, const struct lyd_node *tree, uint32_t *type_idx,
219  struct lys_glob_unres *unres, struct ly_err_item **err)
220 {
221  LY_ERR ret = LY_SUCCESS;
223  uint32_t prev_lo;
224 
225  if (!types || !LY_ARRAY_COUNT(types)) {
226  return LY_EINVAL;
227  }
228 
229  *err = NULL;
230 
231  /* turn logging off */
232  prev_lo = ly_log_options(0);
233 
234  /* use the first usable subtype to store the value */
235  for (u = 0; u < LY_ARRAY_COUNT(types); ++u) {
236  ret = union_store_type(ctx, types[u], subvalue, resolve, ctx_node, tree, unres, err);
237  if ((ret == LY_SUCCESS) || (ret == LY_EINCOMPLETE)) {
238  break;
239  }
240 
241  ly_err_free(*err);
242  *err = NULL;
243  }
244 
245  if (u == LY_ARRAY_COUNT(types)) {
246  ret = ly_err_new(err, LY_EVALID, LYVE_DATA, NULL, NULL, "Invalid union value \"%.*s\" - no matching subtype found.",
247  (int)subvalue->orig_len, (char *)subvalue->original);
248  } else if (type_idx) {
249  *type_idx = u;
250  }
251 
252  /* restore logging */
253  ly_log_options(prev_lo);
254  return ret;
255 }
256 
275 static LY_ERR
276 lyb_fill_subvalue(const struct ly_ctx *ctx, struct lysc_type_union *type_u, const void *lyb_data, size_t lyb_data_len,
277  void *prefix_data, struct lyd_value_union *subvalue, uint32_t *options, struct lys_glob_unres *unres,
278  struct ly_err_item **err)
279 {
280  LY_ERR ret;
281  uint32_t type_idx;
282  const void *lyb_value = NULL;
283  size_t lyb_value_len = 0;
284 
285  ret = lyb_union_validate(lyb_data, lyb_data_len, type_u, err);
286  LY_CHECK_RET(ret);
287 
288  /* Parse lyb_data and set the lyb_value and lyb_value_len. */
289  lyb_parse_union(lyb_data, lyb_data_len, &type_idx, &lyb_value, &lyb_value_len);
290  LY_CHECK_RET(ret);
291 
292  /* Store lyb_data to subvalue. */
293  ret = union_subvalue_assignment(lyb_data, lyb_data_len,
294  &subvalue->original, &subvalue->orig_len, options);
295  LY_CHECK_RET(ret);
296 
297  if (lyb_value) {
298  /* Resolve prefix_data and set format. */
299  ret = lyplg_type_prefix_data_new(ctx, lyb_value, lyb_value_len, LY_VALUE_LYB, prefix_data, &subvalue->format,
300  &subvalue->prefix_data);
301  LY_CHECK_RET(ret);
302  assert(subvalue->format == LY_VALUE_LYB);
303  } else {
304  /* The lyb_parse_union() did not find lyb_value.
305  * Just set format.
306  */
307  subvalue->format = LY_VALUE_LYB;
308  }
309 
310  /* Use the specific type to store the value. */
311  ret = union_store_type(ctx, type_u->types[type_idx], subvalue, 0, NULL, NULL, unres, err);
312 
313  return ret;
314 }
315 
316 API LY_ERR
317 lyplg_type_store_union(const struct ly_ctx *ctx, const struct lysc_type *type, const void *value, size_t value_len,
318  uint32_t options, LY_VALUE_FORMAT format, void *prefix_data, uint32_t hints, const struct lysc_node *ctx_node,
319  struct lyd_value *storage, struct lys_glob_unres *unres, struct ly_err_item **err)
320 {
321  LY_ERR ret = LY_SUCCESS;
322  struct lysc_type_union *type_u = (struct lysc_type_union *)type;
323  struct lyd_value_union *subvalue;
324 
325  *err = NULL;
326 
327  /* init storage */
328  memset(storage, 0, sizeof *storage);
329  LYPLG_TYPE_VAL_INLINE_PREPARE(storage, subvalue);
330  LY_CHECK_ERR_GOTO(!subvalue, ret = LY_EMEM, cleanup);
331  storage->realtype = type;
332  subvalue->hints = hints;
333  subvalue->ctx_node = ctx_node;
334 
335  if (format == LY_VALUE_LYB) {
336  ret = lyb_fill_subvalue(ctx, type_u, value, value_len,
337  prefix_data, subvalue, &options, unres, err);
338  LY_CHECK_GOTO((ret != LY_SUCCESS) && (ret != LY_EINCOMPLETE), cleanup);
339  } else {
340  /* Store @p value to subvalue. */
341  ret = union_subvalue_assignment(value, value_len,
342  &subvalue->original, &subvalue->orig_len, &options);
343  LY_CHECK_GOTO(ret, cleanup);
344 
345  /* store format-specific data for later prefix resolution */
346  ret = lyplg_type_prefix_data_new(ctx, value, value_len, format, prefix_data, &subvalue->format,
347  &subvalue->prefix_data);
348  LY_CHECK_GOTO(ret, cleanup);
349 
350  /* use the first usable subtype to store the value */
351  ret = union_find_type(ctx, type_u->types, subvalue, 0, NULL, NULL, NULL, unres, err);
352  LY_CHECK_GOTO((ret != LY_SUCCESS) && (ret != LY_EINCOMPLETE), cleanup);
353  }
354 
355  /* store canonical value, if any (use the specific type value) */
356  ret = lydict_insert(ctx, subvalue->value._canonical, 0, &storage->_canonical);
357  LY_CHECK_GOTO(ret, cleanup);
358 
359 cleanup:
360  if (options & LYPLG_TYPE_STORE_DYNAMIC) {
361  free((void *)value);
362  }
363 
364  if ((ret != LY_SUCCESS) && (ret != LY_EINCOMPLETE)) {
365  lyplg_type_free_union(ctx, storage);
366  }
367  return ret;
368 }
369 
370 API LY_ERR
371 lyplg_type_validate_union(const struct ly_ctx *ctx, const struct lysc_type *type, const struct lyd_node *ctx_node,
372  const struct lyd_node *tree, struct lyd_value *storage, struct ly_err_item **err)
373 {
374  LY_ERR ret = LY_SUCCESS;
375  struct lysc_type_union *type_u = (struct lysc_type_union *)storage->realtype;
376  struct lyd_value_union *subvalue = storage->subvalue;
377  uint32_t type_idx;
378 
379  *err = NULL;
380 
381  if (!subvalue->value.realtype->plugin->validate) {
382  /* nothing to resolve */
383  return LY_SUCCESS;
384  }
385 
386  /* resolve the stored value */
387  if (!subvalue->value.realtype->plugin->validate(ctx, type, ctx_node, tree, &subvalue->value, err)) {
388  /* resolve successful */
389  return LY_SUCCESS;
390  }
391 
392  /* Resolve failed, we have to try another subtype of the union.
393  * Unfortunately, since the realtype can change (e.g. in leafref), we are not able to detect
394  * which of the subtype's were tried the last time, so we have to try all of them again.
395  */
396  ly_err_free(*err);
397  *err = NULL;
398 
399  if (subvalue->format == LY_VALUE_LYB) {
400  /* use the specific type to store the value */
401  lyb_parse_union(subvalue->original, 0, &type_idx, NULL, NULL);
402  ret = union_store_type(ctx, type_u->types[type_idx], subvalue, 1, ctx_node, tree, NULL, err);
403  LY_CHECK_RET(ret);
404  } else {
405  /* use the first usable subtype to store the value */
406  ret = union_find_type(ctx, type_u->types, subvalue, 1, ctx_node, tree, NULL, NULL, err);
407  LY_CHECK_RET(ret);
408  }
409 
410  /* store and resolve the value */
411  ret = union_find_type(ctx, type_u->types, subvalue, 1, ctx_node, tree, NULL, NULL, err);
412  LY_CHECK_RET(ret);
413 
414  /* success, update the canonical value, if any generated */
415  lydict_remove(ctx, storage->_canonical);
416  LY_CHECK_RET(lydict_insert(ctx, subvalue->value._canonical, 0, &storage->_canonical));
417  return LY_SUCCESS;
418 }
419 
420 API LY_ERR
421 lyplg_type_compare_union(const struct lyd_value *val1, const struct lyd_value *val2)
422 {
423  if (val1->realtype != val2->realtype) {
424  return LY_ENOT;
425  }
426 
427  if (val1->subvalue->value.realtype != val2->subvalue->value.realtype) {
428  return LY_ENOT;
429  }
430  return val1->subvalue->value.realtype->plugin->compare(&val1->subvalue->value, &val2->subvalue->value);
431 }
432 
445 static const void *
446 lyb_union_print(const struct ly_ctx *ctx, struct lysc_type_union *type_u, struct lyd_value_union *subvalue,
447  void *prefix_data, size_t *value_len)
448 {
449  void *ret = NULL;
450  LY_ERR retval;
451  struct ly_err_item *err;
452  uint64_t num = 0;
453  uint32_t type_idx;
454  ly_bool dynamic;
455  size_t pval_len;
456  void *pval;
457 
458  /* Find out the index number (type_idx). The call should succeed
459  * because the union_find_type() has already been called in the
460  * lyplg_type_store_union().
461  */
462  if (!ctx) {
463  assert(subvalue->ctx_node);
464  ctx = subvalue->ctx_node->module->ctx;
465  }
466  subvalue->value.realtype->plugin->free(ctx, &subvalue->value);
467  retval = union_find_type(ctx, type_u->types, subvalue, 0, NULL, NULL, &type_idx, NULL, &err);
468  LY_CHECK_RET((retval != LY_SUCCESS) && (retval != LY_EINCOMPLETE), NULL);
469 
470  /* Print subvalue in LYB format. */
471  pval = (void *)subvalue->value.realtype->plugin->print(NULL, &subvalue->value, LY_VALUE_LYB, prefix_data, &dynamic,
472  &pval_len);
473  LY_CHECK_RET(!pval, NULL);
474 
475  /* Create LYB data. */
476  *value_len = IDX_SIZE + pval_len;
477  ret = malloc(*value_len);
478  LY_CHECK_RET(!ret, NULL);
479 
480  num = type_idx;
481  num = htole64(num);
482  memcpy(ret, &num, IDX_SIZE);
483  memcpy((char *)ret + IDX_SIZE, pval, pval_len);
484 
485  if (dynamic) {
486  free(pval);
487  }
488 
489  return ret;
490 }
491 
492 API const void *
493 lyplg_type_print_union(const struct ly_ctx *ctx, const struct lyd_value *value, LY_VALUE_FORMAT format,
494  void *prefix_data, ly_bool *dynamic, size_t *value_len)
495 {
496  const void *ret;
497  struct lyd_value_union *subvalue = value->subvalue;
498  struct lysc_type_union *type_u = (struct lysc_type_union *)value->realtype;
499  size_t lyb_data_len = 0;
500 
501  if ((format == LY_VALUE_LYB) && (subvalue->format == LY_VALUE_LYB)) {
502  /* The return value is already ready. */
503  *dynamic = 0;
504  if (value_len) {
505  *value_len = subvalue->orig_len;
506  }
507  return subvalue->original;
508  } else if ((format == LY_VALUE_LYB) && (subvalue->format != LY_VALUE_LYB)) {
509  /* The return LYB data must be created. */
510  *dynamic = 1;
511  ret = lyb_union_print(ctx, type_u, subvalue, prefix_data, &lyb_data_len);
512  if (value_len) {
513  *value_len = lyb_data_len;
514  }
515  return ret;
516  }
517 
518  assert(format != LY_VALUE_LYB);
519  ret = (void *)subvalue->value.realtype->plugin->print(ctx, &subvalue->value, format, prefix_data, dynamic, value_len);
520  if (!value->_canonical && (format == LY_VALUE_CANON)) {
521  /* the canonical value is supposed to be stored now */
522  lydict_insert(ctx, subvalue->value._canonical, 0, (const char **)&value->_canonical);
523  }
524 
525  return ret;
526 }
527 
528 API LY_ERR
529 lyplg_type_dup_union(const struct ly_ctx *ctx, const struct lyd_value *original, struct lyd_value *dup)
530 {
531  LY_ERR ret = LY_SUCCESS;
532  struct lyd_value_union *orig_val = original->subvalue, *dup_val;
533 
534  /* init dup value */
535  memset(dup, 0, sizeof *dup);
536  dup->realtype = original->realtype;
537 
538  ret = lydict_insert(ctx, original->_canonical, 0, &dup->_canonical);
539  LY_CHECK_GOTO(ret, cleanup);
540 
541  dup_val = calloc(1, sizeof *dup_val);
542  LY_CHECK_ERR_GOTO(!dup_val, LOGMEM(ctx); ret = LY_EMEM, cleanup);
543  dup->subvalue = dup_val;
544 
545  ret = orig_val->value.realtype->plugin->duplicate(ctx, &orig_val->value, &dup_val->value);
546  LY_CHECK_GOTO(ret, cleanup);
547 
548  if (orig_val->orig_len) {
549  dup_val->original = calloc(1, orig_val->orig_len);
550  LY_CHECK_ERR_GOTO(!dup_val->original, LOGMEM(ctx); ret = LY_EMEM, cleanup);
551  memcpy(dup_val->original, orig_val->original, orig_val->orig_len);
552  } else {
553  dup_val->original = strdup("");
554  LY_CHECK_ERR_GOTO(!dup_val->original, LOGMEM(ctx); ret = LY_EMEM, cleanup);
555  }
556  dup_val->orig_len = orig_val->orig_len;
557 
558  dup_val->format = orig_val->format;
559  dup_val->ctx_node = orig_val->ctx_node;
560  dup_val->hints = orig_val->hints;
561  ret = lyplg_type_prefix_data_dup(ctx, orig_val->format, orig_val->prefix_data, &dup_val->prefix_data);
562  LY_CHECK_GOTO(ret, cleanup);
563 
564 cleanup:
565  if (ret) {
566  lyplg_type_free_union(ctx, dup);
567  }
568  return ret;
569 }
570 
571 API void
572 lyplg_type_free_union(const struct ly_ctx *ctx, struct lyd_value *value)
573 {
574  struct lyd_value_union *val;
575 
576  lydict_remove(ctx, value->_canonical);
577  value->_canonical = NULL;
578  LYD_VALUE_GET(value, val);
579  if (val) {
580  if (val->value.realtype) {
581  val->value.realtype->plugin->free(ctx, &val->value);
582  }
584  free(val->original);
585 
587  }
588 }
589 
598  {
599  .module = "",
600  .revision = NULL,
601  .name = LY_TYPE_UNION_STR,
602 
603  .plugin.id = "libyang 2 - union,version 1",
604  .plugin.store = lyplg_type_store_union,
605  .plugin.validate = lyplg_type_validate_union,
606  .plugin.compare = lyplg_type_compare_union,
607  .plugin.sort = NULL,
608  .plugin.print = lyplg_type_print_union,
609  .plugin.duplicate = lyplg_type_dup_union,
610  .plugin.free = lyplg_type_free_union,
611  .plugin.lyb_data_len = -1,
612  },
613  {0}
614 };
struct lysc_type * realtype
Definition: tree_data.h:539
Compiled YANG data node.
Definition: tree_schema.h:1666
#define LY_PRI_ARRAY_COUNT_TYPE
Printing format specifier macro for LY_ARRAY_SIZE_TYPE values.
Definition: tree.h:109
struct ly_ctx * ctx
Definition: tree_schema.h:2343
struct lyplg_type * plugin
Definition: tree_schema.h:1551
Generic structure for a data node.
Definition: tree_data.h:759
LY_ERR ly_err_new(struct ly_err_item **err, LY_ERR ecode, LY_VECODE vecode, char *path, char *apptag, const char *err_format,...) _FORMAT_PRINTF(6
Create and fill error structure.
Definition: log.h:248
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.
Definition: union.c:317
uint8_t ly_bool
Type to indicate boolean value.
Definition: log.h:25
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 ...
lyplg_type_free_clb free
#define LYPLG_TYPE_STORE_DYNAMIC
void * original
Definition: tree_data.h:593
LY_ERR void ly_err_free(void *ptr)
Destructor for the error records created with ly_err_new().
LY_ERR lyplg_type_prefix_data_dup(const struct ly_ctx *ctx, LY_VALUE_FORMAT format, const void *orig, void **dup)
Duplicate prefix data.
size_t orig_len
Definition: tree_data.h:594
#define LOGMEM(CTX)
Definition: tree_edit.h:22
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...
uint32_t ly_log_options(uint32_t opts)
Set logger options. Default is LY_LOLOG | LY_LOSTORE_LAST.
struct lysc_node * ctx_node
Definition: tree_data.h:600
struct lysc_type ** types
Definition: tree_schema.h:1647
The main libyang public header.
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.
Definition: union.c:493
YANG data representation.
Definition: tree_data.h:535
const char * _canonical
Definition: tree_data.h:536
lyplg_type_store_clb store
Libyang full error structure.
Definition: log.h:291
Definition: log.h:283
#define LYD_VALUE_GET(value, type_val)
Get the value in format specific to the type.
Definition: tree_data.h:578
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.
Definition: log.h:254
struct lyplg_type_record plugins_union[]
Plugin information for union type implementation.
Definition: union.c:597
uint32_t hints
Definition: tree_data.h:595
#define IDX_SIZE
Size in bytes of the index in the LYB Binary Format.
Definition: union.c:46
void * prefix_data
Definition: tree_data.h:599
lyplg_type_dup_clb duplicate
const char * module
#define LY_ARRAY_COUNT(ARRAY)
Get the number of records in the ARRAY.
Definition: tree.h:148
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.
Definition: union.c:572
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.
Definition: union.c:529
LY_ERR lyplg_type_compare_union(const struct lyd_value *val1, const struct lyd_value *val2)
Implementation of lyplg_type_compare_clb for the built-in union type.
Definition: union.c:421
#define LY_ARRAY_COUNT_TYPE
Type (i.e. size) of the sized array&#39;s size counter.
Definition: tree.h:104
Definition: log.h:260
struct lys_module * module
Definition: tree_schema.h:1670
#define LYPLG_TYPE_VAL_INLINE_DESTROY(type_val)
Destroy a prepared value.
LY_VALUE_FORMAT
All kinds of supported value formats and prefix mappings to modules.
Definition: tree.h:235
lyplg_type_print_clb print
lyplg_type_validate_clb validate
void lyplg_type_prefix_data_free(LY_VALUE_FORMAT format, void *prefix_data)
Free internal prefix data.
#define LYPLG_TYPE_VAL_INLINE_PREPARE(storage, type_val)
Prepare value memory for storing a specific type value, may be allocated dynamically.
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.
Definition: union.c:371
LY_ERR
libyang&#39;s error codes returned by the libyang functions.
Definition: log.h:245
lyplg_type_compare_clb compare
Special lyd_value structure for built-in union values.
Definition: tree_data.h:590
API for (user) types plugins.
LY_VALUE_FORMAT format
Definition: tree_data.h:596
libyang context handler.
struct lyd_value value
Definition: tree_data.h:591
Definition: log.h:250