libyang  2.1.148
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  *err = NULL;
176 
177  if (subvalue->format == LY_VALUE_LYB) {
178  lyb_parse_union(subvalue->original, subvalue->orig_len, NULL, &value, &value_len);
179  } else {
180  value = subvalue->original;
181  value_len = subvalue->orig_len;
182  }
183 
184  ret = type->plugin->store(ctx, type, value, value_len, 0, subvalue->format, subvalue->prefix_data, subvalue->hints,
185  subvalue->ctx_node, &subvalue->value, unres, err);
186  if ((ret != LY_SUCCESS) && (ret != LY_EINCOMPLETE)) {
187  /* clear any leftover/freed garbage */
188  memset(&subvalue->value, 0, sizeof subvalue->value);
189  return ret;
190  }
191 
192  if (resolve && (ret == LY_EINCOMPLETE)) {
193  /* we need the value resolved */
194  ret = type->plugin->validate(ctx, type, ctx_node, tree, &subvalue->value, err);
195  if (ret) {
196  /* resolve failed, we need to free the stored value */
197  type->plugin->free(ctx, &subvalue->value);
198  }
199  }
200 
201  return ret;
202 }
203 
218 static LY_ERR
219 union_find_type(const struct ly_ctx *ctx, struct lysc_type **types, struct lyd_value_union *subvalue,
220  ly_bool resolve, const struct lyd_node *ctx_node, const struct lyd_node *tree, uint32_t *type_idx,
221  struct lys_glob_unres *unres, struct ly_err_item **err)
222 {
223  LY_ERR ret = LY_SUCCESS;
225  struct ly_err_item **errs = NULL, *e;
226  uint32_t temp_lo = 0;
227  char *msg = NULL;
228  int msg_len = 0;
229 
230  *err = NULL;
231 
232  if (!types || !LY_ARRAY_COUNT(types)) {
233  return LY_EINVAL;
234  }
235 
236  /* alloc errors */
237  errs = calloc(LY_ARRAY_COUNT(types), sizeof *errs);
238  LY_CHECK_RET(!errs, LY_EMEM);
239 
240  /* turn logging temporarily off */
241  ly_temp_log_options(&temp_lo);
242 
243  /* use the first usable subtype to store the value */
244  for (u = 0; u < LY_ARRAY_COUNT(types); ++u) {
245  ret = union_store_type(ctx, types[u], subvalue, resolve, ctx_node, tree, unres, &e);
246  if ((ret == LY_SUCCESS) || (ret == LY_EINCOMPLETE)) {
247  break;
248  }
249 
250  errs[u] = e;
251  }
252 
253  if (u == LY_ARRAY_COUNT(types)) {
254  /* create the full error */
255  msg_len = asprintf(&msg, "Invalid union value \"%.*s\" - no matching subtype found:\n",
256  (int)subvalue->orig_len, (char *)subvalue->original);
257  if (msg_len == -1) {
258  LY_CHECK_ERR_GOTO(!errs, ret = LY_EMEM, cleanup);
259  }
260  for (u = 0; u < LY_ARRAY_COUNT(types); ++u) {
261  if (!errs[u]) {
262  /* no error for some reason */
263  continue;
264  }
265 
266  msg = ly_realloc(msg, msg_len + 4 + strlen(types[u]->plugin->id) + 2 + strlen(errs[u]->msg) + 2);
267  LY_CHECK_ERR_GOTO(!msg, ret = LY_EMEM, cleanup);
268  msg_len += sprintf(msg + msg_len, " %s: %s\n", types[u]->plugin->id, errs[u]->msg);
269  }
270 
271  ret = ly_err_new(err, LY_EVALID, LYVE_DATA, NULL, NULL, "%s", msg);
272  } else if (type_idx) {
273  *type_idx = u;
274  }
275 
276 cleanup:
277  for (u = 0; u < LY_ARRAY_COUNT(types); ++u) {
278  ly_err_free(errs[u]);
279  }
280  free(errs);
281  free(msg);
282  ly_temp_log_options(NULL);
283  return ret;
284 }
285 
300 static LY_ERR
301 lyb_fill_subvalue(const struct ly_ctx *ctx, struct lysc_type_union *type_u, const void *lyb_data, size_t lyb_data_len,
302  void *prefix_data, struct lyd_value_union *subvalue, uint32_t *options, struct lys_glob_unres *unres,
303  struct ly_err_item **err)
304 {
305  LY_ERR ret;
306  uint32_t type_idx;
307  const void *lyb_value = NULL;
308  size_t lyb_value_len = 0;
309 
310  ret = lyb_union_validate(lyb_data, lyb_data_len, type_u, err);
311  LY_CHECK_RET(ret);
312 
313  /* parse lyb_data and set the lyb_value and lyb_value_len */
314  lyb_parse_union(lyb_data, lyb_data_len, &type_idx, &lyb_value, &lyb_value_len);
315  LY_CHECK_RET(ret);
316 
317  /* store lyb_data to subvalue */
318  ret = union_subvalue_assignment(lyb_data, lyb_data_len, &subvalue->original, &subvalue->orig_len, options);
319  LY_CHECK_RET(ret);
320 
321  if (lyb_value) {
322  /* resolve prefix_data and set format */
323  ret = lyplg_type_prefix_data_new(ctx, lyb_value, lyb_value_len, LY_VALUE_LYB, prefix_data, &subvalue->format,
324  &subvalue->prefix_data);
325  LY_CHECK_RET(ret);
326  assert(subvalue->format == LY_VALUE_LYB);
327  } else {
328  /* lyb_parse_union() did not find lyb_value, just set format */
329  subvalue->format = LY_VALUE_LYB;
330  }
331 
332  /* use the specific type to store the value */
333  ret = union_store_type(ctx, type_u->types[type_idx], subvalue, 0, NULL, NULL, unres, err);
334 
335  return ret;
336 }
337 
338 LIBYANG_API_DEF LY_ERR
339 lyplg_type_store_union(const struct ly_ctx *ctx, const struct lysc_type *type, const void *value, size_t value_len,
340  uint32_t options, LY_VALUE_FORMAT format, void *prefix_data, uint32_t hints, const struct lysc_node *ctx_node,
341  struct lyd_value *storage, struct lys_glob_unres *unres, struct ly_err_item **err)
342 {
343  LY_ERR ret = LY_SUCCESS, r;
344  struct lysc_type_union *type_u = (struct lysc_type_union *)type;
345  struct lyd_value_union *subvalue;
346 
347  *err = NULL;
348 
349  /* init storage */
350  memset(storage, 0, sizeof *storage);
351  LYPLG_TYPE_VAL_INLINE_PREPARE(storage, subvalue);
352  LY_CHECK_ERR_GOTO(!subvalue, ret = LY_EMEM, cleanup);
353  storage->realtype = type;
354  subvalue->hints = hints;
355  subvalue->ctx_node = ctx_node;
356 
357  if (format == LY_VALUE_LYB) {
358  ret = lyb_fill_subvalue(ctx, type_u, value, value_len, prefix_data, subvalue, &options, unres, err);
359  LY_CHECK_GOTO((ret != LY_SUCCESS) && (ret != LY_EINCOMPLETE), cleanup);
360  } else {
361  /* Store @p value to subvalue. */
362  ret = union_subvalue_assignment(value, value_len, &subvalue->original, &subvalue->orig_len, &options);
363  LY_CHECK_GOTO(ret, cleanup);
364 
365  /* store format-specific data for later prefix resolution */
366  ret = lyplg_type_prefix_data_new(ctx, value, value_len, format, prefix_data, &subvalue->format,
367  &subvalue->prefix_data);
368  LY_CHECK_GOTO(ret, cleanup);
369 
370  /* use the first usable subtype to store the value */
371  ret = union_find_type(ctx, type_u->types, subvalue, 0, NULL, NULL, NULL, unres, err);
372  LY_CHECK_GOTO((ret != LY_SUCCESS) && (ret != LY_EINCOMPLETE), cleanup);
373  }
374 
375  /* store canonical value, if any (use the specific type value) */
376  r = lydict_insert(ctx, subvalue->value._canonical, 0, &storage->_canonical);
377  LY_CHECK_ERR_GOTO(r, ret = r, cleanup);
378 
379 cleanup:
380  if (options & LYPLG_TYPE_STORE_DYNAMIC) {
381  free((void *)value);
382  }
383 
384  if ((ret != LY_SUCCESS) && (ret != LY_EINCOMPLETE)) {
385  lyplg_type_free_union(ctx, storage);
386  }
387  return ret;
388 }
389 
390 LIBYANG_API_DEF LY_ERR
391 lyplg_type_validate_union(const struct ly_ctx *ctx, const struct lysc_type *type, const struct lyd_node *ctx_node,
392  const struct lyd_node *tree, struct lyd_value *storage, struct ly_err_item **err)
393 {
394  LY_ERR ret = LY_SUCCESS;
395  struct lysc_type_union *type_u = (struct lysc_type_union *)type;
396  struct lyd_value_union *subvalue = storage->subvalue;
397  uint32_t type_idx;
398 
399  *err = NULL;
400 
401  /* because of types that do not store their own type as realtype (leafref), we are not able to call their
402  * validate callback (there is no way to get the type TODO could be added to struct lyd_value_union), so
403  * we have to perform union value storing again from scratch */
404  subvalue->value.realtype->plugin->free(ctx, &subvalue->value);
405 
406  if (subvalue->format == LY_VALUE_LYB) {
407  /* use the specific type to store the value */
408  lyb_parse_union(subvalue->original, 0, &type_idx, NULL, NULL);
409  ret = union_store_type(ctx, type_u->types[type_idx], subvalue, 1, ctx_node, tree, NULL, err);
410  LY_CHECK_RET(ret);
411  } else {
412  /* use the first usable subtype to store the value */
413  ret = union_find_type(ctx, type_u->types, subvalue, 1, ctx_node, tree, NULL, NULL, err);
414  LY_CHECK_RET(ret);
415  }
416 
417  /* success, update the canonical value, if any generated */
418  lydict_remove(ctx, storage->_canonical);
419  LY_CHECK_RET(lydict_insert(ctx, subvalue->value._canonical, 0, &storage->_canonical));
420  return LY_SUCCESS;
421 }
422 
423 LIBYANG_API_DEF LY_ERR
424 lyplg_type_compare_union(const struct lyd_value *val1, const struct lyd_value *val2)
425 {
426  if (val1->subvalue->value.realtype != val2->subvalue->value.realtype) {
427  return LY_ENOT;
428  }
429  return val1->subvalue->value.realtype->plugin->compare(&val1->subvalue->value, &val2->subvalue->value);
430 }
431 
444 static const void *
445 lyb_union_print(const struct ly_ctx *ctx, struct lysc_type_union *type_u, struct lyd_value_union *subvalue,
446  void *prefix_data, size_t *value_len)
447 {
448  void *ret = NULL;
449  LY_ERR r;
450  struct ly_err_item *err;
451  uint64_t num = 0;
452  uint32_t type_idx = 0;
453  ly_bool dynamic;
454  size_t pval_len;
455  void *pval;
456 
457  /* Find out the index number (type_idx). The call should succeed
458  * because the union_find_type() has already been called in the
459  * lyplg_type_store_union().
460  */
461  if (!ctx) {
462  assert(subvalue->ctx_node);
463  ctx = subvalue->ctx_node->module->ctx;
464  }
465  subvalue->value.realtype->plugin->free(ctx, &subvalue->value);
466  r = union_find_type(ctx, type_u->types, subvalue, 0, NULL, NULL, &type_idx, NULL, &err);
467  ly_err_free(err);
468  LY_CHECK_RET((r != LY_SUCCESS) && (r != 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 LIBYANG_API_DEF 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 LIBYANG_API_DEF 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 LIBYANG_API_DEF 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:564
Compiled YANG data node.
Definition: tree_schema.h:1414
#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:2107
struct lyplg_type * plugin
Definition: tree_schema.h:1298
Generic structure for a data node.
Definition: tree_data.h:781
LIBYANG_API_DECL 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:253
uint8_t ly_bool
Type to indicate boolean value.
Definition: log.h:28
lyplg_type_free_clb free
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.
Definition: union.c:493
#define LYPLG_TYPE_STORE_DYNAMIC
void * original
Definition: tree_data.h:618
size_t orig_len
Definition: tree_data.h:619
#define LOGMEM(CTX)
Definition: tree_edit.h:22
LIBYANG_API_DECL void ly_temp_log_options(uint32_t *opts)
Set temporary thread-safe logger options overwriting those set by ly_log_options().
char * msg
Definition: log.h:300
LIBYANG_API_DECL 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:424
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.
Definition: union.c:572
struct lysc_node * ctx_node
Definition: tree_data.h:625
struct lysc_type ** types
Definition: tree_schema.h:1395
The main libyang public header.
YANG data representation.
Definition: tree_data.h:560
const char * _canonical
Definition: tree_data.h:561
lyplg_type_store_clb store
Libyang full error structure.
Definition: log.h:296
Definition: log.h:288
#define LYD_VALUE_GET(value, type_val)
Get the value in format specific to the type.
Definition: tree_data.h:603
LIBYANG_API_DECL LY_ERR LIBYANG_API_DECL void ly_err_free(void *ptr)
Destructor for the error records created with ly_err_new().
Definition: log.h:259
struct lyplg_type_record plugins_union[]
Plugin information for union type implementation.
Definition: union.c:597
uint32_t hints
Definition: tree_data.h:620
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.
Definition: union.c:339
#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:624
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
const char * module
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.
Definition: tree.h:148
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_COUNT_TYPE
Type (i.e. size) of the sized array&#39;s size counter.
Definition: tree.h:104
Definition: log.h:265
struct lys_module * module
Definition: tree_schema.h:1418
#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:234
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.
LY_ERR
libyang&#39;s error codes returned by the libyang functions.
Definition: log.h:251
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.
Definition: union.c:391
lyplg_type_compare_clb compare
Special lyd_value structure for built-in union values.
Definition: tree_data.h:615
API for (user) types plugins.
LY_VALUE_FORMAT format
Definition: tree_data.h:621
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.
Definition: union.c:529
libyang context handler.
struct lyd_value value
Definition: tree_data.h:616
Definition: log.h:255