libyang  4.0.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
integer.c
Go to the documentation of this file.
1 
16 #define _GNU_SOURCE /* asprintf, strdup */
17 
18 #include "plugins_types.h"
19 
20 #include <assert.h>
21 #include <stdint.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 
25 #include "libyang.h"
26 
27 /* additional internal headers for some useful simple macros */
28 #include "compat.h"
29 #include "ly_common.h"
30 #include "plugins_internal.h" /* LY_TYPE_*_STR */
31 #include "tree_schema_internal.h"
32 
42 static LY_ERR lyplg_type_validate_value_int(const struct ly_ctx *ctx, const struct lysc_type *type,
43  struct lyd_value *storage, struct ly_err_item **err);
44 static LY_ERR lyplg_type_validate_value_uint(const struct ly_ctx *ctx, const struct lysc_type *type,
45  struct lyd_value *storage, struct ly_err_item **err);
46 
47 static LY_ERR
48 lyplg_type_store_int(const struct ly_ctx *ctx, const struct lysc_type *type, const void *value, uint32_t value_size_bits,
49  uint32_t options, LY_VALUE_FORMAT format, void *UNUSED(prefix_data), uint32_t hints,
50  const struct lysc_node *UNUSED(ctx_node), const struct lysc_ext_instance *UNUSED(top_ext),
51  struct lyd_value *storage, struct lys_glob_unres *UNUSED(unres), struct ly_err_item **err)
52 {
53  LY_ERR ret = LY_SUCCESS;
54  uint32_t value_size;
55  int64_t num = 0;
56  int base = 1;
57  char *canon = NULL;
58 
59  /* init storage */
60  memset(storage, 0, sizeof *storage);
61  storage->realtype = type;
62 
63  /* check value length */
64  ret = lyplg_type_check_value_size(lys_datatype2str(type->basetype), format, value_size_bits,
65  LYPLG_LYB_SIZE_VARIABLE_BITS, 0, &value_size, err);
66  LY_CHECK_GOTO(ret, cleanup);
67 
68  if (format == LY_VALUE_LYB) {
69  /* copy the integer and correct the byte order */
70  memcpy(&num, value, value_size);
71  num = le64toh(num);
72  } else {
73  /* check hints */
74  ret = lyplg_type_check_hints(hints, value, value_size, type->basetype, &base, err);
75  LY_CHECK_GOTO(ret, cleanup);
76 
77  /* parse the integer */
78  switch (type->basetype) {
79  case LY_TYPE_INT8:
80  ret = lyplg_type_parse_int("int8", base, INT64_C(-128), INT64_C(127), value, value_size, &num, err);
81  break;
82  case LY_TYPE_INT16:
83  ret = lyplg_type_parse_int("int16", base, INT64_C(-32768), INT64_C(32767), value, value_size, &num, err);
84  break;
85  case LY_TYPE_INT32:
86  ret = lyplg_type_parse_int("int32", base, INT64_C(-2147483648), INT64_C(2147483647), value, value_size, &num, err);
87  break;
88  case LY_TYPE_INT64:
89  ret = lyplg_type_parse_int("int64", base, INT64_C(-9223372036854775807) - INT64_C(1),
90  INT64_C(9223372036854775807), value, value_size, &num, err);
91  break;
92  default:
93  LOGINT(ctx);
94  ret = LY_EINT;
95  }
96  LY_CHECK_GOTO(ret, cleanup);
97  }
98 
99  /* set the value (matters for big-endian) and get the correct int64 number */
100  switch (type->basetype) {
101  case LY_TYPE_INT8:
102  storage->int8 = num;
103  num = storage->int8;
104  break;
105  case LY_TYPE_INT16:
106  storage->int16 = num;
107  num = storage->int16;
108  break;
109  case LY_TYPE_INT32:
110  storage->int32 = num;
111  num = storage->int32;
112  break;
113  case LY_TYPE_INT64:
114  storage->int64 = num;
115  num = storage->int64;
116  break;
117  default:
118  break;
119  }
120 
121  if (format == LY_VALUE_CANON) {
122  /* store canonical value */
123  if (options & LYPLG_TYPE_STORE_DYNAMIC) {
124  ret = lydict_insert_zc(ctx, (char *)value, &storage->_canonical);
125  options &= ~LYPLG_TYPE_STORE_DYNAMIC;
126  LY_CHECK_GOTO(ret, cleanup);
127  } else {
128  ret = lydict_insert(ctx, value, value_size, &storage->_canonical);
129  LY_CHECK_GOTO(ret, cleanup);
130  }
131  } else {
132  /* generate canonical value */
133  switch (type->basetype) {
134  case LY_TYPE_INT8:
135  LY_CHECK_ERR_GOTO(asprintf(&canon, "%" PRId8, storage->int8) == -1, ret = LY_EMEM, cleanup);
136  break;
137  case LY_TYPE_INT16:
138  LY_CHECK_ERR_GOTO(asprintf(&canon, "%" PRId16, storage->int16) == -1, ret = LY_EMEM, cleanup);
139  break;
140  case LY_TYPE_INT32:
141  LY_CHECK_ERR_GOTO(asprintf(&canon, "%" PRId32, storage->int32) == -1, ret = LY_EMEM, cleanup);
142  break;
143  case LY_TYPE_INT64:
144  LY_CHECK_ERR_GOTO(asprintf(&canon, "%" PRId64, storage->int64) == -1, ret = LY_EMEM, cleanup);
145  break;
146  default:
147  break;
148  }
149 
150  /* store it */
151  ret = lydict_insert_zc(ctx, canon, (const char **)&storage->_canonical);
152  LY_CHECK_GOTO(ret, cleanup);
153  }
154 
155  if (!(options & LYPLG_TYPE_STORE_ONLY)) {
156  /* validate value */
157  ret = lyplg_type_validate_value_int(ctx, type, storage, err);
158  LY_CHECK_GOTO(ret, cleanup);
159  }
160 
161 cleanup:
162  if (options & LYPLG_TYPE_STORE_DYNAMIC) {
163  free((void *)value);
164  }
165 
166  if (ret) {
167  lyplg_type_free_simple(ctx, storage);
168  }
169  return ret;
170 }
171 
175 static LY_ERR
176 lyplg_type_validate_value_int(const struct ly_ctx *UNUSED(ctx), const struct lysc_type *type, struct lyd_value *storage,
177  struct ly_err_item **err)
178 {
179  LY_ERR ret;
180  struct lysc_type_num *type_num = (struct lysc_type_num *)type;
181  int64_t num;
182 
183  LY_CHECK_ARG_RET(NULL, type, storage, err, LY_EINVAL);
184  *err = NULL;
185 
186  /* set the value (matters for big-endian) and get the correct int64 number */
187  switch (type->basetype) {
188  case LY_TYPE_INT8:
189  num = storage->int8;
190  break;
191  case LY_TYPE_INT16:
192  num = storage->int16;
193  break;
194  case LY_TYPE_INT32:
195  num = storage->int32;
196  break;
197  case LY_TYPE_INT64:
198  num = storage->int64;
199  break;
200  default:
201  return LY_EINVAL;
202  }
203 
204  /* validate range of the number */
205  if (type_num->range) {
206  ret = lyplg_type_validate_range(type->basetype, type_num->range, num, storage->_canonical,
207  strlen(storage->_canonical), err);
208  LY_CHECK_RET(ret);
209  }
210 
211  return LY_SUCCESS;
212 }
213 
214 static LY_ERR
215 lyplg_type_compare_int(const struct ly_ctx *UNUSED(ctx), const struct lyd_value *val1, const struct lyd_value *val2)
216 {
217  if (val1->realtype != val2->realtype) {
218  return LY_ENOT;
219  }
220 
221  switch (val1->realtype->basetype) {
222  case LY_TYPE_INT8:
223  if (val1->int8 != val2->int8) {
224  return LY_ENOT;
225  }
226  break;
227  case LY_TYPE_INT16:
228  if (val1->int16 != val2->int16) {
229  return LY_ENOT;
230  }
231  break;
232  case LY_TYPE_INT32:
233  if (val1->int32 != val2->int32) {
234  return LY_ENOT;
235  }
236  break;
237  case LY_TYPE_INT64:
238  if (val1->int64 != val2->int64) {
239  return LY_ENOT;
240  }
241  break;
242  default:
243  break;
244  }
245  return LY_SUCCESS;
246 }
247 
248 static int
249 lyplg_type_sort_int(const struct ly_ctx *UNUSED(ctx), const struct lyd_value *val1, const struct lyd_value *val2)
250 {
251  switch (val1->realtype->basetype) {
252  case LY_TYPE_INT8:
253  if (val1->int8 < val2->int8) {
254  return -1;
255  } else if (val1->int8 > val2->int8) {
256  return 1;
257  } else {
258  return 0;
259  }
260  break;
261  case LY_TYPE_INT16:
262  if (val1->int16 < val2->int16) {
263  return -1;
264  } else if (val1->int16 > val2->int16) {
265  return 1;
266  } else {
267  return 0;
268  }
269  break;
270  case LY_TYPE_INT32:
271  if (val1->int32 < val2->int32) {
272  return -1;
273  } else if (val1->int32 > val2->int32) {
274  return 1;
275  } else {
276  return 0;
277  }
278  break;
279  case LY_TYPE_INT64:
280  if (val1->int64 < val2->int64) {
281  return -1;
282  } else if (val1->int64 > val2->int64) {
283  return 1;
284  } else {
285  return 0;
286  }
287  break;
288  default:
289  break;
290  }
291  return 0;
292 }
293 
294 static const void *
295 lyplg_type_print_int(const struct ly_ctx *UNUSED(ctx), const struct lyd_value *value, LY_VALUE_FORMAT format,
296  void *UNUSED(prefix_data), ly_bool *dynamic, uint32_t *value_size_bits)
297 {
298  int64_t prev_num = 0, num = 0;
299  void *buf;
300 
301  if (format == LY_VALUE_LYB) {
302  switch (value->realtype->basetype) {
303  case LY_TYPE_INT8:
304  prev_num = num = value->int8;
305  break;
306  case LY_TYPE_INT16:
307  prev_num = num = value->int16;
308  break;
309  case LY_TYPE_INT32:
310  prev_num = num = value->int32;
311  break;
312  case LY_TYPE_INT64:
313  prev_num = num = value->int64;
314  break;
315  default:
316  break;
317  }
318 
319  num = htole64(num);
320  if (num == prev_num) {
321  /* values are equal, little-endian or int8 */
322  *dynamic = 0;
323  if (value_size_bits) {
324  /* the least amount of bits that can hold the number */
325  *value_size_bits = lyplg_type_get_highest_set_bit_pos(num);
326  }
327  return &value->int64;
328  } else {
329  /* values differ, big-endian */
331  LY_CHECK_RET(!buf, NULL);
332 
333  *dynamic = 1;
334  if (value_size_bits) {
335  *value_size_bits = lyplg_type_get_highest_set_bit_pos(num);
336  }
337  memcpy(buf, &num, LYPLG_BITS2BYTES(lyplg_type_get_highest_set_bit_pos(num)));
338  return buf;
339  }
340  }
341 
342  /* use the cached canonical value */
343  if (dynamic) {
344  *dynamic = 0;
345  }
346  if (value_size_bits) {
347  *value_size_bits = strlen(value->_canonical) * 8;
348  }
349  return value->_canonical;
350 }
351 
352 static LY_ERR
353 lyplg_type_store_uint(const struct ly_ctx *ctx, const struct lysc_type *type, const void *value, uint32_t value_size_bits,
354  uint32_t options, LY_VALUE_FORMAT format, void *UNUSED(prefix_data), uint32_t hints,
355  const struct lysc_node *UNUSED(ctx_node), const struct lysc_ext_instance *UNUSED(top_ext),
356  struct lyd_value *storage, struct lys_glob_unres *UNUSED(unres), struct ly_err_item **err)
357 {
358  LY_ERR ret = LY_SUCCESS;
359  uint32_t value_size;
360  uint64_t num = 0;
361  int base = 0;
362  char *canon;
363 
364  /* init storage */
365  memset(storage, 0, sizeof *storage);
366  storage->realtype = type;
367 
368  /* check value length */
369  ret = lyplg_type_check_value_size(lys_datatype2str(type->basetype), format, value_size_bits,
370  LYPLG_LYB_SIZE_VARIABLE_BITS, 0, &value_size, err);
371  LY_CHECK_GOTO(ret, cleanup);
372 
373  if (format == LY_VALUE_LYB) {
374  /* copy the integer and correct the byte order */
375  memcpy(&num, value, value_size);
376  num = le64toh(num);
377  } else {
378  /* check hints */
379  ret = lyplg_type_check_hints(hints, value, value_size, type->basetype, &base, err);
380  LY_CHECK_GOTO(ret, cleanup);
381 
382  /* parse the integer */
383  switch (type->basetype) {
384  case LY_TYPE_UINT8:
385  ret = lyplg_type_parse_uint("uint8", base, UINT64_C(255), value, value_size, &num, err);
386  break;
387  case LY_TYPE_UINT16:
388  ret = lyplg_type_parse_uint("uint16", base, UINT64_C(65535), value, value_size, &num, err);
389  break;
390  case LY_TYPE_UINT32:
391  ret = lyplg_type_parse_uint("uint32", base, UINT64_C(4294967295), value, value_size, &num, err);
392  break;
393  case LY_TYPE_UINT64:
394  ret = lyplg_type_parse_uint("uint64", base, UINT64_C(18446744073709551615), value, value_size, &num, err);
395  break;
396  default:
397  LOGINT(ctx);
398  ret = LY_EINT;
399  }
400  LY_CHECK_GOTO(ret, cleanup);
401  }
402 
403  /* store value, matters for big-endian */
404  switch (type->basetype) {
405  case LY_TYPE_UINT8:
406  storage->uint8 = num;
407  break;
408  case LY_TYPE_UINT16:
409  storage->uint16 = num;
410  break;
411  case LY_TYPE_UINT32:
412  storage->uint32 = num;
413  break;
414  case LY_TYPE_UINT64:
415  storage->uint64 = num;
416  break;
417  default:
418  break;
419  }
420 
421  if (format == LY_VALUE_CANON) {
422  /* store canonical value */
423  if (options & LYPLG_TYPE_STORE_DYNAMIC) {
424  ret = lydict_insert_zc(ctx, (char *)value, &storage->_canonical);
425  options &= ~LYPLG_TYPE_STORE_DYNAMIC;
426  LY_CHECK_GOTO(ret, cleanup);
427  } else {
428  ret = lydict_insert(ctx, value, value_size, &storage->_canonical);
429  LY_CHECK_GOTO(ret, cleanup);
430  }
431  } else {
432  /* generate canonical value */
433  LY_CHECK_ERR_GOTO(asprintf(&canon, "%" PRIu64, num) == -1, ret = LY_EMEM, cleanup);
434 
435  /* store it */
436  ret = lydict_insert_zc(ctx, canon, (const char **)&storage->_canonical);
437  LY_CHECK_GOTO(ret, cleanup);
438  }
439 
440  if (!(options & LYPLG_TYPE_STORE_ONLY)) {
441  /* validate value */
442  ret = lyplg_type_validate_value_uint(ctx, type, storage, err);
443  LY_CHECK_GOTO(ret, cleanup);
444  }
445 
446 cleanup:
447  if (options & LYPLG_TYPE_STORE_DYNAMIC) {
448  free((void *)value);
449  }
450 
451  if (ret) {
452  lyplg_type_free_simple(ctx, storage);
453  }
454  return ret;
455 }
456 
460 static LY_ERR
461 lyplg_type_validate_value_uint(const struct ly_ctx *UNUSED(ctx), const struct lysc_type *type, struct lyd_value *storage,
462  struct ly_err_item **err)
463 {
464  LY_ERR ret;
465  struct lysc_type_num *type_num = (struct lysc_type_num *)type;
466  uint64_t num;
467 
468  LY_CHECK_ARG_RET(NULL, type, storage, err, LY_EINVAL);
469  *err = NULL;
470 
471  /* set the value (matters for big-endian) and get the correct int64 number */
472  switch (type->basetype) {
473  case LY_TYPE_UINT8:
474  num = storage->uint8;
475  break;
476  case LY_TYPE_UINT16:
477  num = storage->uint16;
478  break;
479  case LY_TYPE_UINT32:
480  num = storage->uint32;
481  break;
482  case LY_TYPE_UINT64:
483  num = storage->uint64;
484  break;
485  default:
486  return LY_EINVAL;
487  }
488 
489  /* validate range of the number */
490  if (type_num->range) {
491  ret = lyplg_type_validate_range(type->basetype, type_num->range, num, storage->_canonical,
492  strlen(storage->_canonical), err);
493  LY_CHECK_RET(ret);
494  }
495 
496  return LY_SUCCESS;
497 }
498 
499 static LY_ERR
500 lyplg_type_compare_uint(const struct ly_ctx *UNUSED(ctx), const struct lyd_value *val1, const struct lyd_value *val2)
501 {
502  switch (val1->realtype->basetype) {
503  case LY_TYPE_UINT8:
504  if (val1->uint8 != val2->uint8) {
505  return LY_ENOT;
506  }
507  break;
508  case LY_TYPE_UINT16:
509  if (val1->uint16 != val2->uint16) {
510  return LY_ENOT;
511  }
512  break;
513  case LY_TYPE_UINT32:
514  if (val1->uint32 != val2->uint32) {
515  return LY_ENOT;
516  }
517  break;
518  case LY_TYPE_UINT64:
519  if (val1->uint64 != val2->uint64) {
520  return LY_ENOT;
521  }
522  break;
523  default:
524  break;
525  }
526  return LY_SUCCESS;
527 }
528 
529 static int
530 lyplg_type_sort_uint(const struct ly_ctx *UNUSED(ctx), const struct lyd_value *val1, const struct lyd_value *val2)
531 {
532  switch (val1->realtype->basetype) {
533  case LY_TYPE_UINT8:
534  if (val1->uint8 < val2->uint8) {
535  return -1;
536  } else if (val1->uint8 > val2->uint8) {
537  return 1;
538  } else {
539  return 0;
540  }
541  break;
542  case LY_TYPE_UINT16:
543  if (val1->uint16 < val2->uint16) {
544  return -1;
545  } else if (val1->uint16 > val2->uint16) {
546  return 1;
547  } else {
548  return 0;
549  }
550  break;
551  case LY_TYPE_UINT32:
552  if (val1->uint32 < val2->uint32) {
553  return -1;
554  } else if (val1->uint32 > val2->uint32) {
555  return 1;
556  } else {
557  return 0;
558  }
559  break;
560  case LY_TYPE_UINT64:
561  if (val1->uint64 < val2->uint64) {
562  return -1;
563  } else if (val1->uint64 > val2->uint64) {
564  return 1;
565  } else {
566  return 0;
567  }
568  break;
569  default:
570  break;
571  }
572  return 0;
573 }
574 
575 static const void *
576 lyplg_type_print_uint(const struct ly_ctx *UNUSED(ctx), const struct lyd_value *value, LY_VALUE_FORMAT format,
577  void *UNUSED(prefix_data), ly_bool *dynamic, uint32_t *value_size_bits)
578 {
579  uint64_t num = 0;
580  void *buf;
581 
582  if (format == LY_VALUE_LYB) {
583  switch (value->realtype->basetype) {
584  case LY_TYPE_UINT8:
585  num = value->uint8;
586  break;
587  case LY_TYPE_UINT16:
588  num = value->uint16;
589  break;
590  case LY_TYPE_UINT32:
591  num = value->uint32;
592  break;
593  case LY_TYPE_UINT64:
594  num = value->uint64;
595  break;
596  default:
597  break;
598  }
599  num = htole64(num);
600  if (num == value->uint64) {
601  /* values are equal, little-endian or uint8 */
602  *dynamic = 0;
603  if (value_size_bits) {
604  /* the least amount of bits that can hold the number */
605  *value_size_bits = lyplg_type_get_highest_set_bit_pos(num);
606  }
607  return &value->uint64;
608  } else {
609  /* values differ, big-endian */
611  LY_CHECK_RET(!buf, NULL);
612 
613  *dynamic = 1;
614  if (value_size_bits) {
615  *value_size_bits = lyplg_type_get_highest_set_bit_pos(num);
616  }
617  memcpy(buf, &num, LYPLG_BITS2BYTES(lyplg_type_get_highest_set_bit_pos(num)));
618  return buf;
619  }
620  }
621 
622  /* use the cached canonical value */
623  if (dynamic) {
624  *dynamic = 0;
625  }
626  if (value_size_bits) {
627  *value_size_bits = strlen(value->_canonical) * 8;
628  }
629  return value->_canonical;
630 }
631 
640  {
641  .module = "",
642  .revision = NULL,
643  .name = LY_TYPE_UINT8_STR,
644 
645  .plugin.id = "ly2 integers",
646  .plugin.lyb_size = lyplg_type_lyb_size_variable_bits,
647  .plugin.store = lyplg_type_store_uint,
648  .plugin.validate_value = lyplg_type_validate_value_uint,
649  .plugin.validate_tree = NULL,
650  .plugin.compare = lyplg_type_compare_uint,
651  .plugin.sort = lyplg_type_sort_uint,
652  .plugin.print = lyplg_type_print_uint,
653  .plugin.duplicate = lyplg_type_dup_simple,
654  .plugin.free = lyplg_type_free_simple,
655  }, {
656  .module = "",
657  .revision = NULL,
658  .name = LY_TYPE_UINT16_STR,
659 
660  .plugin.id = "ly2 integers",
661  .plugin.lyb_size = lyplg_type_lyb_size_variable_bits,
662  .plugin.store = lyplg_type_store_uint,
663  .plugin.validate_value = lyplg_type_validate_value_uint,
664  .plugin.validate_tree = NULL,
665  .plugin.compare = lyplg_type_compare_uint,
666  .plugin.sort = lyplg_type_sort_uint,
667  .plugin.print = lyplg_type_print_uint,
668  .plugin.duplicate = lyplg_type_dup_simple,
669  .plugin.free = lyplg_type_free_simple,
670  }, {
671  .module = "",
672  .revision = NULL,
673  .name = LY_TYPE_UINT32_STR,
674 
675  .plugin.id = "ly2 integers",
676  .plugin.lyb_size = lyplg_type_lyb_size_variable_bits,
677  .plugin.store = lyplg_type_store_uint,
678  .plugin.validate_value = lyplg_type_validate_value_uint,
679  .plugin.validate_tree = NULL,
680  .plugin.compare = lyplg_type_compare_uint,
681  .plugin.sort = lyplg_type_sort_uint,
682  .plugin.print = lyplg_type_print_uint,
683  .plugin.duplicate = lyplg_type_dup_simple,
684  .plugin.free = lyplg_type_free_simple,
685  }, {
686  .module = "",
687  .revision = NULL,
688  .name = LY_TYPE_UINT64_STR,
689 
690  .plugin.id = "ly2 integers",
691  .plugin.lyb_size = lyplg_type_lyb_size_variable_bits,
692  .plugin.store = lyplg_type_store_uint,
693  .plugin.validate_value = lyplg_type_validate_value_uint,
694  .plugin.validate_tree = NULL,
695  .plugin.compare = lyplg_type_compare_uint,
696  .plugin.sort = lyplg_type_sort_uint,
697  .plugin.print = lyplg_type_print_uint,
698  .plugin.duplicate = lyplg_type_dup_simple,
699  .plugin.free = lyplg_type_free_simple,
700  }, {
701  .module = "",
702  .revision = NULL,
703  .name = LY_TYPE_INT8_STR,
704 
705  .plugin.id = "ly2 integers",
706  .plugin.lyb_size = lyplg_type_lyb_size_variable_bits,
707  .plugin.store = lyplg_type_store_int,
708  .plugin.validate_value = lyplg_type_validate_value_int,
709  .plugin.validate_tree = NULL,
710  .plugin.compare = lyplg_type_compare_int,
711  .plugin.sort = lyplg_type_sort_int,
712  .plugin.print = lyplg_type_print_int,
713  .plugin.duplicate = lyplg_type_dup_simple,
714  .plugin.free = lyplg_type_free_simple,
715  }, {
716  .module = "",
717  .revision = NULL,
718  .name = LY_TYPE_INT16_STR,
719 
720  .plugin.id = "ly2 integers",
721  .plugin.lyb_size = lyplg_type_lyb_size_variable_bits,
722  .plugin.store = lyplg_type_store_int,
723  .plugin.validate_value = lyplg_type_validate_value_int,
724  .plugin.validate_tree = NULL,
725  .plugin.compare = lyplg_type_compare_int,
726  .plugin.sort = lyplg_type_sort_int,
727  .plugin.print = lyplg_type_print_int,
728  .plugin.duplicate = lyplg_type_dup_simple,
729  .plugin.free = lyplg_type_free_simple,
730  }, {
731  .module = "",
732  .revision = NULL,
733  .name = LY_TYPE_INT32_STR,
734 
735  .plugin.id = "ly2 integers",
736  .plugin.lyb_size = lyplg_type_lyb_size_variable_bits,
737  .plugin.store = lyplg_type_store_int,
738  .plugin.validate_value = lyplg_type_validate_value_int,
739  .plugin.validate_tree = NULL,
740  .plugin.compare = lyplg_type_compare_int,
741  .plugin.sort = lyplg_type_sort_int,
742  .plugin.print = lyplg_type_print_int,
743  .plugin.duplicate = lyplg_type_dup_simple,
744  .plugin.free = lyplg_type_free_simple,
745  }, {
746  .module = "",
747  .revision = NULL,
748  .name = LY_TYPE_INT64_STR,
749 
750  .plugin.id = "ly2 integers",
751  .plugin.lyb_size = lyplg_type_lyb_size_variable_bits,
752  .plugin.store = lyplg_type_store_int,
753  .plugin.validate_value = lyplg_type_validate_value_int,
754  .plugin.validate_tree = NULL,
755  .plugin.compare = lyplg_type_compare_int,
756  .plugin.sort = lyplg_type_sort_int,
757  .plugin.print = lyplg_type_print_int,
758  .plugin.duplicate = lyplg_type_dup_simple,
759  .plugin.free = lyplg_type_free_simple,
760  },
761  {0}
762 };
LIBYANG_API_DECL void lyplg_type_lyb_size_variable_bits(const struct lysc_type *type, enum lyplg_lyb_size_type *size_type, uint32_t *fixed_size_bits)
Implementation of lyplg_type_lyb_size_clb for a type with variable length in bits.
struct lysc_type * realtype
Definition: tree_data.h:567
Compiled YANG data node.
Definition: tree_schema.h:1434
memset(value->fixed_mem, 0, LYD_VALUE_FIXED_MEM_SIZE)
LIBYANG_API_DECL LY_ERR lyplg_type_check_value_size(const char *type_name, LY_VALUE_FORMAT format, uint32_t value_size_bits, enum lyplg_lyb_size_type lyb_size_type, uint32_t lyb_fixed_size_bits, uint32_t *value_size, struct ly_err_item **err)
Check a value type in bits is correct and as expected.
YANG extension compiled instance.
Definition: plugins_exts.h:436
struct lyplg_type_record plugins_integer[]
Plugin information for integer types implementation.
Definition: integer.c:639
LY_ERR
libyang&#39;s error codes returned by the libyang functions.
Definition: log.h:240
uint8_t ly_bool
Type to indicate boolean value.
Definition: log.h:28
Definition: log.h:254
#define LYPLG_TYPE_STORE_DYNAMIC
LIBYANG_API_DECL LY_ERR lyplg_type_parse_int(const char *datatype, int base, int64_t min, int64_t max, const char *value, uint32_t value_len, int64_t *ret, struct ly_err_item **err)
Unsigned integer value parser and validator.
Definition: log.h:244
Definition: log.h:242
The main libyang public header.
YANG data representation.
Definition: tree_data.h:563
const char * _canonical
Definition: tree_data.h:564
Definition: log.h:247
Libyang full error structure.
Definition: log.h:285
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...
struct lysc_range * range
Definition: tree_schema.h:1312
const char * module
LIBYANG_API_DECL LY_ERR lyplg_type_parse_uint(const char *datatype, int base, uint64_t max, const char *value, uint32_t value_len, uint64_t *ret, struct ly_err_item **err)
Unsigned integer value parser and validator.
LIBYANG_API_DECL LY_ERR lydict_insert_zc(const struct ly_ctx *ctx, char *value, const char **str_p)
Insert string into dictionary - zerocopy version. If the string is already present, only a reference counter is incremented and no memory allocation is performed. This insert function variant avoids duplication of specified value - it is inserted into the dictionary directly.
LIBYANG_API_DECL uint64_t lyplg_type_get_highest_set_bit_pos(uint64_t num)
Learn the position of the highest set bit in a number. Represents also the least amount of bits requi...
LY_VALUE_FORMAT
All kinds of supported value formats and prefix mappings to modules.
Definition: tree.h:234
LY_DATA_TYPE basetype
Definition: tree_schema.h:1300
LIBYANG_API_DECL LY_ERR lyplg_type_dup_simple(const struct ly_ctx *ctx, const struct lyd_value *original, struct lyd_value *dup)
Implementation of lyplg_type_dup_clb for a generic simple type.
LIBYANG_API_DECL void lyplg_type_free_simple(const struct ly_ctx *ctx, struct lyd_value *value)
Implementation of lyplg_type_free_clb for a generic simple type.
LIBYANG_API_DECL LY_ERR lyplg_type_check_hints(uint32_t hints, const char *value, uint32_t value_len, LY_DATA_TYPE type, int *base, struct ly_err_item **err)
Check that the type is suitable for the parser&#39;s hints (if any) in the specified format.
API for (user) types plugins.
libyang context handler.
LIBYANG_API_DECL LY_ERR lyplg_type_validate_range(LY_DATA_TYPE basetype, struct lysc_range *range, int64_t value, const char *strval, uint32_t strval_len, struct ly_err_item **err)
Data type validator for a range/length-restricted values.
#define LYPLG_BITS2BYTES(bits)
Convert bits to bytes.
#define LYPLG_TYPE_STORE_ONLY