libyang  2.1.148
libyang is YANG data modelling language parser and toolkit written (and providing API) in C.
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 
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 };
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_DEF 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
const struct lysc_node * ctx_node
Definition: tree_data.h:625
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_DEF 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_DEF 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_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
const struct lysc_type * realtype
Definition: tree_data.h:564
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
const 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_DEF 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_DEF 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_DEF 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