libyang  2.2.8
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 "compat.h"
28 #include "ly_common.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 
167 static LY_ERR
168 union_store_type(const struct ly_ctx *ctx, struct lysc_type *type, struct lyd_value_union *subvalue, uint32_t options,
169  ly_bool resolve, const struct lyd_node *ctx_node, const struct lyd_node *tree, struct lys_glob_unres *unres,
170  struct ly_err_item **err)
171 {
172  LY_ERR ret;
173  const void *value = NULL;
174  size_t value_len = 0;
175  uint32_t opts;
176 
177  *err = NULL;
178 
179  if (subvalue->format == LY_VALUE_LYB) {
180  lyb_parse_union(subvalue->original, subvalue->orig_len, NULL, &value, &value_len);
181  } else {
182  value = subvalue->original;
183  value_len = subvalue->orig_len;
184  }
185 
186  opts = (options & LYPLG_TYPE_STORE_ONLY) ? LYPLG_TYPE_STORE_ONLY : 0;
187  ret = type->plugin->store(ctx, type, value, value_len, opts, subvalue->format, subvalue->prefix_data, subvalue->hints,
188  subvalue->ctx_node, &subvalue->value, unres, err);
189  if ((ret != LY_SUCCESS) && (ret != LY_EINCOMPLETE)) {
190  /* clear any leftover/freed garbage */
191  memset(&subvalue->value, 0, sizeof subvalue->value);
192  return ret;
193  }
194 
195  if (resolve && (ret == LY_EINCOMPLETE)) {
196  /* we need the value resolved */
197  ret = type->plugin->validate(ctx, type, ctx_node, tree, &subvalue->value, err);
198  if (ret) {
199  /* resolve failed, we need to free the stored value */
200  type->plugin->free(ctx, &subvalue->value);
201  }
202  }
203 
204  return ret;
205 }
206 
222 static LY_ERR
223 union_find_type(const struct ly_ctx *ctx, struct lysc_type **types, struct lyd_value_union *subvalue,
224  uint32_t options, ly_bool resolve, const struct lyd_node *ctx_node, const struct lyd_node *tree,
225  uint32_t *type_idx, struct lys_glob_unres *unres, struct ly_err_item **err)
226 {
227  LY_ERR ret = LY_SUCCESS;
229  struct ly_err_item **errs = NULL, *e;
230  uint32_t *prev_lo, temp_lo = 0;
231  char *msg = NULL;
232  int msg_len = 0;
233 
234  *err = NULL;
235 
236  if (!types || !LY_ARRAY_COUNT(types)) {
237  return LY_EINVAL;
238  }
239 
240  /* alloc errors */
241  errs = calloc(LY_ARRAY_COUNT(types), sizeof *errs);
242  LY_CHECK_RET(!errs, LY_EMEM);
243 
244  /* turn logging temporarily off */
245  prev_lo = ly_temp_log_options(&temp_lo);
246 
247  /* use the first usable subtype to store the value */
248  for (u = 0; u < LY_ARRAY_COUNT(types); ++u) {
249  ret = union_store_type(ctx, types[u], subvalue, options, resolve, ctx_node, tree, unres, &e);
250  if ((ret == LY_SUCCESS) || (ret == LY_EINCOMPLETE)) {
251  break;
252  }
253 
254  errs[u] = e;
255  }
256 
257  if (u == LY_ARRAY_COUNT(types)) {
258  /* create the full error */
259  msg_len = asprintf(&msg, "Invalid union value \"%.*s\" - no matching subtype found:\n",
260  (int)subvalue->orig_len, (char *)subvalue->original);
261  if (msg_len == -1) {
262  LY_CHECK_ERR_GOTO(!errs, ret = LY_EMEM, cleanup);
263  }
264  for (u = 0; u < LY_ARRAY_COUNT(types); ++u) {
265  if (!errs[u]) {
266  /* no error for some reason */
267  continue;
268  }
269 
270  msg = ly_realloc(msg, msg_len + 4 + strlen(types[u]->plugin->id) + 2 + strlen(errs[u]->msg) + 2);
271  LY_CHECK_ERR_GOTO(!msg, ret = LY_EMEM, cleanup);
272  msg_len += sprintf(msg + msg_len, " %s: %s\n", types[u]->plugin->id, errs[u]->msg);
273  }
274 
275  ret = ly_err_new(err, LY_EVALID, LYVE_DATA, NULL, NULL, "%s", msg);
276  } else if (type_idx) {
277  *type_idx = u;
278  }
279 
280 cleanup:
281  for (u = 0; u < LY_ARRAY_COUNT(types); ++u) {
282  ly_err_free(errs[u]);
283  }
284  free(errs);
285  free(msg);
286  ly_temp_log_options(prev_lo);
287  return ret;
288 }
289 
304 static LY_ERR
305 lyb_fill_subvalue(const struct ly_ctx *ctx, struct lysc_type_union *type_u, const void *lyb_data, size_t lyb_data_len,
306  void *prefix_data, struct lyd_value_union *subvalue, uint32_t *options, struct lys_glob_unres *unres,
307  struct ly_err_item **err)
308 {
309  LY_ERR ret;
310  uint32_t type_idx;
311  const void *lyb_value = NULL;
312  size_t lyb_value_len = 0;
313 
314  ret = lyb_union_validate(lyb_data, lyb_data_len, type_u, err);
315  LY_CHECK_RET(ret);
316 
317  /* parse lyb_data and set the lyb_value and lyb_value_len */
318  lyb_parse_union(lyb_data, lyb_data_len, &type_idx, &lyb_value, &lyb_value_len);
319  LY_CHECK_RET(ret);
320 
321  /* store lyb_data to subvalue */
322  ret = union_subvalue_assignment(lyb_data, lyb_data_len, &subvalue->original, &subvalue->orig_len, options);
323  LY_CHECK_RET(ret);
324 
325  if (lyb_value) {
326  /* resolve prefix_data and set format */
327  ret = lyplg_type_prefix_data_new(ctx, lyb_value, lyb_value_len, LY_VALUE_LYB, prefix_data, &subvalue->format,
328  &subvalue->prefix_data);
329  LY_CHECK_RET(ret);
330  assert(subvalue->format == LY_VALUE_LYB);
331  } else {
332  /* lyb_parse_union() did not find lyb_value, just set format */
333  subvalue->format = LY_VALUE_LYB;
334  }
335 
336  /* use the specific type to store the value */
337  ret = union_store_type(ctx, type_u->types[type_idx], subvalue, *options, 0, NULL, NULL, unres, err);
338 
339  return ret;
340 }
341 
342 LIBYANG_API_DEF LY_ERR
343 lyplg_type_store_union(const struct ly_ctx *ctx, const struct lysc_type *type, const void *value, size_t value_len,
344  uint32_t options, LY_VALUE_FORMAT format, void *prefix_data, uint32_t hints, const struct lysc_node *ctx_node,
345  struct lyd_value *storage, struct lys_glob_unres *unres, struct ly_err_item **err)
346 {
347  LY_ERR ret = LY_SUCCESS, r;
348  struct lysc_type_union *type_u = (struct lysc_type_union *)type;
349  struct lyd_value_union *subvalue;
350 
351  *err = NULL;
352 
353  /* init storage */
354  memset(storage, 0, sizeof *storage);
355  LYPLG_TYPE_VAL_INLINE_PREPARE(storage, subvalue);
356  LY_CHECK_ERR_GOTO(!subvalue, ret = LY_EMEM, cleanup);
357  storage->realtype = type;
358  subvalue->hints = hints;
359  subvalue->ctx_node = ctx_node;
360 
361  if (format == LY_VALUE_LYB) {
362  ret = lyb_fill_subvalue(ctx, type_u, value, value_len, prefix_data, subvalue, &options, unres, err);
363  LY_CHECK_GOTO((ret != LY_SUCCESS) && (ret != LY_EINCOMPLETE), cleanup);
364  } else {
365  /* Store @p value to subvalue. */
366  ret = union_subvalue_assignment(value, value_len, &subvalue->original, &subvalue->orig_len, &options);
367  LY_CHECK_GOTO(ret, cleanup);
368 
369  /* store format-specific data for later prefix resolution */
370  ret = lyplg_type_prefix_data_new(ctx, value, value_len, format, prefix_data, &subvalue->format,
371  &subvalue->prefix_data);
372  LY_CHECK_GOTO(ret, cleanup);
373 
374  /* use the first usable subtype to store the value */
375  ret = union_find_type(ctx, type_u->types, subvalue, options, 0, NULL, NULL, NULL, unres, err);
376  LY_CHECK_GOTO((ret != LY_SUCCESS) && (ret != LY_EINCOMPLETE), cleanup);
377  }
378 
379  /* store canonical value, if any (use the specific type value) */
380  r = lydict_insert(ctx, subvalue->value._canonical, 0, &storage->_canonical);
381  LY_CHECK_ERR_GOTO(r, ret = r, cleanup);
382 
383 cleanup:
384  if (options & LYPLG_TYPE_STORE_DYNAMIC) {
385  free((void *)value);
386  }
387 
388  if ((ret != LY_SUCCESS) && (ret != LY_EINCOMPLETE)) {
389  lyplg_type_free_union(ctx, storage);
390  }
391  return ret;
392 }
393 
394 LIBYANG_API_DEF LY_ERR
395 lyplg_type_validate_union(const struct ly_ctx *ctx, const struct lysc_type *type, const struct lyd_node *ctx_node,
396  const struct lyd_node *tree, struct lyd_value *storage, struct ly_err_item **err)
397 {
398  LY_ERR ret = LY_SUCCESS;
399  struct lysc_type_union *type_u = (struct lysc_type_union *)type;
400  struct lyd_value_union *subvalue = storage->subvalue;
401  uint32_t type_idx;
402 
403  *err = NULL;
404 
405  /* because of types that do not store their own type as realtype (leafref), we are not able to call their
406  * validate callback (there is no way to get the type TODO could be added to struct lyd_value_union), so
407  * we have to perform union value storing again from scratch */
408  subvalue->value.realtype->plugin->free(ctx, &subvalue->value);
409 
410  if (subvalue->format == LY_VALUE_LYB) {
411  /* use the specific type to store the value */
412  lyb_parse_union(subvalue->original, 0, &type_idx, NULL, NULL);
413  ret = union_store_type(ctx, type_u->types[type_idx], subvalue, 0, 1, ctx_node, tree, NULL, err);
414  LY_CHECK_RET(ret);
415  } else {
416  /* use the first usable subtype to store the value */
417  ret = union_find_type(ctx, type_u->types, subvalue, 0, 1, ctx_node, tree, NULL, NULL, err);
418  LY_CHECK_RET(ret);
419  }
420 
421  /* success, update the canonical value, if any generated */
422  lydict_remove(ctx, storage->_canonical);
423  LY_CHECK_RET(lydict_insert(ctx, subvalue->value._canonical, 0, &storage->_canonical));
424  return LY_SUCCESS;
425 }
426 
427 LIBYANG_API_DEF LY_ERR
428 lyplg_type_compare_union(const struct ly_ctx *ctx, const struct lyd_value *val1, const struct lyd_value *val2)
429 {
430  if (val1->subvalue->value.realtype != val2->subvalue->value.realtype) {
431  return LY_ENOT;
432  }
433  return val1->subvalue->value.realtype->plugin->compare(ctx, &val1->subvalue->value, &val2->subvalue->value);
434 }
435 
436 LIBYANG_API_DEF int
437 lyplg_type_sort_union(const struct ly_ctx *ctx, const struct lyd_value *val1, const struct lyd_value *val2)
438 {
439  int ret;
441  struct lysc_type **types;
442 
443  if (val1->subvalue->value.realtype == val2->subvalue->value.realtype) {
444  return val1->subvalue->value.realtype->plugin->sort(ctx, &val1->subvalue->value, &val2->subvalue->value);
445  }
446 
447  /* compare according to the order of types */
448  ret = 0;
449  types = ((struct lysc_type_union *)val1->realtype)->types;
450  LY_ARRAY_FOR(types, u) {
451  if (types[u] == val1->subvalue->value.realtype) {
452  ret = 1;
453  break;
454  } else if (types[u] == val2->subvalue->value.realtype) {
455  ret = -1;
456  break;
457  }
458  }
459  assert(ret != 0);
460 
461  return ret;
462 }
463 
476 static const void *
477 lyb_union_print(const struct ly_ctx *ctx, struct lysc_type_union *type_u, struct lyd_value_union *subvalue,
478  void *prefix_data, size_t *value_len)
479 {
480  void *ret = NULL;
481  LY_ERR r;
482  struct ly_err_item *err;
483  uint64_t num = 0;
484  uint32_t type_idx = 0;
485  ly_bool dynamic;
486  size_t pval_len;
487  void *pval;
488 
489  /* Find out the index number (type_idx). The call should succeed
490  * because the union_find_type() has already been called in the
491  * lyplg_type_store_union().
492  */
493  if (!ctx) {
494  assert(subvalue->ctx_node);
495  ctx = subvalue->ctx_node->module->ctx;
496  }
497  subvalue->value.realtype->plugin->free(ctx, &subvalue->value);
498  r = union_find_type(ctx, type_u->types, subvalue, 0, 0, NULL, NULL, &type_idx, NULL, &err);
499  ly_err_free(err);
500  LY_CHECK_RET((r != LY_SUCCESS) && (r != LY_EINCOMPLETE), NULL);
501 
502  /* Print subvalue in LYB format. */
503  pval = (void *)subvalue->value.realtype->plugin->print(NULL, &subvalue->value, LY_VALUE_LYB, prefix_data, &dynamic,
504  &pval_len);
505  LY_CHECK_RET(!pval, NULL);
506 
507  /* Create LYB data. */
508  *value_len = IDX_SIZE + pval_len;
509  ret = malloc(*value_len);
510  LY_CHECK_RET(!ret, NULL);
511 
512  num = type_idx;
513  num = htole64(num);
514  memcpy(ret, &num, IDX_SIZE);
515  memcpy((char *)ret + IDX_SIZE, pval, pval_len);
516 
517  if (dynamic) {
518  free(pval);
519  }
520 
521  return ret;
522 }
523 
524 LIBYANG_API_DEF const void *
525 lyplg_type_print_union(const struct ly_ctx *ctx, const struct lyd_value *value, LY_VALUE_FORMAT format,
526  void *prefix_data, ly_bool *dynamic, size_t *value_len)
527 {
528  const void *ret;
529  struct lyd_value_union *subvalue = value->subvalue;
530  struct lysc_type_union *type_u = (struct lysc_type_union *)value->realtype;
531  size_t lyb_data_len = 0;
532 
533  if ((format == LY_VALUE_LYB) && (subvalue->format == LY_VALUE_LYB)) {
534  /* The return value is already ready. */
535  *dynamic = 0;
536  if (value_len) {
537  *value_len = subvalue->orig_len;
538  }
539  return subvalue->original;
540  } else if ((format == LY_VALUE_LYB) && (subvalue->format != LY_VALUE_LYB)) {
541  /* The return LYB data must be created. */
542  *dynamic = 1;
543  ret = lyb_union_print(ctx, type_u, subvalue, prefix_data, &lyb_data_len);
544  if (value_len) {
545  *value_len = lyb_data_len;
546  }
547  return ret;
548  }
549 
550  assert(format != LY_VALUE_LYB);
551  ret = (void *)subvalue->value.realtype->plugin->print(ctx, &subvalue->value, format, prefix_data, dynamic, value_len);
552  if (!value->_canonical && (format == LY_VALUE_CANON)) {
553  /* the canonical value is supposed to be stored now */
554  lydict_insert(ctx, subvalue->value._canonical, 0, (const char **)&value->_canonical);
555  }
556 
557  return ret;
558 }
559 
560 LIBYANG_API_DEF LY_ERR
561 lyplg_type_dup_union(const struct ly_ctx *ctx, const struct lyd_value *original, struct lyd_value *dup)
562 {
563  LY_ERR ret = LY_SUCCESS;
564  struct lyd_value_union *orig_val = original->subvalue, *dup_val;
565 
566  /* init dup value */
567  memset(dup, 0, sizeof *dup);
568  dup->realtype = original->realtype;
569 
570  ret = lydict_insert(ctx, original->_canonical, 0, &dup->_canonical);
571  LY_CHECK_GOTO(ret, cleanup);
572 
573  dup_val = calloc(1, sizeof *dup_val);
574  LY_CHECK_ERR_GOTO(!dup_val, LOGMEM(ctx); ret = LY_EMEM, cleanup);
575  dup->subvalue = dup_val;
576 
577  ret = orig_val->value.realtype->plugin->duplicate(ctx, &orig_val->value, &dup_val->value);
578  LY_CHECK_GOTO(ret, cleanup);
579 
580  if (orig_val->orig_len) {
581  dup_val->original = calloc(1, orig_val->orig_len);
582  LY_CHECK_ERR_GOTO(!dup_val->original, LOGMEM(ctx); ret = LY_EMEM, cleanup);
583  memcpy(dup_val->original, orig_val->original, orig_val->orig_len);
584  } else {
585  dup_val->original = strdup("");
586  LY_CHECK_ERR_GOTO(!dup_val->original, LOGMEM(ctx); ret = LY_EMEM, cleanup);
587  }
588  dup_val->orig_len = orig_val->orig_len;
589 
590  dup_val->format = orig_val->format;
591  dup_val->ctx_node = orig_val->ctx_node;
592  dup_val->hints = orig_val->hints;
593  ret = lyplg_type_prefix_data_dup(ctx, orig_val->format, orig_val->prefix_data, &dup_val->prefix_data);
594  LY_CHECK_GOTO(ret, cleanup);
595 
596 cleanup:
597  if (ret) {
598  lyplg_type_free_union(ctx, dup);
599  }
600  return ret;
601 }
602 
603 LIBYANG_API_DEF void
604 lyplg_type_free_union(const struct ly_ctx *ctx, struct lyd_value *value)
605 {
606  struct lyd_value_union *val;
607 
608  lydict_remove(ctx, value->_canonical);
609  value->_canonical = NULL;
610  LYD_VALUE_GET(value, val);
611  if (val) {
612  if (val->value.realtype) {
613  val->value.realtype->plugin->free(ctx, &val->value);
614  }
616  free(val->original);
617 
619  }
620 }
621 
630  {
631  .module = "",
632  .revision = NULL,
633  .name = LY_TYPE_UNION_STR,
634 
635  .plugin.id = "libyang 2 - union,version 1",
636  .plugin.store = lyplg_type_store_union,
637  .plugin.validate = lyplg_type_validate_union,
638  .plugin.compare = lyplg_type_compare_union,
639  .plugin.sort = lyplg_type_sort_union,
640  .plugin.print = lyplg_type_print_union,
641  .plugin.duplicate = lyplg_type_dup_union,
642  .plugin.free = lyplg_type_free_union,
643  .plugin.lyb_data_len = -1,
644  },
645  {0}
646 };
struct lysc_type * realtype
Definition: tree_data.h:575
Compiled YANG data node.
Definition: tree_schema.h:1439
#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:2132
memset(value->fixed_mem, 0, LYD_VALUE_FIXED_MEM_SIZE)
struct lyplg_type * plugin
Definition: tree_schema.h:1304
Definition: log.h:244
Generic structure for a data node.
Definition: tree_data.h:799
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.
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:525
Definition: log.h:242
LY_ERR err
Definition: log.h:287
#define LYPLG_TYPE_STORE_DYNAMIC
void * original
Definition: tree_data.h:629
size_t orig_len
Definition: tree_data.h:630
#define LOGMEM(CTX)
Definition: tree_edit.h:22
char * msg
Definition: log.h:289
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:604
struct lysc_node * ctx_node
Definition: tree_data.h:636
struct lysc_type ** types
Definition: tree_schema.h:1418
LYPLG_TYPE_VAL_INLINE_DESTROY(val)
The main libyang public header.
YANG data representation.
Definition: tree_data.h:571
const char * _canonical
Definition: tree_data.h:572
lyplg_type_store_clb store
Libyang full error structure.
Definition: log.h:285
Definition: log.h:277
#define LYD_VALUE_GET(value, type_val)
Get the value in format specific to the type.
Definition: tree_data.h:614
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.
Definition: union.c:629
uint32_t hints
Definition: tree_data.h:631
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:343
#define IDX_SIZE
Size in bytes of the index in the LYB Binary Format.
Definition: union.c:46
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.
Definition: union.c:428
void * prefix_data
Definition: tree_data.h:635
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
lyplg_type_sort_clb sort
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.
Definition: union.c:437
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).
Definition: tree.h:167
#define LY_ARRAY_COUNT_TYPE
Type (i.e. size) of the sized array&#39;s size counter.
Definition: tree.h:104
struct lys_module * module
Definition: tree_schema.h:1443
if((v1->size!=v2->size)||memcmp(v1->data, v2->data, v1->size))
Definition: binary.c:372
LY_VALUE_FORMAT
All kinds of supported value formats and prefix mappings to modules.
Definition: tree.h:234
lyplg_type_print_clb print
Definition: log.h:248
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.
Definition: union.c:395
lyplg_type_compare_clb compare
Special lyd_value structure for built-in union values.
Definition: tree_data.h:626
API for (user) types plugins.
LY_VALUE_FORMAT format
Definition: tree_data.h:632
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:561
LY_ERR
libyang&#39;s error codes returned by the libyang functions.
Definition: log.h:240
libyang context handler.
struct lyd_value value
Definition: tree_data.h:627
#define LYPLG_TYPE_STORE_ONLY
Definition: log.h:254
assert(!value->_canonical)