Loading...
Searching...
No Matches
enumeration.c
Go to the documentation of this file.
#define _GNU_SOURCE /* strdup */
#include "plugins_types.h"
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "libyang.h"
/* additional internal headers for some useful simple macros */
#include "compat.h"
#include "ly_common.h"
#include "plugins_internal.h" /* LY_TYPE_*_STR */
LIBYANG_API_DEF LY_ERR
lyplg_type_store_enum(const struct ly_ctx *ctx, const struct lysc_type *type, const void *value, size_t value_len,
uint32_t options, LY_VALUE_FORMAT format, void *UNUSED(prefix_data), uint32_t hints,
const struct lysc_node *UNUSED(ctx_node), struct lyd_value *storage, struct lys_glob_unres *UNUSED(unres),
struct ly_err_item **err)
{
struct lysc_type_enum *type_enum = (struct lysc_type_enum *)type;
LY_ERR ret = LY_SUCCESS;
LY_ARRAY_COUNT_TYPE u;
ly_bool found = 0;
int64_t num = 0;
int32_t num_val;
/* init storage */
memset(storage, 0, sizeof *storage);
storage->realtype = type;
if (format == LY_VALUE_LYB) {
/* validation */
if (value_len != 4) {
ret = ly_err_new(err, LY_EVALID, LYVE_DATA, NULL, NULL, "Invalid LYB enumeration value size %zu (expected 4).",
value_len);
goto cleanup;
}
/* convert the value to host byte order */
memcpy(&num, value, value_len);
num = le64toh(num);
num_val = num;
/* find the matching enumeration value item */
LY_ARRAY_FOR(type_enum->enums, u) {
if (type_enum->enums[u].value == num_val) {
found = 1;
break;
}
}
if (!found) {
/* value not found */
ret = ly_err_new(err, LY_EVALID, LYVE_DATA, NULL, NULL, "Invalid enumeration value % " PRIi32 ".", num_val);
goto cleanup;
}
/* store value */
storage->enum_item = &type_enum->enums[u];
/* canonical settings via dictionary due to free callback */
ret = lydict_insert(ctx, type_enum->enums[u].name, 0, &storage->_canonical);
LY_CHECK_GOTO(ret, cleanup);
/* success */
goto cleanup;
}
/* check hints */
ret = lyplg_type_check_hints(hints, value, value_len, type->basetype, NULL, err);
LY_CHECK_GOTO(ret, cleanup);
/* find the matching enumeration value item */
LY_ARRAY_FOR(type_enum->enums, u) {
if (!ly_strncmp(type_enum->enums[u].name, value, value_len)) {
found = 1;
break;
}
}
if (!found) {
/* enum not found */
ret = ly_err_new(err, LY_EVALID, LYVE_DATA, NULL, NULL, "Invalid enumeration value \"%.*s\".", (int)value_len,
(char *)value);
goto cleanup;
}
/* store value */
storage->enum_item = &type_enum->enums[u];
/* store canonical value, it always is */
if (options & LYPLG_TYPE_STORE_DYNAMIC) {
ret = lydict_insert_zc(ctx, (char *)value, &storage->_canonical);
options &= ~LYPLG_TYPE_STORE_DYNAMIC;
LY_CHECK_GOTO(ret, cleanup);
} else {
ret = lydict_insert(ctx, value, value_len, &storage->_canonical);
LY_CHECK_GOTO(ret, cleanup);
}
cleanup:
if (options & LYPLG_TYPE_STORE_DYNAMIC) {
free((void *)value);
}
if (ret) {
lyplg_type_free_simple(ctx, storage);
}
return ret;
}
LIBYANG_API_DEF int
lyplg_type_sort_enum(const struct ly_ctx *UNUSED(ctx), const struct lyd_value *val1,
const struct lyd_value *val2)
{
if (val1->enum_item->value > val2->enum_item->value) {
return -1;
} else if (val1->enum_item->value < val2->enum_item->value) {
return 1;
} else {
return 0;
}
}
LIBYANG_API_DEF const void *
lyplg_type_print_enum(const struct ly_ctx *UNUSED(ctx), const struct lyd_value *value, LY_VALUE_FORMAT format,
void *UNUSED(prefix_data), ly_bool *dynamic, size_t *value_len)
{
int64_t prev_num = 0, num = 0;
void *buf;
if (format == LY_VALUE_LYB) {
prev_num = num = value->enum_item->value;
num = htole64(num);
if (num == prev_num) {
/* values are equal, little-endian */
*dynamic = 0;
if (value_len) {
*value_len = 4;
}
return &value->enum_item->value;
} else {
/* values differ, big-endian */
buf = calloc(1, 4);
LY_CHECK_RET(!buf, NULL);
*dynamic = 1;
if (value_len) {
*value_len = 4;
}
memcpy(buf, &num, 4);
return buf;
}
}
/* use the cached canonical value */
if (dynamic) {
*dynamic = 0;
}
if (value_len) {
*value_len = strlen(value->_canonical);
}
return value->_canonical;
}
const struct lyplg_type_record plugins_enumeration[] = {
{
.module = "",
.revision = NULL,
.name = LY_TYPE_ENUM_STR,
.plugin.id = "libyang 2 - enumeration, version 1",
.plugin.store = lyplg_type_store_enum,
.plugin.validate = NULL,
.plugin.compare = lyplg_type_compare_simple,
.plugin.sort = lyplg_type_sort_enum,
.plugin.print = lyplg_type_print_enum,
.plugin.duplicate = lyplg_type_dup_simple,
.plugin.free = lyplg_type_free_simple,
.plugin.lyb_data_len = 4,
},
{0}
};
lyplg_type_sort_enum
LIBYANG_API_DEF int lyplg_type_sort_enum(const struct ly_ctx *UNUSED(ctx), const struct lyd_value *val1, const struct lyd_value *val2)
Definition enumeration.c:138
lyplg_type_store_enum
LIBYANG_API_DEF LY_ERR lyplg_type_store_enum(const struct ly_ctx *ctx, const struct lysc_type *type, const void *value, size_t value_len, uint32_t options, LY_VALUE_FORMAT format, void *UNUSED(prefix_data), uint32_t hints, const struct lysc_node *UNUSED(ctx_node), struct lyd_value *storage, struct lys_glob_unres *UNUSED(unres), struct ly_err_item **err)
Definition enumeration.c:40
plugins_enumeration
const struct lyplg_type_record plugins_enumeration[]
Plugin information for enumeration type implementation.
Definition enumeration.c:198
lyplg_type_print_enum
LIBYANG_API_DEF const void * lyplg_type_print_enum(const struct ly_ctx *UNUSED(ctx), const struct lyd_value *value, LY_VALUE_FORMAT format, void *UNUSED(prefix_data), ly_bool *dynamic, size_t *value_len)
Definition enumeration.c:151
ly_ctx
libyang context handler.
lydict_insert
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...
lydict_insert_zc
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
LY_ERR
libyang's error codes returned by the libyang functions.
Definition log.h:237
LYVE_DATA
@ LYVE_DATA
Definition log.h:274
LY_EVALID
@ LY_EVALID
Definition log.h:245
LY_SUCCESS
@ LY_SUCCESS
Definition log.h:238
ly_err_item
Libyang full error structure.
Definition log.h:282
lyplg_type_sort_enum
LIBYANG_API_DEF int lyplg_type_sort_enum(const struct ly_ctx *ctx, const struct lyd_value *val1, const struct lyd_value *val2)
Implementation of lyplg_type_sort_clb for the built-in enumeration type.
lyplg_type_print_enum
LIBYANG_API_DECL const void * lyplg_type_print_enum(const struct ly_ctx *ctx, const struct lyd_value *value, LY_VALUE_FORMAT format, void *prefix_data, ly_bool *dynamic, size_t *value_len)
Implementation of lyplg_type_print_clb for the built-in enumeration type.
lyplg_type_store_enum
LIBYANG_API_DECL LY_ERR lyplg_type_store_enum(const struct ly_ctx *ctx, const struct lysc_type *type, const void *value, size_t value_len, uint32_t options, LY_VALUE_FORMAT format, void *prefix_data, uint32_t hints, const struct lysc_node *ctx_node, struct lyd_value *storage, struct lys_glob_unres *unres, struct ly_err_item **err)
Implementation of lyplg_type_store_clb for the built-in enumeration type.
lyplg_type_check_hints
LIBYANG_API_DECL LY_ERR lyplg_type_check_hints(uint32_t hints, const char *value, size_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.
ly_err_new
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.
lyplg_type_record
Definition plugins_types.h:635
lyplg_type_dup_simple
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.
lyplg_type_free_simple
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.
lyplg_type_compare_simple
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.
LYPLG_TYPE_STORE_DYNAMIC
#define LYPLG_TYPE_STORE_DYNAMIC
Definition plugins_types.h:471
lysc_type::basetype
LY_DATA_TYPE basetype
Definition tree_schema.h:1287
lysc_type_enum::enums
struct lysc_type_bitenum_item * enums
Definition tree_schema.h:1345
lysc_type_bitenum_item::name
const char * name
Definition tree_schema.h:1325
lysc_node
Compiled YANG data node.
Definition tree_schema.h:1421
lysc_type
Definition tree_schema.h:1283
lysc_type_enum
Definition tree_schema.h:1338
LY_ARRAY_FOR
#define LY_ARRAY_FOR(ARRAY,...)
Sized-array iterator (for-loop).
Definition tree.h:167
LY_VALUE_FORMAT
LY_VALUE_FORMAT
All kinds of supported value formats and prefix mappings to modules.
Definition tree.h:234
LY_ARRAY_COUNT_TYPE
#define LY_ARRAY_COUNT_TYPE
Type (i.e. size) of the sized array's size counter.
Definition tree.h:104
LY_VALUE_LYB
@ LY_VALUE_LYB
Definition tree.h:240
libyang.h
The main libyang public header.
ly_bool
uint8_t ly_bool
Type to indicate boolean value.
Definition log.h:35
plugins_types.h
API for (user) types plugins.
lyd_value::realtype
const struct lysc_type * realtype
Definition tree_data.h:571
lyd_value::_canonical
const char * _canonical
Definition tree_data.h:568
lyd_value
YANG data representation.
Definition tree_data.h:567