Mercurial > libjeffpc
view include/jeffpc/nvl.h @ 822:f8d9ccf26563
nvl: add nvl_lookup_val to easily get at the struct val pointer value
Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
author | Josef 'Jeff' Sipek <jeffpc@josefsipek.net> |
---|---|
date | Fri, 30 Oct 2020 17:57:53 -0400 |
parents | 342a128c5011 |
children | ccb955138113 |
line wrap: on
line source
/* * Copyright (c) 2017-2020 Josef 'Jeff' Sipek <jeffpc@josefsipek.net> * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #ifndef __JEFFPC_NVL_H #define __JEFFPC_NVL_H #include <stdbool.h> #include <jeffpc/val.h> #include <jeffpc/buffer.h> struct nvlist { struct val val; }; /* do not access these directly */ struct nvpair { struct rb_node node; struct str *name; struct val *value; }; enum nvcvtcond { NVCVT_COND_ALWAYS = 0, NVCVT_COND_STR_EMPTY, }; struct nvl_convert_info { const char *name; enum val_type tgt_type; enum nvcvtcond cond; }; #define nvl_alloc() ((struct nvlist *) val_alloc_nvl()) /* * struct val reference counting & casting to struct nvl */ static inline struct nvlist *val_cast_to_nvl(struct val *val) { ASSERT(!val || (val->type == VT_NVL)); return container_of(val, struct nvlist, val); } #define val_getref_nvl(v) val_cast_to_nvl(val_getref(v)) /* * struct nvl reference counting & casting to struct val */ #define nvl_getref(nvl) ((struct nvlist *) val_getref(nvl_cast_to_val(nvl))) #define nvl_putref(nvl) val_putref(nvl_cast_to_val(nvl)) #define nvl_getref_val(nvl) val_getref(nvl_cast_to_val(nvl)) static inline struct val *nvl_cast_to_val(struct nvlist *nvl) { return &nvl->val; } /* * Misc functions */ extern int nvl_merge(struct nvlist *dest, struct nvlist *src); static inline void nvl_dump_file(FILE *out, struct nvlist *nvl) { val_dump_file(out, nvl_cast_to_val(nvl), 0); } /* * If convert_all is true, then all errors except -ENOTSUP encountered * during the conversion are ignored. */ extern int nvl_convert(struct nvlist *nvl, const struct nvl_convert_info *table, bool convert_all); /* serialization & deserialization */ extern struct nvlist *nvl_unpack(const void *ptr, size_t len, enum val_format format); static inline ssize_t nvl_size(struct nvlist *nvl, enum val_format format) { return val_size(nvl_cast_to_val(nvl), format); } static inline ssize_t nvl_pack_into(struct nvlist *nvl, void *buf, size_t bufsize, enum val_format format) { return val_pack_into(nvl_cast_to_val(nvl), buf, bufsize, format); } static inline struct buffer *nvl_pack(struct nvlist *nvl, enum val_format format) { return val_pack(nvl_cast_to_val(nvl), format); } /* iteration */ extern const struct nvpair *nvl_iter_start(struct nvlist *nvl); extern const struct nvpair *nvl_iter_next(struct nvlist *nvl, const struct nvpair *prev); #define nvl_for_each(pair, nvl) \ for (pair = nvl_iter_start(nvl); \ pair != NULL; \ pair = nvl_iter_next(nvl, pair)) /* * There are two types of lookup functions - those that return a pointer and * those than return an int. The functions that return a pointer either * return a valid pointer with a new reference or an errno. The functions * that return an int, return 0 and set the out argument to the value or * return an errno. * * -ENOENT = not found * -ERANGE = wrong type (e.g., looking up an int, but stored value is a string) */ extern int nvl_lookup_array(struct nvlist *nvl, const char *name, struct val ***vals, size_t *nelem); extern int nvl_lookup_blob(struct nvlist *nvl, const char *name, const void **ptr, size_t *size); extern int nvl_lookup_bool(struct nvlist *nvl, const char *name, bool *out); extern int nvl_lookup_int(struct nvlist *nvl, const char *name, uint64_t *out); extern int nvl_lookup_null(struct nvlist *nvl, const char *name); extern const struct nvpair *nvl_lookup(struct nvlist *nvl, const char *name); extern struct nvlist *nvl_lookup_nvl(struct nvlist *nvl, const char *name); extern struct str *nvl_lookup_str(struct nvlist *nvl, const char *name); extern struct val *nvl_lookup_val(struct nvlist *nvl, const char *name); /* * Add a new key-value pair or change the value of an existing key-value * pair. * * always consume val's reference * * -ENOMEM = out of memory */ extern int nvl_set(struct nvlist *nvl, const char *name, struct val *val); extern int nvl_set_array(struct nvlist *nvl, const char *name, struct val **vals, size_t nelem); extern int nvl_set_array_copy(struct nvlist *nvl, const char *name, struct val **vals, size_t nelem); extern int nvl_set_blob(struct nvlist *nvl, const char *name, void *ptr, size_t size); extern int nvl_set_blob_copy(struct nvlist *nvl, const char *name, const void *ptr, size_t size); extern int nvl_set_bool(struct nvlist *nvl, const char *name, bool val); extern int nvl_set_cstr_dup(struct nvlist *nvl, const char *name, const char *val); extern int nvl_set_int(struct nvlist *nvl, const char *name, uint64_t val); extern int nvl_set_null(struct nvlist *nvl, const char *name); extern int nvl_set_nvl(struct nvlist *nvl, const char *name, struct nvlist *val); extern int nvl_set_str(struct nvlist *nvl, const char *name, struct str *val); extern int nvl_set_pair(struct nvlist *nvl, const struct nvpair *pair); /* * Remove a key-value pair from the list. * * -ENOENT = not found * -ERANGE = existing item's type doesn't match requested type */ extern int nvl_unset(struct nvlist *nvl, const char *name); extern int nvl_unset_type(struct nvlist *nvl, const char *name, enum val_type type); /* * Check existence of a specific key, or key-valuetype pair from the list. * * The generic nvl_exists returns true if the item exists and false * otherwise. * * The type-specific checks return: * * -ENOENT = does not exist * -ERANGE = exists, wrong type * 0 = exists, correct type */ extern bool nvl_exists(struct nvlist *nvl, const char *name); extern int nvl_exists_type(struct nvlist *nvl, const char *name, enum val_type type); /* * nvpair related functions */ static inline const char *nvpair_name(const struct nvpair *pair) { return str_cstr(pair->name); } static inline struct str *nvpair_name_str(const struct nvpair *pair) { return str_getref(pair->name); } static inline enum val_type nvpair_type(const struct nvpair *pair) { return pair->value->type; } static inline struct val *nvpair_value(const struct nvpair *pair) { return val_getref(pair->value); } /* * As with the nvl_lookup_* functions, there return either a pointer or an * integer. The meaning of the return values is the same as well. */ extern int nvpair_value_array(const struct nvpair *pair, struct val ***vals, size_t *nelem); extern int nvpair_value_blob(const struct nvpair *pair, const void **ptr, size_t *size); extern int nvpair_value_bool(const struct nvpair *pair, bool *out); extern int nvpair_value_int(const struct nvpair *pair, uint64_t *out); extern int nvpair_value_null(const struct nvpair *pair); extern struct nvlist *nvpair_value_nvl(const struct nvpair *pair); extern struct str *nvpair_value_str(const struct nvpair *pair); #endif