42 #include <qb/qbdefs.h> 43 #include <qb/qblist.h> 46 #define ICMAP_MAX_VALUE_LEN (16*1024) 66 struct qb_list_head list;
72 struct qb_list_head list;
85 static int icmap_check_key_name(
const char *
key_name);
101 static int icmap_is_valid_name_char(
char c);
132 res |= QB_MAP_NOTIFY_DELETED;
136 res |= QB_MAP_NOTIFY_REPLACED;
140 res |= QB_MAP_NOTIFY_INSERTED;
144 res |= QB_MAP_NOTIFY_RECURSIVE;
154 if (track_type & QB_MAP_NOTIFY_DELETED) {
158 if (track_type & QB_MAP_NOTIFY_REPLACED) {
162 if (track_type & QB_MAP_NOTIFY_INSERTED) {
166 if (track_type & QB_MAP_NOTIFY_RECURSIVE) {
173 static void icmap_map_free_cb(uint32_t event,
174 char* key,
void* old_value,
182 if (item != NULL &&
value != old_value) {
192 *result = malloc(
sizeof(
struct icmap_map));
193 if (*result == NULL) {
197 (*result)->qb_map = qb_trie_create();
198 if ((*result)->qb_map == NULL)
201 err = qb_map_notify_add((*result)->qb_map, NULL, icmap_map_free_cb, QB_MAP_NOTIFY_FREE, NULL);
211 static void icmap_set_ro_access_free(
void)
213 struct qb_list_head *iter, *tmp_iter;
216 qb_list_for_each_safe(iter, tmp_iter, &icmap_ro_access_item_list_head) {
218 qb_list_del(&icmap_ro_ai->
list);
224 static void icmap_del_all_track(
void)
226 struct qb_list_head *iter, *tmp_iter;
229 qb_list_for_each_safe(iter, tmp_iter, &icmap_track_list_head) {
230 icmap_track = qb_list_entry(iter,
struct icmap_track,
list);
239 qb_map_destroy(map->
qb_map);
248 icmap_del_all_track();
257 icmap_set_ro_access_free();
265 return (icmap_global_map);
268 static int icmap_is_valid_name_char(
char c)
270 return ((c >=
'a' && c <=
'z') ||
271 (c >=
'A' && c <=
'Z') ||
272 (c >=
'0' && c <=
'9') ||
273 c ==
'.' || c ==
'_' || c ==
'-' || c ==
'/' || c ==
':');
280 for (i = 0; i < strlen(key_name); i++) {
281 if (!icmap_is_valid_name_char(key_name[i])) {
287 static int icmap_check_key_name(
const char *
key_name)
295 for (i = 0; i < strlen(key_name); i++) {
296 if (!icmap_is_valid_name_char(key_name[i])) {
362 if (item->
type != type) {
367 ptr_len = strlen((
const char *)
value);
385 const char *key_name1,
387 const char *key_name2)
391 if (map1 == NULL || key_name1 == NULL || map2 == NULL || key_name2 == NULL) {
395 item1 = qb_map_get(map1->
qb_map, key_name1);
396 item2 = qb_map_get(map2->
qb_map, key_name2);
398 if (item1 == NULL || item2 == NULL) {
414 size_t new_value_len;
415 size_t new_item_size;
417 if (value == NULL || key_name == NULL) {
421 if (icmap_check_value_len(value, value_len, type) != 0) {
425 item = qb_map_get(map->
qb_map, key_name);
430 if (icmap_item_eq(item, value, value_len, type)) {
434 if (icmap_check_key_name(key_name) != 0) {
441 new_value_len = strlen((
const char *)value);
442 if (new_value_len > value_len) {
453 new_item_size =
sizeof(
struct icmap_item) + new_value_len;
454 new_item = malloc(new_item_size);
455 if (new_item == NULL) {
458 memset(new_item, 0, new_item_size);
461 new_item->key_name = strdup(key_name);
462 if (new_item->key_name == NULL) {
467 new_item->key_name = item->
key_name;
471 new_item->type =
type;
472 new_item->value_len = new_value_len;
474 memcpy(new_item->value, value, new_value_len);
477 ((
char *)new_item->value)[new_value_len - 1] = 0;
480 qb_map_put(map->
qb_map, new_item->key_name, new_item);
492 return (
icmap_set_r(icmap_global_map, key_name, value, value_len, type));
635 if (key_name == NULL) {
639 item = qb_map_get(map->
qb_map, key_name);
699 size_t tmp_value_len;
701 res = icmap_get_ref_r(map, key_name, &tmp_value, &tmp_value_len, type);
707 if (value_len != NULL) {
708 *value_len = tmp_value_len;
711 if (value_len == NULL || *value_len < tmp_value_len) {
715 *value_len = tmp_value_len;
717 memcpy(value, tmp_value, tmp_value_len);
730 return (
icmap_get_r(icmap_global_map, key_name, value, value_len, type));
739 res =
icmap_get_r(map, key_name, NULL, &str_len, &type);
748 *str = malloc(str_len);
755 res =
icmap_get_r(map, key_name, *str, &str_len, &type);
778 key_size =
sizeof(key_value);
779 memset(key_value, 0, key_size);
785 if (key_type != type) {
932 if (key_name == NULL) {
936 item = qb_map_get(map->
qb_map, key_name);
941 switch (item->
type) {
944 memcpy(&u8, item->
value,
sizeof(u8));
950 memcpy(&u16, item->
value,
sizeof(u16));
956 memcpy(&u32, item->
value,
sizeof(u32));
962 memcpy(&u64, item->
value,
sizeof(u64));
993 if (key_name == NULL) {
997 item = qb_map_get(map->
qb_map, key_name);
1002 switch (item->
type) {
1005 *(uint8_t *)item->
value += step;
1009 *(uint16_t *)item->
value += step;
1013 *(uint32_t *)item->
value += step;
1017 *(uint64_t *)item->
value += step;
1084 return (qb_map_pref_iter_create(map->
qb_map, prefix));
1098 res = qb_map_iter_next(iter, (
void **)&item);
1103 if (value_len != NULL) {
1104 *value_len = item->value_len;
1116 qb_map_iter_free(iter);
1119 static void icmap_notify_fn(uint32_t event,
char *key,
void *old_value,
void *
value,
void *
user_data)
1127 if (
value == NULL && old_value == NULL) {
1131 if (new_item != NULL) {
1136 memset(&new_val, 0,
sizeof(new_val));
1142 if (old_item != NULL && old_item != new_item) {
1147 memset(&old_val, 0,
sizeof(old_val));
1166 if (notify_fn == NULL || icmap_track == NULL) {
1174 *icmap_track = malloc(
sizeof(**icmap_track));
1175 if (*icmap_track == NULL) {
1178 memset(*icmap_track, 0,
sizeof(**icmap_track));
1180 if (key_name != NULL) {
1181 (*icmap_track)->key_name = strdup(key_name);
1184 (*icmap_track)->track_type = track_type;
1185 (*icmap_track)->notify_fn = notify_fn;
1188 if ((err = qb_map_notify_add(icmap_global_map->
qb_map, (*icmap_track)->key_name, icmap_notify_fn,
1190 free((*icmap_track)->key_name);
1196 qb_list_init(&(*icmap_track)->list);
1197 qb_list_add (&(*icmap_track)->list, &icmap_track_list_head);
1206 if ((err = qb_map_notify_del_2(icmap_global_map->
qb_map, icmap_track->
key_name,
1211 qb_list_del(&icmap_track->
list);
1225 struct qb_list_head *iter, *tmp_iter;
1228 qb_list_for_each_safe(iter, tmp_iter, &icmap_ro_access_item_list_head) {
1231 if (icmap_ro_ai->
prefix == prefix && strcmp(key_name, icmap_ro_ai->
key_name) == 0) {
1238 qb_list_del(&icmap_ro_ai->
list);
1251 icmap_ro_ai = malloc(
sizeof(*icmap_ro_ai));
1252 if (icmap_ro_ai == NULL) {
1256 memset(icmap_ro_ai, 0,
sizeof(*icmap_ro_ai));
1257 icmap_ro_ai->
key_name = strdup(key_name);
1258 if (icmap_ro_ai->
key_name == NULL) {
1264 qb_list_init(&icmap_ro_ai->
list);
1265 qb_list_add (&icmap_ro_ai->
list, &icmap_ro_access_item_list_head);
1272 struct qb_list_head *iter;
1275 qb_list_for_each(iter, &icmap_ro_access_item_list_head) {
1278 if (icmap_ro_ai->
prefix) {
1279 if (strlen(icmap_ro_ai->
key_name) > strlen(key_name))
1282 if (strncmp(icmap_ro_ai->
key_name, key_name, strlen(icmap_ro_ai->
key_name)) == 0) {
1286 if (strcmp(icmap_ro_ai->
key_name, key_name) == 0) {
1312 while ((key_name =
icmap_iter_next(iter, &value_len, &value_type)) != NULL) {
1313 err = icmap_get_ref_r(src_map, key_name, &value, &value_len, &value_type);
1315 goto exit_iter_finalize;
1318 err =
icmap_set_r(dst_map, key_name, value, value_len, value_type);
1320 goto exit_iter_finalize;
cs_error_t icmap_set_float(const char *key_name, float value)
cs_error_t icmap_set_r(const icmap_map_t map, const char *key_name, const void *value, size_t value_len, icmap_value_types_t type)
Reentrant version of icmap_set.
cs_error_t icmap_get_double(const char *key_name, double *dbl)
icmap_notify_fn_t notify_fn
cs_error_t icmap_get_uint64(const char *key_name, uint64_t *u64)
cs_error_t icmap_set_int16_r(const icmap_map_t map, const char *key_name, int16_t value)
cs_error_t icmap_get_r(const icmap_map_t map, const char *key_name, void *value, size_t *value_len, icmap_value_types_t *type)
Same as icmap_get but it's reentrant and operates on given icmap_map.
cs_error_t icmap_dec_r(const icmap_map_t map, const char *key_name)
icmap_dec_r
cs_error_t icmap_get_int16(const char *key_name, int16_t *i16)
cs_error_t icmap_get_uint8(const char *key_name, uint8_t *u8)
cs_error_t icmap_set_double(const char *key_name, double value)
int32_t icmap_qbtt_to_tt(int32_t track_type)
cs_error_t icmap_track_add(const char *key_name, int32_t track_type, icmap_notify_fn_t notify_fn, void *user_data, icmap_track_t *icmap_track)
Add tracking function for given key_name.
cs_error_t icmap_set_uint64_r(const icmap_map_t map, const char *key_name, uint64_t value)
cs_error_t icmap_set_uint32(const char *key_name, uint32_t value)
cs_error_t icmap_set_uint16_r(const icmap_map_t map, const char *key_name, uint16_t value)
cs_error_t icmap_fast_inc(const char *key_name)
Increase stored value by one.
cs_error_t icmap_get_string_r(icmap_map_t map, const char *key_name, char **str)
cs_error_t icmap_set_int8_r(const icmap_map_t map, const char *key_name, int8_t value)
#define ICMAP_MAX_VALUE_LEN
const char * icmap_iter_next(icmap_iter_t iter, size_t *value_len, icmap_value_types_t *type)
Return next item in iterator iter.
cs_error_t icmap_adjust_int(const char *key_name, int32_t step)
icmap_adjust_int
void icmap_convert_name_to_valid_name(char *key_name)
Converts given key_name to valid key name (replacing all prohibited characters by _) ...
cs_error_t icmap_get_int32(const char *key_name, int32_t *i32)
cs_error_t icmap_track_delete(icmap_track_t icmap_track)
Remove previously added track.
icmap_iter_t icmap_iter_init_r(const icmap_map_t map, const char *prefix)
icmap_iter_init_r
cs_error_t icmap_get_uint32_r(const icmap_map_t map, const char *key_name, uint32_t *u32)
cs_error_t icmap_get_float_r(const icmap_map_t map, const char *key_name, float *flt)
cs_error_t icmap_inc(const char *key_name)
Increase stored value by one.
cs_error_t icmap_get_uint32(const char *key_name, uint32_t *u32)
cs_error_t icmap_init_r(icmap_map_t *result)
Initialize additional (local, reentrant) icmap_map.
cs_error_t icmap_set_int8(const char *key_name, int8_t value)
#define ICMAP_TRACK_DELETE
#define ICMAP_KEYNAME_MAXLEN
Maximum length of key in icmap.
cs_error_t icmap_fast_inc_r(const icmap_map_t map, const char *key_name)
icmap_fast_inc_r
cs_error_t icmap_get_int8_r(const icmap_map_t map, const char *key_name, int8_t *i8)
cs_error_t icmap_set_string_r(const icmap_map_t map, const char *key_name, const char *value)
cs_error_t icmap_set_int64_r(const icmap_map_t map, const char *key_name, int64_t value)
cs_error_t icmap_set_double_r(const icmap_map_t map, const char *key_name, double value)
#define ICMAP_TRACK_MODIFY
icmap_map_t icmap_get_global_map(void)
Return global icmap.
int32_t icmap_tt_to_qbtt(int32_t track_type)
void(* icmap_notify_fn_t)(int32_t event, const char *key_name, struct icmap_notify_value new_value, struct icmap_notify_value old_value, void *user_data)
Prototype for notify callback function.
cs_error_t icmap_set_uint8_r(const icmap_map_t map, const char *key_name, uint8_t value)
cs_error_t icmap_get_int8(const char *key_name, int8_t *i8)
cs_error_t icmap_set_uint64(const char *key_name, uint64_t value)
int icmap_is_key_ro(const char *key_name)
Check in given key is read only.
cs_error_t icmap_fast_adjust_int_r(const icmap_map_t map, const char *key_name, int32_t step)
icmap_fast_adjust_int_r
cs_error_t icmap_set_uint16(const char *key_name, uint16_t value)
cs_error_t icmap_set_int16(const char *key_name, int16_t value)
cs_error_t
The cs_error_t enum.
cs_error_t icmap_get_uint8_r(const icmap_map_t map, const char *key_name, uint8_t *u8)
cs_error_t icmap_delete(const char *key_name)
Delete key from map.
cs_error_t icmap_get_int16_r(const icmap_map_t map, const char *key_name, int16_t *i16)
QB_LIST_DECLARE(icmap_ro_access_item_list_head)
cs_error_t icmap_set_float_r(const icmap_map_t map, const char *key_name, float value)
cs_error_t icmap_get_int64_r(const icmap_map_t map, const char *key_name, int64_t *i64)
cs_error_t icmap_fast_adjust_int(const char *key_name, int32_t step)
icmap_fast_adjust_int
cs_error_t icmap_copy_map(icmap_map_t dst_map, const icmap_map_t src_map)
Copy content of src_map icmap to dst_map icmap.
icmap_iter_t icmap_iter_init(const char *prefix)
Initialize iterator with given prefix.
cs_error_t icmap_init(void)
Initialize global icmap.
void icmap_iter_finalize(icmap_iter_t iter)
Finalize iterator.
cs_error_t icmap_set_int64(const char *key_name, int64_t value)
cs_error_t icmap_get(const char *key_name, void *value, size_t *value_len, icmap_value_types_t *type)
Retrieve value of key key_name and store it in user preallocated value pointer.
cs_error_t icmap_fast_dec_r(const icmap_map_t map, const char *key_name)
icmap_fast_dec_r
cs_error_t icmap_delete_r(const icmap_map_t map, const char *key_name)
icmap_delete_r
cs_error_t icmap_get_int64(const char *key_name, int64_t *i64)
cs_error_t icmap_set_int32(const char *key_name, int32_t value)
int icmap_key_value_eq(const icmap_map_t map1, const char *key_name1, const icmap_map_t map2, const char *key_name2)
Compare value of key with name key_name1 in map1 with key with name key_name2 in map2.
cs_error_t icmap_set_int32_r(const icmap_map_t map, const char *key_name, int32_t value)
cs_error_t icmap_dec(const char *key_name)
Decrease stored value by one.
cs_error_t icmap_set_uint8(const char *key_name, uint8_t value)
struct icmap_track * icmap_track_t
Track type.
size_t icmap_get_valuetype_len(icmap_value_types_t type)
cs_error_t icmap_get_uint16_r(const icmap_map_t map, const char *key_name, uint16_t *u16)
cs_error_t icmap_set_string(const char *key_name, const char *value)
#define ICMAP_KEYNAME_MINLEN
Minimum lenght of key in icmap.
cs_error_t icmap_set_uint32_r(const icmap_map_t map, const char *key_name, uint32_t value)
cs_error_t icmap_adjust_int_r(const icmap_map_t map, const char *key_name, int32_t step)
icmap_adjust_int_r
cs_error_t icmap_inc_r(const icmap_map_t map, const char *key_name)
icmap_inc_r
cs_error_t icmap_set(const char *key_name, const void *value, size_t value_len, icmap_value_types_t type)
Store value with value_len length and type as key_name name in global icmap.
cs_error_t icmap_get_int32_r(const icmap_map_t map, const char *key_name, int32_t *i32)
void icmap_fini(void)
Finalize global icmap.
cs_error_t icmap_get_string(const char *key_name, char **str)
Shortcut for icmap_get for string type.
cs_error_t icmap_get_uint64_r(const icmap_map_t map, const char *key_name, uint64_t *u64)
cs_error_t icmap_fast_dec(const char *key_name)
Decrease stored value by one.
cs_error_t icmap_get_uint16(const char *key_name, uint16_t *u16)
cs_error_t icmap_set_ro_access(const char *key_name, int prefix, int ro_access)
Set read-only access for given key (key_name) or prefix, If prefix is set.
cs_error_t qb_to_cs_error(int result)
qb_to_cs_error
icmap_value_types_t
Possible types of value.
cs_error_t icmap_get_double_r(const icmap_map_t map, const char *key_name, double *dbl)
void icmap_fini_r(const icmap_map_t map)
Finalize local, reentrant icmap.
cs_error_t icmap_get_float(const char *key_name, float *flt)
qb_map_iter_t * icmap_iter_t
Itterator type.
Structure passed as new_value and old_value in change callback.
#define ICMAP_TRACK_PREFIX
Whole prefix is tracked, instead of key only (so "totem." tracking means that "totem.nodeid", "totem.version", ...
void * icmap_track_get_user_data(icmap_track_t icmap_track)
Return user data associated with given track.