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
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 "libyang.h"
22 
23 /* additional internal headers for some useful simple macros */
24 #include "compat.h"
25 #include "ly_common.h"
26 #include "plugins_internal.h" /* LY_TYPE_*_STR */
27 
37 static void
38 lyplg_type_lyb_size_boolean(const struct lysc_type *UNUSED(type), enum lyplg_lyb_size_type *size_type,
39  uint32_t *fixed_size_bits)
40 {
41  *size_type = LYPLG_LYB_SIZE_FIXED_BITS;
42  *fixed_size_bits = 1;
43 }
44 
45 static LY_ERR
46 lyplg_type_store_boolean(const struct ly_ctx *ctx, const struct lysc_type *type, const void *value, uint32_t value_size_bits,
47  uint32_t options, LY_VALUE_FORMAT format, void *UNUSED(prefix_data), uint32_t hints,
48  const struct lysc_node *UNUSED(ctx_node), const struct lysc_ext_instance *UNUSED(top_ext),
49  struct lyd_value *storage, struct lys_glob_unres *UNUSED(unres), struct ly_err_item **err)
50 {
51  LY_ERR ret = LY_SUCCESS;
52  uint32_t value_size;
53  uint8_t i;
54 
55  /* init storage */
56  memset(storage, 0, sizeof *storage);
57  storage->realtype = type;
58 
59  /* check value length */
60  ret = lyplg_type_check_value_size("boolean", format, value_size_bits, LYPLG_LYB_SIZE_FIXED_BITS, 1, &value_size, err);
61  LY_CHECK_GOTO(ret, cleanup);
62 
63  if (format == LY_VALUE_LYB) {
64  /* store value */
65  i = *(uint8_t *)value;
66  storage->boolean = i ? 1 : 0;
67 
68  /* store canonical value, it always is */
69  ret = lydict_insert(ctx, i ? "true" : "false", 0, &storage->_canonical);
70  LY_CHECK_GOTO(ret, cleanup);
71 
72  /* success */
73  goto cleanup;
74  }
75 
76  /* check hints */
77  ret = lyplg_type_check_hints(hints, value, value_size, type->basetype, NULL, err);
78  LY_CHECK_GOTO(ret, cleanup);
79 
80  /* validate and store the value */
81  if ((value_size == ly_strlen_const("true")) && !strncmp(value, "true", ly_strlen_const("true"))) {
82  i = 1;
83  } else if ((value_size == ly_strlen_const("false")) && !strncmp(value, "false", ly_strlen_const("false"))) {
84  i = 0;
85  } else {
86  ret = ly_err_new(err, LY_EVALID, LYVE_DATA, NULL, NULL, "Invalid boolean value \"%.*s\".", (int)value_size,
87  (char *)value);
88  goto cleanup;
89  }
90  storage->boolean = i;
91 
92  /* store canonical value, it always is */
93  if (options & LYPLG_TYPE_STORE_DYNAMIC) {
94  ret = lydict_insert_zc(ctx, (char *)value, &storage->_canonical);
95  options &= ~LYPLG_TYPE_STORE_DYNAMIC;
96  LY_CHECK_GOTO(ret, cleanup);
97  } else {
98  ret = lydict_insert(ctx, value, value_size, &storage->_canonical);
99  LY_CHECK_GOTO(ret, cleanup);
100  }
101 
102 cleanup:
103  if (options & LYPLG_TYPE_STORE_DYNAMIC) {
104  free((char *)value);
105  }
106 
107  if (ret) {
108  lyplg_type_free_simple(ctx, storage);
109  }
110  return ret;
111 }
112 
113 static LY_ERR
114 lyplg_type_compare_boolean(const struct ly_ctx *UNUSED(ctx), const struct lyd_value *val1, const struct lyd_value *val2)
115 {
116  if (val1->boolean != val2->boolean) {
117  return LY_ENOT;
118  }
119  return LY_SUCCESS;
120 }
121 
122 static int
123 lyplg_type_sort_boolean(const struct ly_ctx *UNUSED(ctx), const struct lyd_value *val1, const struct lyd_value *val2)
124 {
125  if (val1->boolean > val2->boolean) {
126  return 1;
127  } else if (val1->boolean < val2->boolean) {
128  return -1;
129  } else {
130  return 0;
131  }
132 }
133 
134 static const void *
135 lyplg_type_print_boolean(const struct ly_ctx *UNUSED(ctx), const struct lyd_value *value, LY_VALUE_FORMAT format,
136  void *UNUSED(prefix_data), ly_bool *dynamic, uint32_t *value_size_bits)
137 {
138  if (format == LY_VALUE_LYB) {
139  *dynamic = 0;
140  if (value_size_bits) {
141  *value_size_bits = 1;
142  }
143  return &value->boolean;
144  }
145 
146  /* use the cached canonical value */
147  if (dynamic) {
148  *dynamic = 0;
149  }
150  if (value_size_bits) {
151  *value_size_bits = strlen(value->_canonical) * 8;
152  }
153  return value->_canonical;
154 }
155 
163 const struct lyplg_type_record plugins_boolean[] = {
164  {
165  .module = "",
166  .revision = NULL,
167  .name = LY_TYPE_BOOL_STR,
168 
169  .plugin.id = "ly2 boolean",
170  .plugin.lyb_size = lyplg_type_lyb_size_boolean,
171  .plugin.store = lyplg_type_store_boolean,
172  .plugin.validate_value = NULL,
173  .plugin.validate_tree = NULL,
174  .plugin.compare = lyplg_type_compare_boolean,
175  .plugin.sort = lyplg_type_sort_boolean,
176  .plugin.print = lyplg_type_print_boolean,
177  .plugin.duplicate = lyplg_type_dup_simple,
178  .plugin.free = lyplg_type_free_simple,
179  },
180  {0}
181 };
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.
lyplg_lyb_size_type
Type of the LYB size of a value of a particular type.
YANG extension compiled instance.
Definition: plugins_exts.h:436
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
The main libyang public header.
YANG data representation.
Definition: tree_data.h:563
const char * _canonical
Definition: tree_data.h:564
Libyang full error structure.
Definition: log.h:285
Definition: log.h:277
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:248
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: 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.