libyang 3.7.8
libyang is YANG data modelling language parser and toolkit written (and providing API) in C.
Loading...
Searching...
No Matches
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
58static LY_ERR
59union_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
91static LY_ERR
92lyb_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
127static void
128lyb_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
168static LY_ERR
169union_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) {
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
261static LY_ERR
262union_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
319cleanup:
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
343static LY_ERR
344lyb_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
381LIBYANG_API_DEF LY_ERR
382lyplg_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 /* to correctly resolve the union type, we need to always validate the value */
405 options &= ~LYPLG_TYPE_STORE_ONLY;
406
407 /* store value to subvalue */
408 ret = union_subvalue_assignment(value, value_len, &subvalue->original, &subvalue->orig_len, &options);
409 LY_CHECK_GOTO(ret, cleanup);
410
411 /* store format-specific data for later prefix resolution */
412 ret = lyplg_type_prefix_data_new(ctx, value, value_len, format, prefix_data, &subvalue->format,
413 &subvalue->prefix_data);
414 LY_CHECK_GOTO(ret, cleanup);
415
416 /* use the first usable subtype to store the value */
417 ret = union_find_type(ctx, type_u, subvalue, options, 0, NULL, NULL, NULL, unres, err);
418 LY_CHECK_GOTO((ret != LY_SUCCESS) && (ret != LY_EINCOMPLETE), cleanup);
419 }
420
421 /* store canonical value, if any (use the specific type value) */
422 r = lydict_insert(ctx, subvalue->value._canonical, 0, &storage->_canonical);
423 LY_CHECK_ERR_GOTO(r, ret = r, cleanup);
424
425cleanup:
426 if (options & LYPLG_TYPE_STORE_DYNAMIC) {
427 free((void *)value);
428 }
429
430 if ((ret != LY_SUCCESS) && (ret != LY_EINCOMPLETE)) {
431 lyplg_type_free_union(ctx, storage);
432 }
433 return ret;
434}
435
436LIBYANG_API_DEF LY_ERR
437lyplg_type_validate_union(const struct ly_ctx *ctx, const struct lysc_type *type, const struct lyd_node *ctx_node,
438 const struct lyd_node *tree, struct lyd_value *storage, struct ly_err_item **err)
439{
440 LY_ERR rc = LY_SUCCESS;
441 struct lysc_type_union *type_u = (struct lysc_type_union *)type;
442 struct lyd_value_union *subvalue = storage->subvalue;
443 struct lyd_value orig = {0};
444 uint32_t type_idx;
445 ly_bool validated = 0;
446
447 *err = NULL;
448
449 /* because of types that do not store their own type as realtype (leafref), we are not able to call their
450 * validate callback (there is no way to get the type) but even if possible, the value may be invalid
451 * for the type, so we may have to perform union value storing again from scratch, but keep a value backup */
452 LY_CHECK_RET(subvalue->value.realtype->plugin->duplicate(ctx, &subvalue->value, &orig));
453 subvalue->value.realtype->plugin->free(ctx, &subvalue->value);
454
455 if (subvalue->format == LY_VALUE_LYB) {
456 /* use the specific type to store and validate the value */
457 lyb_parse_union(subvalue->original, 0, &type_idx, NULL, NULL);
458
459 if (union_store_type(ctx, type_u, type_idx, subvalue, 0, 1, ctx_node, tree, NULL, err)) {
460 /* validation failed, we need to try storing the value again */
461 ly_err_free(*err);
462 *err = NULL;
463 } else {
464 validated = 1;
465 }
466 }
467
468 if (!validated) {
469 /* use the first usable subtype to store and validate the value */
470 rc = union_find_type(ctx, type_u, subvalue, 0, 1, ctx_node, tree, NULL, NULL, err);
471 if (rc) {
472 /* validation failed, restore the previous value */
473 subvalue->value = orig;
474 return rc;
475 }
476 }
477
478 /* update the canonical value, if any generated */
479 lydict_remove(ctx, storage->_canonical);
480 LY_CHECK_RET(lydict_insert(ctx, subvalue->value._canonical, 0, &storage->_canonical));
481
482 /* free backup value */
483 orig.realtype->plugin->free(ctx, &orig);
484 return LY_SUCCESS;
485}
486
487LIBYANG_API_DEF LY_ERR
488lyplg_type_compare_union(const struct ly_ctx *ctx, const struct lyd_value *val1, const struct lyd_value *val2)
489{
490 if (val1->subvalue->value.realtype != val2->subvalue->value.realtype) {
491 return LY_ENOT;
492 }
493 return val1->subvalue->value.realtype->plugin->compare(ctx, &val1->subvalue->value, &val2->subvalue->value);
494}
495
496LIBYANG_API_DEF int
497lyplg_type_sort_union(const struct ly_ctx *ctx, const struct lyd_value *val1, const struct lyd_value *val2)
498{
499 int rc = LY_SUCCESS;
501 struct lysc_type **types;
502
503 if (val1->subvalue->value.realtype == val2->subvalue->value.realtype) {
504 return val1->subvalue->value.realtype->plugin->sort(ctx, &val1->subvalue->value, &val2->subvalue->value);
505 }
506
507 /* compare according to the order of types */
508 types = ((struct lysc_type_union *)val1->realtype)->types;
509 LY_ARRAY_FOR(types, u) {
510 if (types[u] == val1->subvalue->value.realtype) {
511 rc = 1;
512 break;
513 } else if (types[u] == val2->subvalue->value.realtype) {
514 rc = -1;
515 break;
516 }
517 }
518 assert(rc != 0);
519
520 return rc;
521}
522
535static const void *
536lyb_union_print(const struct ly_ctx *ctx, struct lysc_type_union *type_u, struct lyd_value_union *subvalue,
537 void *prefix_data, size_t *value_len)
538{
539 void *ret = NULL;
540 LY_ERR r;
541 struct ly_err_item *err;
542 uint64_t num = 0;
543 uint32_t type_idx = 0;
544 ly_bool dynamic;
545 size_t pval_len;
546 void *pval;
547
548 /* Find out the index number (type_idx). The call should succeed
549 * because the union_find_type() has already been called in the
550 * lyplg_type_store_union().
551 */
552 if (!ctx) {
553 assert(subvalue->ctx_node);
554 ctx = subvalue->ctx_node->module->ctx;
555 }
556 subvalue->value.realtype->plugin->free(ctx, &subvalue->value);
557 r = union_find_type(ctx, type_u, subvalue, 0, 0, NULL, NULL, &type_idx, NULL, &err);
559 LY_CHECK_RET((r != LY_SUCCESS) && (r != LY_EINCOMPLETE), NULL);
560
561 /* Print subvalue in LYB format. */
562 pval = (void *)subvalue->value.realtype->plugin->print(NULL, &subvalue->value, LY_VALUE_LYB, prefix_data, &dynamic,
563 &pval_len);
564 LY_CHECK_RET(!pval, NULL);
565
566 /* Create LYB data. */
567 *value_len = TYPE_IDX_SIZE + pval_len;
568 ret = malloc(*value_len);
569 LY_CHECK_RET(!ret, NULL);
570
571 num = type_idx;
572 num = htole64(num);
573 memcpy(ret, &num, TYPE_IDX_SIZE);
574 memcpy((char *)ret + TYPE_IDX_SIZE, pval, pval_len);
575
576 if (dynamic) {
577 free(pval);
578 }
579
580 return ret;
581}
582
583LIBYANG_API_DEF const void *
584lyplg_type_print_union(const struct ly_ctx *ctx, const struct lyd_value *value, LY_VALUE_FORMAT format,
585 void *prefix_data, ly_bool *dynamic, size_t *value_len)
586{
587 const void *ret;
588 struct lyd_value_union *subvalue = value->subvalue;
589 struct lysc_type_union *type_u = (struct lysc_type_union *)value->realtype;
590 size_t lyb_data_len = 0;
591
592 if ((format == LY_VALUE_LYB) && (subvalue->format == LY_VALUE_LYB)) {
593 /* The return value is already ready. */
594 *dynamic = 0;
595 if (value_len) {
596 *value_len = subvalue->orig_len;
597 }
598 return subvalue->original;
599 } else if ((format == LY_VALUE_LYB) && (subvalue->format != LY_VALUE_LYB)) {
600 /* The return LYB data must be created. */
601 *dynamic = 1;
602 ret = lyb_union_print(ctx, type_u, subvalue, prefix_data, &lyb_data_len);
603 if (value_len) {
604 *value_len = lyb_data_len;
605 }
606 return ret;
607 }
608
609 assert(format != LY_VALUE_LYB);
610 ret = (void *)subvalue->value.realtype->plugin->print(ctx, &subvalue->value, format, prefix_data, dynamic, value_len);
611 if (!value->_canonical && (format == LY_VALUE_CANON)) {
612 /* the canonical value is supposed to be stored now */
613 lydict_insert(ctx, subvalue->value._canonical, 0, (const char **)&value->_canonical);
614 }
615
616 return ret;
617}
618
619LIBYANG_API_DEF LY_ERR
620lyplg_type_dup_union(const struct ly_ctx *ctx, const struct lyd_value *original, struct lyd_value *dup)
621{
622 LY_ERR ret = LY_SUCCESS;
623 struct lyd_value_union *orig_val = original->subvalue, *dup_val;
624
625 /* init dup value */
626 memset(dup, 0, sizeof *dup);
627 dup->realtype = original->realtype;
628
629 ret = lydict_insert(ctx, original->_canonical, 0, &dup->_canonical);
630 LY_CHECK_GOTO(ret, cleanup);
631
632 dup_val = calloc(1, sizeof *dup_val);
633 LY_CHECK_ERR_GOTO(!dup_val, LOGMEM(ctx); ret = LY_EMEM, cleanup);
634 dup->subvalue = dup_val;
635
636 ret = orig_val->value.realtype->plugin->duplicate(ctx, &orig_val->value, &dup_val->value);
637 LY_CHECK_GOTO(ret, cleanup);
638
639 if (orig_val->orig_len) {
640 dup_val->original = calloc(1, orig_val->orig_len);
641 LY_CHECK_ERR_GOTO(!dup_val->original, LOGMEM(ctx); ret = LY_EMEM, cleanup);
642 memcpy(dup_val->original, orig_val->original, orig_val->orig_len);
643 } else {
644 dup_val->original = strdup("");
645 LY_CHECK_ERR_GOTO(!dup_val->original, LOGMEM(ctx); ret = LY_EMEM, cleanup);
646 }
647 dup_val->orig_len = orig_val->orig_len;
648
649 dup_val->format = orig_val->format;
650 dup_val->ctx_node = orig_val->ctx_node;
651 dup_val->hints = orig_val->hints;
652 ret = lyplg_type_prefix_data_dup(ctx, orig_val->format, orig_val->prefix_data, &dup_val->prefix_data);
653 LY_CHECK_GOTO(ret, cleanup);
654
655cleanup:
656 if (ret) {
657 lyplg_type_free_union(ctx, dup);
658 }
659 return ret;
660}
661
662LIBYANG_API_DEF void
663lyplg_type_free_union(const struct ly_ctx *ctx, struct lyd_value *value)
664{
665 struct lyd_value_union *val;
666
668 value->_canonical = NULL;
669 LYD_VALUE_GET(value, val);
670 if (val) {
671 if (val->value.realtype) {
672 val->value.realtype->plugin->free(ctx, &val->value);
673 }
675 free(val->original);
676
678 }
679}
680
689 {
690 .module = "",
691 .revision = NULL,
692 .name = LY_TYPE_UNION_STR,
693
694 .plugin.id = "libyang 2 - union,version 1",
695 .plugin.store = lyplg_type_store_union,
696 .plugin.validate = lyplg_type_validate_union,
697 .plugin.compare = lyplg_type_compare_union,
698 .plugin.sort = lyplg_type_sort_union,
699 .plugin.print = lyplg_type_print_union,
700 .plugin.duplicate = lyplg_type_dup_union,
701 .plugin.free = lyplg_type_free_union,
702 .plugin.lyb_data_len = -1,
703 },
704 {0}
705};
libyang context handler.
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...
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 ...
LY_ERR err
Definition log.h:284
char * msg
Definition log.h:286
LY_ERR
libyang's error codes returned by the libyang functions.
Definition log.h:237
@ LYVE_DATA
Definition log.h:274
@ LY_EMEM
Definition log.h:239
@ LY_ENOT
Definition log.h:251
@ LY_EVALID
Definition log.h:245
@ LY_SUCCESS
Definition log.h:238
@ LY_EINCOMPLETE
Definition log.h:247
Libyang full error structure.
Definition log.h:282
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().
const char *const char * revision
lyplg_type_print_clb print
lyplg_type_store_clb store
lyplg_type_compare_clb compare
lyplg_type_validate_clb validate
const char * id
lyplg_type_dup_clb duplicate
lyplg_type_free_clb free
lyplg_type_sort_clb sort
#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 LIBYANG_API_DECL void ly_err_free(void *ptr)
Destructor for the error records created with ly_err_new().
#define LYPLG_TYPE_VAL_INLINE_DESTROY(type_val)
Destroy a prepared value.
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.
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_prefix_data_dup(const struct ly_ctx *ctx, LY_VALUE_FORMAT format, const void *orig, void **dup)
Duplicate prefix data.
LIBYANG_API_DECL void lyplg_type_prefix_data_free(LY_VALUE_FORMAT format, void *prefix_data)
Free internal prefix data.
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:663
LIBYANG_API_DEF 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:488
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:584
LIBYANG_API_DEF 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:497
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:437
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:382
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:620
#define LYPLG_TYPE_STORE_DYNAMIC
#define LYPLG_TYPE_STORE_ONLY
struct lyplg_type * plugin
struct lysc_type ** types
Compiled YANG data node.
#define LY_ARRAY_COUNT(ARRAY)
Get the number of records in the ARRAY.
Definition tree.h:148
#define LY_ARRAY_FOR(ARRAY,...)
Sized-array iterator (for-loop).
Definition tree.h:167
LY_VALUE_FORMAT
All kinds of supported value formats and prefix mappings to modules.
Definition tree.h:234
#define LY_PRI_ARRAY_COUNT_TYPE
Printing format specifier macro for LY_ARRAY_SIZE_TYPE values.
Definition tree.h:109
#define LY_ARRAY_COUNT_TYPE
Type (i.e. size) of the sized array's size counter.
Definition tree.h:104
@ LY_VALUE_JSON
Definition tree.h:239
@ LY_VALUE_CANON
Definition tree.h:235
@ LY_VALUE_LYB
Definition tree.h:240
The main libyang public header.
uint8_t ly_bool
Type to indicate boolean value.
Definition log.h:35
API for (user) types plugins.
const struct lysc_type * realtype
Definition tree_data.h:579
void * prefix_data
Definition tree_data.h:639
uint32_t hints
Definition tree_data.h:635
#define LYD_VALUE_GET(value, type_val)
Get the value in format specific to the type.
Definition tree_data.h:618
struct lyd_value value
Definition tree_data.h:631
const char * _canonical
Definition tree_data.h:576
LY_VALUE_FORMAT format
Definition tree_data.h:636
const struct lysc_node * ctx_node
Definition tree_data.h:640
Generic structure for a data node.
Definition tree_data.h:803
YANG data representation.
Definition tree_data.h:575
Special lyd_value structure for built-in union values.
Definition tree_data.h:630
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 LOGMEM(CTX)
Definition tree_edit.h:22
#define TYPE_IDX_SIZE
Size in bytes of the used type index in the LYB Binary Format.
Definition union.c:46
const struct lyplg_type_record plugins_union[]
Plugin information for union type implementation.
Definition union.c:688