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
string.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 
45 static LY_ERR
46 string_check_chars(const char *value, uint32_t value_size, struct ly_err_item **err)
47 {
48  uint32_t len, parsed = 0;
49 
50  while (value_size - parsed) {
51  if (ly_checkutf8(value + parsed, value_size - parsed, &len)) {
52  return ly_err_new(err, LY_EVALID, LYVE_DATA, NULL, NULL, "Invalid character 0x%hhx.", value[parsed]);
53  }
54  parsed += len;
55  }
56 
57  return LY_SUCCESS;
58 }
59 
60 LIBYANG_API_DEF LY_ERR
61 lyplg_type_store_string(const struct ly_ctx *ctx, const struct lysc_type *type, const void *value, uint32_t value_size_bits,
62  uint32_t options, LY_VALUE_FORMAT format, void *UNUSED(prefix_data), uint32_t hints,
63  const struct lysc_node *UNUSED(ctx_node), const struct lysc_ext_instance *UNUSED(top_ext),
64  struct lyd_value *storage, struct lys_glob_unres *UNUSED(unres), struct ly_err_item **err)
65 {
66  LY_ERR ret = LY_SUCCESS;
67  uint32_t value_size;
68 
69  /* init storage */
70  memset(storage, 0, sizeof *storage);
71  storage->realtype = type;
72 
73  /* check value length */
74  ret = lyplg_type_check_value_size("string", format, value_size_bits, LYPLG_LYB_SIZE_VARIABLE_BYTES, 0, &value_size, err);
75  LY_CHECK_GOTO(ret, cleanup);
76 
77  if (!(options & LYPLG_TYPE_STORE_IS_UTF8)) {
78  /* check the UTF-8 encoding */
79  ret = string_check_chars(value, value_size, err);
80  LY_CHECK_GOTO(ret, cleanup);
81  }
82 
83  /* check hints */
84  ret = lyplg_type_check_hints(hints, value, value_size, type->basetype, NULL, err);
85  LY_CHECK_GOTO(ret, cleanup);
86 
87  /* store canonical value */
88  if (options & LYPLG_TYPE_STORE_DYNAMIC) {
89  ret = lydict_insert_zc(ctx, (char *)value, &storage->_canonical);
90  options &= ~LYPLG_TYPE_STORE_DYNAMIC;
91  LY_CHECK_GOTO(ret, cleanup);
92 
93  /* value may have been freed */
94  value = storage->_canonical;
95  } else {
96  ret = lydict_insert(ctx, value_size ? value : "", value_size, &storage->_canonical);
97  LY_CHECK_GOTO(ret, cleanup);
98  }
99 
100  if (!(options & LYPLG_TYPE_STORE_ONLY)) {
101  /* validate value */
102  ret = lyplg_type_validate_value_string(ctx, type, storage, err);
103  LY_CHECK_GOTO(ret, cleanup);
104  }
105 
106 cleanup:
107  if (options & LYPLG_TYPE_STORE_DYNAMIC) {
108  free((void *)value);
109  }
110 
111  if (ret) {
112  lyplg_type_free_simple(ctx, storage);
113  }
114  return ret;
115 }
116 
117 LIBYANG_API_DEF LY_ERR
118 lyplg_type_validate_value_string(const struct ly_ctx *ctx, const struct lysc_type *type, struct lyd_value *storage,
119  struct ly_err_item **err)
120 {
121  LY_ERR ret;
122  struct lysc_type_str *type_str = (struct lysc_type_str *)type;
123  const void *value;
124  size_t value_len;
125 
126  LY_CHECK_ARG_RET(NULL, type, storage, err, LY_EINVAL);
127  value = lyd_value_get_canonical(ctx, storage);
128  value_len = strlen(value);
129  *err = NULL;
130 
131  /* length restriction of the string */
132  if (type_str->length) {
133  /* value_len is in bytes, but we need number of characters here */
134  ret = lyplg_type_validate_range(LY_TYPE_STRING, type_str->length, ly_utf8len(value, value_len), value, value_len, err);
135  LY_CHECK_RET(ret);
136  }
137 
138  /* pattern restrictions */
139  ret = lyplg_type_validate_patterns(ctx, type_str->patterns, value, value_len, err);
140  LY_CHECK_RET(ret);
141 
142  return LY_SUCCESS;
143 }
144 
153  {
154  .module = "",
155  .revision = NULL,
156  .name = LY_TYPE_STRING_STR,
157 
158  .plugin.id = "ly2 string",
159  .plugin.lyb_size = lyplg_type_lyb_size_variable_bytes,
160  .plugin.store = lyplg_type_store_string,
161  .plugin.validate_value = lyplg_type_validate_value_string,
162  .plugin.validate_tree = NULL,
163  .plugin.compare = lyplg_type_compare_simple,
164  .plugin.sort = lyplg_type_sort_simple,
165  .plugin.print = lyplg_type_print_simple,
166  .plugin.duplicate = lyplg_type_dup_simple,
167  .plugin.free = lyplg_type_free_simple,
168  },
169  {0}
170 };
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
LIBYANG_API_DECL const void * lyplg_type_print_simple(const struct ly_ctx *ctx, const struct lyd_value *value, LY_VALUE_FORMAT format, void *prefix_data, ly_bool *dynamic, uint32_t *value_size_bits)
Implementation of lyplg_type_print_clb for a generic simple type.
LIBYANG_API_DECL LY_ERR lyplg_type_compare_simple(const struct ly_ctx *ctx, const struct lyd_value *val1, const struct lyd_value *val2)
Implementation of lyplg_type_compare_clb for a generic simple type.
LY_ERR
libyang&#39;s error codes returned by the libyang functions.
Definition: log.h:240
#define LYPLG_TYPE_STORE_DYNAMIC
LIBYANG_API_DECL LY_ERR lyplg_type_validate_patterns(const struct ly_ctx *ctx, struct lysc_pattern **patterns, const char *str, uint32_t str_len, struct ly_err_item **err)
Data type validator for pattern-restricted string values.
LIBYANG_API_DEF int lyplg_type_sort_simple(const struct ly_ctx *ctx, const struct lyd_value *val1, const struct lyd_value *val2)
Implementation of lyplg_type_sort_clb for a generic simple type.
Definition: log.h:244
The main libyang public header.
LIBYANG_API_DECL void lyplg_type_lyb_size_variable_bytes(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 rounded to bytes...
struct lysc_pattern ** patterns
Definition: tree_schema.h:1334
struct lysc_range * length
Definition: tree_schema.h:1333
YANG data representation.
Definition: tree_data.h:563
const char * _canonical
Definition: tree_data.h:564
Libyang full error structure.
Definition: log.h:285
LIBYANG_API_DECL const char * lyd_value_get_canonical(const struct ly_ctx *ctx, const struct lyd_value *value)
Get the (canonical) value of a lyd_value.
Definition: log.h:277
LIBYANG_API_DECL LY_ERR lyplg_type_validate_value_string(const struct ly_ctx *ctx, const struct lysc_type *type, struct lyd_value *storage, struct ly_err_item **err)
Implementation of lyplg_type_validate_value_clb for the string type.
Definition: string.c:118
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.
#define LYPLG_TYPE_STORE_IS_UTF8
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
struct lyplg_type_record plugins_string[]
Plugin information for string type implementation.
Definition: string.c:152
LIBYANG_API_DECL LY_ERR lyplg_type_store_string(const struct ly_ctx *ctx, const struct lysc_type *type, const void *value, uint32_t value_len, uint32_t options, LY_VALUE_FORMAT format, void *prefix_data, uint32_t hints, const struct lysc_node *ctx_node, const struct lysc_ext_instance *top_ext, struct lyd_value *storage, struct lys_glob_unres *unres, struct ly_err_item **err)
Implementation of lyplg_type_store_clb for the built-in string type.
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_TYPE_STORE_ONLY