libyang  6.3.1
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
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 };
struct lysc_type * realtype
Definition: tree_data.h:615
Compiled YANG data node.
Definition: tree_schema.h:1430
memset(value->fixed_mem, 0, LYD_VALUE_FIXED_MEM_SIZE)
lyplg_lyb_size_type
Type of the LYB size of a value of a particular type.
LY_ERR
libyang&#39;s error codes returned by the libyang functions.
Definition: log.h:255
uint8_t ly_bool
Type to indicate boolean value.
Definition: log.h:29
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 dictionary
Definition: log.h:269
#define LYPLG_TYPE_STORE_DYNAMIC
YANG data representation.
Definition: tree_data.h:611
const char * _canonical
Definition: tree_data.h:612
Libyang full error structure.
Definition: log.h:301
Definition: log.h:293
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 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...
Definition: log.h:263
const char * module
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.
LY_VALUE_FORMAT
All kinds of supported value formats and prefix mappings to modules.
Definition: utils.h:93
LY_DATA_TYPE basetype
Definition: tree_schema.h:1296
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.