libyang  3.4.2
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 TYPE_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 < TYPE_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, TYPE_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, TYPE_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 == TYPE_IDX_SIZE) {
144  *lyb_value_len = 0;
145  *lyb_value = "";
146  } else {
147  *lyb_value_len = lyb_data_len - TYPE_IDX_SIZE;
148  *lyb_value = (char *)lyb_data + TYPE_IDX_SIZE;
149  }
150  }
151 }
152 
168 static LY_ERR
169 union_store_type(const struct ly_ctx *ctx, struct lysc_type_union *type_u, uint32_t type_idx, struct lyd_value_union *subvalue,
170  uint32_t options, ly_bool validate, const struct lyd_node *ctx_node, const struct lyd_node *tree,
171  struct lys_glob_unres *unres, struct ly_err_item **err)
172 {
173  LY_ERR rc = LY_SUCCESS;
174  struct lysc_type *type = type_u->types[type_idx];
175  const void *value = NULL;
176  size_t value_len = 0;
177  ly_bool dynamic = 0;
178  LY_VALUE_FORMAT format;
179  void *prefix_data;
180  uint32_t opts = 0, ti;
181 
182  *err = NULL;
183 
184  if (subvalue->format == LY_VALUE_LYB) {
185  lyb_parse_union(subvalue->original, subvalue->orig_len, &ti, &value, &value_len);
186  if (ti != type_idx) {
187  /* value of another type, first store the value properly and then use its JSON value for parsing */
188  rc = type_u->types[ti]->plugin->store(ctx, type_u->types[ti], value, value_len, LYPLG_TYPE_STORE_ONLY,
189  subvalue->format, subvalue->prefix_data, subvalue->hints, subvalue->ctx_node, &subvalue->value, unres, err);
190  if ((rc != LY_SUCCESS) && (rc != LY_EINCOMPLETE)) {
191  /* clear any leftover/freed garbage */
192  memset(&subvalue->value, 0, sizeof subvalue->value);
193  return rc;
194  }
195 
196  assert(subvalue->value.realtype);
197  value = subvalue->value.realtype->plugin->print(ctx, &subvalue->value, LY_VALUE_JSON, NULL, &dynamic, &value_len);
198 
199  /* to avoid leaks, free subvalue->value, but we need the value, which may be stored there */
200  if (!dynamic) {
201  value = strndup(value, value_len);
202  dynamic = 1;
203  }
204  type_u->types[ti]->plugin->free(ctx, &subvalue->value);
205 
206  format = LY_VALUE_JSON;
207  prefix_data = NULL;
208  } else {
209  format = subvalue->format;
210  prefix_data = subvalue->prefix_data;
211  }
212  } else {
213  value = subvalue->original;
214  value_len = subvalue->orig_len;
215  format = subvalue->format;
216  prefix_data = subvalue->prefix_data;
217  }
218 
219  if (options & LYPLG_TYPE_STORE_ONLY) {
220  opts |= LYPLG_TYPE_STORE_ONLY;
221  }
222  if (dynamic) {
223  opts |= LYPLG_TYPE_STORE_DYNAMIC;
224  }
225 
226  rc = type->plugin->store(ctx, type, value, value_len, opts, format, prefix_data, subvalue->hints,
227  subvalue->ctx_node, &subvalue->value, unres, err);
228  if ((rc != LY_SUCCESS) && (rc != LY_EINCOMPLETE)) {
229  /* clear any leftover/freed garbage */
230  memset(&subvalue->value, 0, sizeof subvalue->value);
231  return rc;
232  }
233 
234  if (validate && (rc == LY_EINCOMPLETE)) {
235  /* we need the value validated */
236  rc = type->plugin->validate(ctx, type, ctx_node, tree, &subvalue->value, err);
237  if (rc) {
238  /* validate failed, we need to free the stored value */
239  type->plugin->free(ctx, &subvalue->value);
240  }
241  }
242 
243  return rc;
244 }
245 
261 static LY_ERR
262 union_find_type(const struct ly_ctx *ctx, struct lysc_type_union *type_u, struct lyd_value_union *subvalue,
263  uint32_t options, ly_bool resolve, const struct lyd_node *ctx_node, const struct lyd_node *tree,
264  uint32_t *type_idx, struct lys_glob_unres *unres, struct ly_err_item **err)
265 {
266  LY_ERR ret = LY_SUCCESS;
268  struct ly_err_item **errs = NULL, *e;
269  uint32_t *prev_lo, temp_lo = 0;
270  char *msg = NULL;
271  int msg_len = 0;
272 
273  *err = NULL;
274 
275  /* alloc errors */
276  errs = calloc(LY_ARRAY_COUNT(type_u->types), sizeof *errs);
277  LY_CHECK_RET(!errs, LY_EMEM);
278 
279  /* turn logging temporarily off */
280  prev_lo = ly_temp_log_options(&temp_lo);
281 
282  /* use the first usable subtype to store the value */
283  for (u = 0; u < LY_ARRAY_COUNT(type_u->types); ++u) {
284  ret = union_store_type(ctx, type_u, u, subvalue, options, resolve, ctx_node, tree, unres, &e);
285  if ((ret == LY_SUCCESS) || (ret == LY_EINCOMPLETE)) {
286  break;
287  }
288 
289  errs[u] = e;
290  }
291 
292  if (u == LY_ARRAY_COUNT(type_u->types)) {
293  /* create the full error */
294  if (subvalue->format == LY_VALUE_LYB) {
295  msg_len = asprintf(&msg, "Invalid LYB union value - no matching subtype found:\n");
296  } else {
297  msg_len = asprintf(&msg, "Invalid union value \"%.*s\" - no matching subtype found:\n",
298  (int)subvalue->orig_len, (char *)subvalue->original);
299  }
300  if (msg_len == -1) {
301  LY_CHECK_ERR_GOTO(!errs, ret = LY_EMEM, cleanup);
302  }
303  for (u = 0; u < LY_ARRAY_COUNT(type_u->types); ++u) {
304  if (!errs[u]) {
305  /* no error for some reason */
306  continue;
307  }
308 
309  msg = ly_realloc(msg, msg_len + 4 + strlen(type_u->types[u]->plugin->id) + 2 + strlen(errs[u]->msg) + 2);
310  LY_CHECK_ERR_GOTO(!msg, ret = LY_EMEM, cleanup);
311  msg_len += sprintf(msg + msg_len, " %s: %s\n", type_u->types[u]->plugin->id, errs[u]->msg);
312  }
313 
314  ret = ly_err_new(err, LY_EVALID, LYVE_DATA, NULL, NULL, "%s", msg);
315  } else if (type_idx) {
316  *type_idx = u;
317  }
318 
319 cleanup:
320  for (u = 0; u < LY_ARRAY_COUNT(type_u->types); ++u) {
321  ly_err_free(errs[u]);
322  }
323  free(errs);
324  free(msg);
325  ly_temp_log_options(prev_lo);
326  return ret;
327 }
328 
343 static LY_ERR
344 lyb_fill_subvalue(const struct ly_ctx *ctx, struct lysc_type_union *type_u, const void *lyb_data, size_t lyb_data_len,
345  void *prefix_data, struct lyd_value_union *subvalue, uint32_t *options, struct lys_glob_unres *unres,
346  struct ly_err_item **err)
347 {
348  LY_ERR ret;
349  uint32_t type_idx;
350  const void *lyb_value = NULL;
351  size_t lyb_value_len = 0;
352 
353  ret = lyb_union_validate(lyb_data, lyb_data_len, type_u, err);
354  LY_CHECK_RET(ret);
355 
356  /* parse lyb_data and set the lyb_value and lyb_value_len */
357  lyb_parse_union(lyb_data, lyb_data_len, &type_idx, &lyb_value, &lyb_value_len);
358  LY_CHECK_RET(ret);
359 
360  /* store lyb_data to subvalue */
361  ret = union_subvalue_assignment(lyb_data, lyb_data_len, &subvalue->original, &subvalue->orig_len, options);
362  LY_CHECK_RET(ret);
363 
364  if (lyb_value) {
365  /* resolve prefix_data and set format */
366  ret = lyplg_type_prefix_data_new(ctx, lyb_value, lyb_value_len, LY_VALUE_LYB, prefix_data, &subvalue->format,
367  &subvalue->prefix_data);
368  LY_CHECK_RET(ret);
369  assert(subvalue->format == LY_VALUE_LYB);
370  } else {
371  /* lyb_parse_union() did not find lyb_value, just set format */
372  subvalue->format = LY_VALUE_LYB;
373  }
374 
375  /* use the specific type to store the value */
376  ret = union_store_type(ctx, type_u, type_idx, subvalue, *options, 0, NULL, NULL, unres, err);
377 
378  return ret;
379 }
380 
381 LIBYANG_API_DEF LY_ERR
382 lyplg_type_store_union(const struct ly_ctx *ctx, const struct lysc_type *type, const void *value, size_t value_len,
383  uint32_t options, LY_VALUE_FORMAT format, void *prefix_data, uint32_t hints, const struct lysc_node *ctx_node,
384  struct lyd_value *storage, struct lys_glob_unres *unres, struct ly_err_item **err)
385 {
386  LY_ERR ret = LY_SUCCESS, r;
387  struct lysc_type_union *type_u = (struct lysc_type_union *)type;
388  struct lyd_value_union *subvalue;
389 
390  *err = NULL;
391 
392  /* init storage */
393  memset(storage, 0, sizeof *storage);
394  LYPLG_TYPE_VAL_INLINE_PREPARE(storage, subvalue);
395  LY_CHECK_ERR_GOTO(!subvalue, ret = LY_EMEM, cleanup);
396  storage->realtype = type;
397  subvalue->hints = hints;
398  subvalue->ctx_node = ctx_node;
399 
400  if (format == LY_VALUE_LYB) {
401  ret = lyb_fill_subvalue(ctx, type_u, value, value_len, prefix_data, subvalue, &options, unres, err);
402  LY_CHECK_GOTO((ret != LY_SUCCESS) && (ret != LY_EINCOMPLETE), cleanup);
403  } else {
404  /* store value to subvalue */
405  ret = union_subvalue_assignment(value, value_len, &subvalue->original, &subvalue->orig_len, &options);
406  LY_CHECK_GOTO(ret, cleanup);
407 
408  /* store format-specific data for later prefix resolution */
409  ret = lyplg_type_prefix_data_new(ctx, value, value_len, format, prefix_data, &subvalue->format,
410  &subvalue->prefix_data);
411  LY_CHECK_GOTO(ret, cleanup);
412 
413  /* use the first usable subtype to store the value */
414  ret = union_find_type(ctx, type_u, subvalue, options, 0, NULL, NULL, NULL, unres, err);
415  LY_CHECK_GOTO((ret != LY_SUCCESS) && (ret != LY_EINCOMPLETE), cleanup);
416  }
417 
418  /* store canonical value, if any (use the specific type value) */
419  r = lydict_insert(ctx, subvalue->value._canonical, 0, &storage->_canonical);
420  LY_CHECK_ERR_GOTO(r, ret = r, cleanup);
421 
422 cleanup:
423  if (options & LYPLG_TYPE_STORE_DYNAMIC) {
424  free((void *)value);
425  }
426 
427  if ((ret != LY_SUCCESS) && (ret != LY_EINCOMPLETE)) {
428  lyplg_type_free_union(ctx, storage);
429  }
430  return ret;
431 }
432 
433 LIBYANG_API_DEF LY_ERR
434 lyplg_type_validate_union(const struct ly_ctx *ctx, const struct lysc_type *type, const struct lyd_node *ctx_node,
435  const struct lyd_node *tree, struct lyd_value *storage, struct ly_err_item **err)
436 {
437  LY_ERR rc = LY_SUCCESS;
438  struct lysc_type_union *type_u = (struct lysc_type_union *)type;
439  struct lyd_value_union *subvalue = storage->subvalue;
440  struct lyd_value orig = {0};
441  uint32_t type_idx;
442  ly_bool validated = 0;
443 
444  *err = NULL;
445 
446  /* because of types that do not store their own type as realtype (leafref), we are not able to call their
447  * validate callback (there is no way to get the type) but even if possible, the value may be invalid
448  * for the type, so we may have to perform union value storing again from scratch, but keep a value backup */
449  LY_CHECK_RET(subvalue->value.realtype->plugin->duplicate(ctx, &subvalue->value, &orig));
450  subvalue->value.realtype->plugin->free(ctx, &subvalue->value);
451 
452  if (subvalue->format == LY_VALUE_LYB) {
453  /* use the specific type to store and validate the value */
454  lyb_parse_union(subvalue->original, 0, &type_idx, NULL, NULL);
455 
456  if (union_store_type(ctx, type_u, type_idx, subvalue, 0, 1, ctx_node, tree, NULL, err)) {
457  /* validation failed, we need to try storing the value again */
458  ly_err_free(*err);
459  *err = NULL;
460  } else {
461  validated = 1;
462  }
463  }
464 
465  if (!validated) {
466  /* use the first usable subtype to store and validate the value */
467  rc = union_find_type(ctx, type_u, subvalue, 0, 1, ctx_node, tree, NULL, NULL, err);
468  if (rc) {
469  /* validation failed, restore the previous value */
470  subvalue->value = orig;
471  return rc;
472  }
473  }
474 
475  /* update the canonical value, if any generated */
476  lydict_remove(ctx, storage->_canonical);
477  LY_CHECK_RET(lydict_insert(ctx, subvalue->value._canonical, 0, &storage->_canonical));
478 
479  /* free backup value */
480  orig.realtype->plugin->free(ctx, &orig);
481  return LY_SUCCESS;
482 }
483 
484 LIBYANG_API_DEF LY_ERR
485 lyplg_type_compare_union(const struct ly_ctx *ctx, const struct lyd_value *val1, const struct lyd_value *val2)
486 {
487  if (val1->subvalue->value.realtype != val2->subvalue->value.realtype) {
488  return LY_ENOT;
489  }
490  return val1->subvalue->value.realtype->plugin->compare(ctx, &val1->subvalue->value, &val2->subvalue->value);
491 }
492 
493 LIBYANG_API_DEF int
494 lyplg_type_sort_union(const struct ly_ctx *ctx, const struct lyd_value *val1, const struct lyd_value *val2)
495 {
496  int rc = LY_SUCCESS;
498  struct lysc_type **types;
499 
500  if (val1->subvalue->value.realtype == val2->subvalue->value.realtype) {
501  return val1->subvalue->value.realtype->plugin->sort(ctx, &val1->subvalue->value, &val2->subvalue->value);
502  }
503 
504  /* compare according to the order of types */
505  types = ((struct lysc_type_union *)val1->realtype)->types;
506  LY_ARRAY_FOR(types, u) {
507  if (types[u] == val1->subvalue->value.realtype) {
508  rc = 1;
509  break;
510  } else if (types[u] == val2->subvalue->value.realtype) {
511  rc = -1;
512  break;
513  }
514  }
515  assert(rc != 0);
516 
517  return rc;
518 }
519 
532 static const void *
533 lyb_union_print(const struct ly_ctx *ctx, struct lysc_type_union *type_u, struct lyd_value_union *subvalue,
534  void *prefix_data, size_t *value_len)
535 {
536  void *ret = NULL;
537  LY_ERR r;
538  struct ly_err_item *err;
539  uint64_t num = 0;
540  uint32_t type_idx = 0;
541  ly_bool dynamic;
542  size_t pval_len;
543  void *pval;
544 
545  /* Find out the index number (type_idx). The call should succeed
546  * because the union_find_type() has already been called in the
547  * lyplg_type_store_union().
548  */
549  if (!ctx) {
550  assert(subvalue->ctx_node);
551  ctx = subvalue->ctx_node->module->ctx;
552  }
553  subvalue->value.realtype->plugin->free(ctx, &subvalue->value);
554  r = union_find_type(ctx, type_u, subvalue, 0, 0, NULL, NULL, &type_idx, NULL, &err);
555  ly_err_free(err);
556  LY_CHECK_RET((r != LY_SUCCESS) && (r != LY_EINCOMPLETE), NULL);
557 
558  /* Print subvalue in LYB format. */
559  pval = (void *)subvalue->value.realtype->plugin->print(NULL, &subvalue->value, LY_VALUE_LYB, prefix_data, &dynamic,
560  &pval_len);
561  LY_CHECK_RET(!pval, NULL);
562 
563  /* Create LYB data. */
564  *value_len = TYPE_IDX_SIZE + pval_len;
565  ret = malloc(*value_len);
566  LY_CHECK_RET(!ret, NULL);
567 
568  num = type_idx;
569  num = htole64(num);
570  memcpy(ret, &num, TYPE_IDX_SIZE);
571  memcpy((char *)ret + TYPE_IDX_SIZE, pval, pval_len);
572 
573  if (dynamic) {
574  free(pval);
575  }
576 
577  return ret;
578 }
579 
580 LIBYANG_API_DEF const void *
581 lyplg_type_print_union(const struct ly_ctx *ctx, const struct lyd_value *value, LY_VALUE_FORMAT format,
582  void *prefix_data, ly_bool *dynamic, size_t *value_len)
583 {
584  const void *ret;
585  struct lyd_value_union *subvalue = value->subvalue;
586  struct lysc_type_union *type_u = (struct lysc_type_union *)value->realtype;
587  size_t lyb_data_len = 0;
588 
589  if ((format == LY_VALUE_LYB) && (subvalue->format == LY_VALUE_LYB)) {
590  /* The return value is already ready. */
591  *dynamic = 0;
592  if (value_len) {
593  *value_len = subvalue->orig_len;
594  }
595  return subvalue->original;
596  } else if ((format == LY_VALUE_LYB) && (subvalue->format != LY_VALUE_LYB)) {
597  /* The return LYB data must be created. */
598  *dynamic = 1;
599  ret = lyb_union_print(ctx, type_u, subvalue, prefix_data, &lyb_data_len);
600  if (value_len) {
601  *value_len = lyb_data_len;
602  }
603  return ret;
604  }
605 
606  assert(format != LY_VALUE_LYB);
607  ret = (void *)subvalue->value.realtype->plugin->print(ctx, &subvalue->value, format, prefix_data, dynamic, value_len);
608  if (!value->_canonical && (format == LY_VALUE_CANON)) {
609  /* the canonical value is supposed to be stored now */
610  lydict_insert(ctx, subvalue->value._canonical, 0, (const char **)&value->_canonical);
611  }
612 
613  return ret;
614 }
615 
616 LIBYANG_API_DEF LY_ERR
617 lyplg_type_dup_union(const struct ly_ctx *ctx, const struct lyd_value *original, struct lyd_value *dup)
618 {
619  LY_ERR ret = LY_SUCCESS;
620  struct lyd_value_union *orig_val = original->subvalue, *dup_val;
621 
622  /* init dup value */
623  memset(dup, 0, sizeof *dup);
624  dup->realtype = original->realtype;
625 
626  ret = lydict_insert(ctx, original->_canonical, 0, &dup->_canonical);
627  LY_CHECK_GOTO(ret, cleanup);
628 
629  dup_val = calloc(1, sizeof *dup_val);
630  LY_CHECK_ERR_GOTO(!dup_val, LOGMEM(ctx); ret = LY_EMEM, cleanup);
631  dup->subvalue = dup_val;
632 
633  ret = orig_val->value.realtype->plugin->duplicate(ctx, &orig_val->value, &dup_val->value);
634  LY_CHECK_GOTO(ret, cleanup);
635 
636  if (orig_val->orig_len) {
637  dup_val->original = calloc(1, orig_val->orig_len);
638  LY_CHECK_ERR_GOTO(!dup_val->original, LOGMEM(ctx); ret = LY_EMEM, cleanup);
639  memcpy(dup_val->original, orig_val->original, orig_val->orig_len);
640  } else {
641  dup_val->original = strdup("");
642  LY_CHECK_ERR_GOTO(!dup_val->original, LOGMEM(ctx); ret = LY_EMEM, cleanup);
643  }
644  dup_val->orig_len = orig_val->orig_len;
645 
646  dup_val->format = orig_val->format;
647  dup_val->ctx_node = orig_val->ctx_node;
648  dup_val->hints = orig_val->hints;
649  ret = lyplg_type_prefix_data_dup(ctx, orig_val->format, orig_val->prefix_data, &dup_val->prefix_data);
650  LY_CHECK_GOTO(ret, cleanup);
651 
652 cleanup:
653  if (ret) {
654  lyplg_type_free_union(ctx, dup);
655  }
656  return ret;
657 }
658 
659 LIBYANG_API_DEF void
660 lyplg_type_free_union(const struct ly_ctx *ctx, struct lyd_value *value)
661 {
662  struct lyd_value_union *val;
663 
664  lydict_remove(ctx, value->_canonical);
665  value->_canonical = NULL;
666  LYD_VALUE_GET(value, val);
667  if (val) {
668  if (val->value.realtype) {
669  val->value.realtype->plugin->free(ctx, &val->value);
670  }
672  free(val->original);
673 
675  }
676 }
677 
686  {
687  .module = "",
688  .revision = NULL,
689  .name = LY_TYPE_UNION_STR,
690 
691  .plugin.id = "libyang 2 - union,version 1",
692  .plugin.store = lyplg_type_store_union,
693  .plugin.validate = lyplg_type_validate_union,
694  .plugin.compare = lyplg_type_compare_union,
695  .plugin.sort = lyplg_type_sort_union,
696  .plugin.print = lyplg_type_print_union,
697  .plugin.duplicate = lyplg_type_dup_union,
698  .plugin.free = lyplg_type_free_union,
699  .plugin.lyb_data_len = -1,
700  },
701  {0}
702 };
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)
const char * id
struct lyplg_type * plugin
Definition: tree_schema.h:1304
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:581
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:660
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:685
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:382
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:485
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:494
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:349
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:434
#define TYPE_IDX_SIZE
Size in bytes of the used type index in the LYB Binary Format.
Definition: union.c:46
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:617
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)