libyang  6.4.26
libyang is YANG data modelling language parser and toolkit written (and providing API) in C.
boolean.c
Go to the documentation of this file.
1 
16 #include "plugins_types.h"
17 
18 #include <stdint.h>
19 #include <stdlib.h>
20 
21 #include "compat.h"
22 #include "dict.h"
23 #include "ly_common.h"
24 #include "plugins_internal.h"
25 
35 static void
36 lyplg_type_lyb_size_boolean(const struct lysc_type *UNUSED(type), enum lyplg_lyb_size_type *size_type,
37  uint64_t *fixed_size_bits)
38 {
39  *size_type = LYPLG_LYB_SIZE_FIXED_BITS;
40  *fixed_size_bits = 1;
41 }
42 
43 static LY_ERR
44 lyplg_type_store_boolean(const struct ly_ctx *ctx, const struct lysc_type *type, const void *value, uint64_t value_size_bits,
45  uint32_t options, LY_VALUE_FORMAT format, void *UNUSED(prefix_data), uint32_t hints,
46  const struct lysc_node *UNUSED(ctx_node), struct lyd_value *storage, struct lys_glob_unres *UNUSED(unres),
47  struct ly_err_item **err)
48 {
49  LY_ERR ret = LY_SUCCESS;
50  uint32_t value_size;
51  uint8_t i;
52 
53  /* init storage */
54  memset(storage, 0, sizeof *storage);
55  storage->realtype = type;
56 
57  /* check value length */
58  ret = lyplg_type_check_value_size("boolean", format, value_size_bits, LYPLG_LYB_SIZE_FIXED_BITS, 1, &value_size, err);
59  LY_CHECK_GOTO(ret, cleanup);
60 
61  if (format == LY_VALUE_LYB) {
62  /* store value */
63  i = *(uint8_t *)value;
64  storage->boolean = i ? 1 : 0;
65 
66  /* store canonical value, it always is */
67  ret = lydict_insert(ctx, i ? "true" : "false", 0, &storage->_canonical);
68  LY_CHECK_GOTO(ret, cleanup);
69 
70  /* success */
71  goto cleanup;
72  }
73 
74  /* check hints */
75  ret = lyplg_type_check_hints(hints, value, value_size, type->basetype, NULL, err);
76  LY_CHECK_GOTO(ret, cleanup);
77 
78  /* validate and store the value */
79  if ((value_size == ly_strlen_const("true")) && !strncmp(value, "true", ly_strlen_const("true"))) {
80  i = 1;
81  } else if ((value_size == ly_strlen_const("false")) && !strncmp(value, "false", ly_strlen_const("false"))) {
82  i = 0;
83  } else {
84  ret = ly_err_new(err, LY_EVALID, LYVE_DATA, NULL, NULL, "Invalid boolean value \"%.*s\".", (int)value_size,
85  (char *)value);
86  goto cleanup;
87  }
88  storage->boolean = i;
89 
90  /* store canonical value, it always is */
91  if (options & LYPLG_TYPE_STORE_DYNAMIC) {
92  ret = lydict_insert_zc(ctx, (char *)value, &storage->_canonical);
93  options &= ~LYPLG_TYPE_STORE_DYNAMIC;
94  LY_CHECK_GOTO(ret, cleanup);
95  } else {
96  ret = lydict_insert(ctx, value, value_size, &storage->_canonical);
97  LY_CHECK_GOTO(ret, cleanup);
98  }
99 
100 cleanup:
101  if (options & LYPLG_TYPE_STORE_DYNAMIC) {
102  free((char *)value);
103  }
104 
105  if (ret) {
106  lyplg_type_free_simple(ctx, storage);
107  }
108  return ret;
109 }
110 
111 static LY_ERR
112 lyplg_type_compare_boolean(const struct ly_ctx *UNUSED(ctx), const struct lyd_value *val1, const struct lyd_value *val2)
113 {
114  if (val1->boolean != val2->boolean) {
115  return LY_ENOT;
116  }
117  return LY_SUCCESS;
118 }
119 
120 static int
121 lyplg_type_sort_boolean(const struct ly_ctx *UNUSED(ctx), const struct lyd_value *val1, const struct lyd_value *val2)
122 {
123  if (val1->boolean > val2->boolean) {
124  return 1;
125  } else if (val1->boolean < val2->boolean) {
126  return -1;
127  } else {
128  return 0;
129  }
130 }
131 
132 static const void *
133 lyplg_type_print_boolean(const struct ly_ctx *UNUSED(ctx), const struct lyd_value *value, LY_VALUE_FORMAT format,
134  void *UNUSED(prefix_data), ly_bool *dynamic, uint64_t *value_size_bits)
135 {
136  if (format == LY_VALUE_LYB) {
137  *dynamic = 0;
138  if (value_size_bits) {
139  *value_size_bits = 1;
140  }
141  return &value->boolean;
142  }
143 
144  /* use the cached canonical value */
145  if (dynamic) {
146  *dynamic = 0;
147  }
148  if (value_size_bits) {
149  *value_size_bits = strlen(value->_canonical) * 8;
150  }
151  return value->_canonical;
152 }
153 
161 const struct lyplg_type_record plugins_boolean[] = {
162  {
163  .module = "",
164  .revision = NULL,
165  .name = LY_TYPE_BOOL_STR,
166 
167  .plugin.id = "ly2 boolean",
168  .plugin.lyb_size = lyplg_type_lyb_size_boolean,
169  .plugin.store = lyplg_type_store_boolean,
170  .plugin.validate_value = NULL,
171  .plugin.validate_tree = NULL,
172  .plugin.compare = lyplg_type_compare_boolean,
173  .plugin.sort = lyplg_type_sort_boolean,
174  .plugin.print = lyplg_type_print_boolean,
175  .plugin.duplicate = lyplg_type_dup_simple,
176  .plugin.free = lyplg_type_free_simple,
177  },
178  {0}
179 };
const struct lyplg_type_record plugins_boolean[]
Plugin information for boolean type implementation.
Definition: boolean.c:161
libyang dictionary
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_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,...
LY_ERR
libyang's error codes returned by the libyang functions.
Definition: log.h:252
@ LYVE_DATA
Definition: log.h:290
@ LY_ENOT
Definition: log.h:266
@ LY_EVALID
Definition: log.h:260
@ LY_SUCCESS
Definition: log.h:253
Libyang full error structure.
Definition: log.h:298
const char * module
lyplg_lyb_size_type
Type of the LYB size of a value of a particular 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's hints (if any) in the specified format.
LIBYANG_API_DECL LY_ERR lyplg_type_check_value_size(const char *type_name, LY_VALUE_FORMAT format, uint64_t value_size_bits, enum lyplg_lyb_size_type lyb_size_type, uint64_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.
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 an error structure.
@ LYPLG_LYB_SIZE_FIXED_BITS
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.
#define LYPLG_TYPE_STORE_DYNAMIC
LY_DATA_TYPE basetype
Definition: tree_schema.h:1278
Compiled YANG data node.
Definition: tree_schema.h:1412
uint8_t ly_bool
Type to indicate boolean value.
Definition: log.h:29
API for (user) types plugins.
const struct lysc_type * realtype
Definition: tree_data.h:614
const char * _canonical
Definition: tree_data.h:611
YANG data representation.
Definition: tree_data.h:610
LY_VALUE_FORMAT
All kinds of supported value formats and prefix mappings to modules.
Definition: utils.h:93
@ LY_VALUE_LYB
Definition: utils.h:100