/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _DICT_H #define _DICT_H #include #include #include #include "common-utils.h" #include "libglusterfs-messages.h" typedef struct _data data_t; typedef struct _dict dict_t; typedef struct _data_pair data_pair_t; #define GF_PROTOCOL_DICT_SERIALIZE(this,from_dict,to,len,ope,labl) do { \ int _ret = 0; \ \ if (!from_dict) \ break; \ \ _ret = dict_allocate_and_serialize (from_dict, to, &len);\ if (_ret < 0) { \ gf_msg (this->name, GF_LOG_WARNING, 0, \ LG_MSG_DICT_SERIAL_FAILED, \ "failed to get serialized dict (%s)", \ (#from_dict)); \ ope = EINVAL; \ goto labl; \ } \ } while (0) #define GF_PROTOCOL_DICT_UNSERIALIZE(xl,to,buff,len,ret,ope,labl) do { \ if (!len) \ break; \ to = dict_new(); \ GF_VALIDATE_OR_GOTO (xl->name, to, labl); \ \ ret = dict_unserialize (buff, len, &to); \ if (ret < 0) { \ gf_msg (xl->name, GF_LOG_WARNING, 0, \ LG_MSG_DICT_UNSERIAL_FAILED, \ "failed to unserialize dictionary (%s)", \ (#to)); \ \ ope = EINVAL; \ goto labl; \ } \ \ } while (0) struct _data { unsigned char is_static:1; unsigned char is_const:1; int32_t len; char *data; int32_t refcount; gf_lock_t lock; }; struct _data_pair { struct _data_pair *hash_next; struct _data_pair *prev; struct _data_pair *next; data_t *value; char *key; }; struct _dict { unsigned char is_static:1; int32_t hash_size; int32_t count; int32_t refcount; data_pair_t **members; data_pair_t *members_list; char *extra_free; char *extra_stdfree; gf_lock_t lock; data_pair_t *members_internal; data_pair_t free_pair; gf_boolean_t free_pair_in_use; }; typedef gf_boolean_t (*dict_match_t) (dict_t *d, char *k, data_t *v, void *data); int32_t is_data_equal (data_t *one, data_t *two); void data_destroy (data_t *data); /* function to set a key/value pair (overwrite existing if matches the key */ int32_t dict_set (dict_t *this, char *key, data_t *value); /* function to set a new key/value pair (without checking for duplicate) */ int32_t dict_add (dict_t *this, char *key, data_t *value); data_t *dict_get (dict_t *this, char *key); void dict_del (dict_t *this, char *key); int dict_reset (dict_t *dict); int dict_key_count (dict_t *this); int32_t dict_serialized_length (dict_t *dict); int32_t dict_serialize (dict_t *dict, char *buf); int32_t dict_unserialize (char *buf, int32_t size, dict_t **fill); int32_t dict_allocate_and_serialize (dict_t *this, char **buf, u_int *length); void dict_unref (dict_t *dict); dict_t *dict_ref (dict_t *dict); data_t *data_ref (data_t *data); void data_unref (data_t *data); int32_t dict_lookup (dict_t *this, char *key, data_t **data); /* TODO: provide converts for different byte sizes, signedness, and void * */ data_t *int_to_data (int64_t value); data_t *str_to_data (char *value); data_t *data_from_dynstr (char *value); data_t *data_from_dynptr (void *value, int32_t len); data_t *bin_to_data (void *value, int32_t len); data_t *static_str_to_data (char *value); data_t *static_bin_to_data (void *value); int64_t data_to_int64 (data_t *data); int32_t data_to_int32 (data_t *data); int16_t data_to_int16 (data_t *data); int8_t data_to_int8 (data_t *data); uint64_t data_to_uint64 (data_t *data); uint32_t data_to_uint32 (data_t *data); uint16_t data_to_uint16 (data_t *data); uint8_t data_to_uint8 (data_t *data); data_t *data_from_int64 (int64_t value); data_t *data_from_int32 (int32_t value); data_t *data_from_int16 (int16_t value); data_t *data_from_int8 (int8_t value); data_t *data_from_uint64 (uint64_t value); data_t *data_from_uint32 (uint32_t value); data_t *data_from_uint16 (uint16_t value); char *data_to_str (data_t *data); void *data_to_bin (data_t *data); void *data_to_ptr (data_t *data); data_t * data_copy (data_t *old); int dict_foreach (dict_t *this, int (*fn)(dict_t *this, char *key, data_t *value, void *data), void *data); int dict_foreach_fnmatch (dict_t *dict, char *pattern, int (*fn)(dict_t *this, char *key, data_t *value, void *data), void *data); int dict_foreach_match (dict_t *dict, gf_boolean_t (*match)(dict_t *this, char *key, data_t *value, void *mdata), void *match_data, int (*action)(dict_t *this, char *key, data_t *value, void *adata), void *action_data); int dict_null_foreach_fn (dict_t *d, char *k, data_t *v, void *tmp); int dict_remove_foreach_fn (dict_t *d, char *k, data_t *v, void *tmp); dict_t *dict_copy (dict_t *this, dict_t *new); dict_t *get_new_dict (void); int dict_keys_join (void *value, int size, dict_t *dict, int (*filter_fn)(char *key)); /* CLEANED UP FUNCTIONS DECLARATIONS */ GF_MUST_CHECK dict_t *dict_new (void); dict_t *dict_copy_with_ref (dict_t *this, dict_t *new); GF_MUST_CHECK int dict_reset (dict_t *dict); GF_MUST_CHECK int dict_get_int8 (dict_t *this, char *key, int8_t *val); GF_MUST_CHECK int dict_set_int8 (dict_t *this, char *key, int8_t val); GF_MUST_CHECK int dict_get_int16 (dict_t *this, char *key, int16_t *val); GF_MUST_CHECK int dict_set_int16 (dict_t *this, char *key, int16_t val); GF_MUST_CHECK int dict_get_int32 (dict_t *this, char *key, int32_t *val); GF_MUST_CHECK int dict_set_int32 (dict_t *this, char *key, int32_t val); GF_MUST_CHECK int dict_get_int64 (dict_t *this, char *key, int64_t *val); GF_MUST_CHECK int dict_set_int64 (dict_t *this, char *key, int64_t val); GF_MUST_CHECK int dict_get_uint16 (dict_t *this, char *key, uint16_t *val); GF_MUST_CHECK int dict_set_uint16 (dict_t *this, char *key, uint16_t val); GF_MUST_CHECK int dict_get_uint32 (dict_t *this, char *key, uint32_t *val); GF_MUST_CHECK int dict_set_uint32 (dict_t *this, char *key, uint32_t val); GF_MUST_CHECK int dict_get_uint64 (dict_t *this, char *key, uint64_t *val); GF_MUST_CHECK int dict_set_uint64 (dict_t *this, char *key, uint64_t val); GF_MUST_CHECK int dict_get_double (dict_t *this, char *key, double *val); GF_MUST_CHECK int dict_set_double (dict_t *this, char *key, double val); GF_MUST_CHECK int dict_set_static_ptr (dict_t *this, char *key, void *ptr); GF_MUST_CHECK int dict_get_ptr (dict_t *this, char *key, void **ptr); GF_MUST_CHECK int dict_get_ptr_and_len (dict_t *this, char *key, void **ptr, int *len); GF_MUST_CHECK int dict_set_ptr (dict_t *this, char *key, void *ptr); GF_MUST_CHECK int dict_set_dynptr (dict_t *this, char *key, void *ptr, size_t size); GF_MUST_CHECK int dict_get_bin (dict_t *this, char *key, void **ptr); GF_MUST_CHECK int dict_set_bin (dict_t *this, char *key, void *ptr, size_t size); GF_MUST_CHECK int dict_set_static_bin (dict_t *this, char *key, void *ptr, size_t size); GF_MUST_CHECK int dict_set_str (dict_t *this, char *key, char *str); GF_MUST_CHECK int dict_set_dynstr (dict_t *this, char *key, char *str); GF_MUST_CHECK int dict_set_dynstr_with_alloc (dict_t *this, char *key, const char *str); GF_MUST_CHECK int dict_add_dynstr_with_alloc (dict_t *this, char *key, char *str); GF_MUST_CHECK int dict_get_str (dict_t *this, char *key, char **str); GF_MUST_CHECK int dict_get_str_boolean (dict_t *this, char *key, int default_val); GF_MUST_CHECK int dict_rename_key (dict_t *this, char *key, char *replace_key); GF_MUST_CHECK int dict_serialize_value_with_delim (dict_t *this, char *buf, int32_t *serz_len, char delimiter); void dict_dump_to_statedump (dict_t *dict, char *dict_name, char *domain); void dict_dump_to_log (dict_t *dict); int dict_dump_to_str (dict_t *dict, char *dump, int dumpsize, char *format); gf_boolean_t dict_match_everything (dict_t *d, char *k, data_t *v, void *data); dict_t * dict_for_key_value (const char *name, const char *value, size_t size); gf_boolean_t are_dicts_equal (dict_t *one, dict_t *two, gf_boolean_t (*match) (dict_t *d, char *k, data_t *v, void *data), gf_boolean_t (*value_ignore) (char *k)); #endif