42 #include <qb/qbdefs.h>
46 #define ICMAP_MAX_VALUE_LEN (16*1024)
85 static int icmap_check_key_name(
const char *key_name);
101 static int32_t icmap_tt_to_qbtt(int32_t track_type);
106 static int32_t icmap_qbtt_to_tt(int32_t track_type);
116 static int icmap_is_valid_name_char(
char c);
123 const char *key_name,
134 const char *key_name,
142 static int32_t icmap_tt_to_qbtt(int32_t track_type)
147 res |= QB_MAP_NOTIFY_DELETED;
151 res |= QB_MAP_NOTIFY_REPLACED;
155 res |= QB_MAP_NOTIFY_INSERTED;
159 res |= QB_MAP_NOTIFY_RECURSIVE;
165 static int32_t icmap_qbtt_to_tt(int32_t track_type)
169 if (track_type & QB_MAP_NOTIFY_DELETED) {
173 if (track_type & QB_MAP_NOTIFY_REPLACED) {
177 if (track_type & QB_MAP_NOTIFY_INSERTED) {
181 if (track_type & QB_MAP_NOTIFY_RECURSIVE) {
188 static void icmap_map_free_cb(uint32_t event,
189 char* key,
void* old_value,
197 if (item != NULL && value != old_value) {
207 *result = malloc(
sizeof(
struct icmap_map));
208 if (*result == NULL) {
212 (*result)->qb_map = qb_trie_create();
213 if ((*result)->qb_map == NULL)
216 err = qb_map_notify_add((*result)->qb_map, NULL, icmap_map_free_cb, QB_MAP_NOTIFY_FREE, NULL);
226 static void icmap_set_ro_access_free(
void)
228 struct list_head *iter = icmap_ro_access_item_list_head.
next;
231 while (iter != &icmap_ro_access_item_list_head) {
233 list_del(&icmap_ro_ai->
list);
236 iter = icmap_ro_access_item_list_head.
next;
240 static void icmap_del_all_track(
void)
245 while (iter != &icmap_track_list_head) {
248 iter = icmap_track_list_head.
next;
255 qb_map_destroy(map->
qb_map);
264 icmap_del_all_track();
273 icmap_set_ro_access_free();
281 return (icmap_global_map);
284 static int icmap_is_valid_name_char(
char c)
286 return ((c >=
'a' && c <=
'z') ||
287 (c >=
'A' && c <=
'Z') ||
288 (c >=
'0' && c <=
'9') ||
289 c ==
'.' || c ==
'_' || c ==
'-' || c ==
'/' || c ==
':');
296 for (i = 0; i < strlen(key_name); i++) {
297 if (!icmap_is_valid_name_char(key_name[i])) {
303 static int icmap_check_key_name(
const char *
key_name)
311 for (i = 0; i < strlen(key_name); i++) {
312 if (!icmap_is_valid_name_char(key_name[i])) {
344 static int icmap_check_value_len(
const void *value,
size_t value_len,
icmap_value_types_t type)
352 if (icmap_get_valuetype_len(type) == value_len) {
364 if (value_len > strlen((
const char *)value) + 1) {
378 if (item->
type != type) {
383 ptr_len = strlen((
const char *)value);
384 if (ptr_len > value_len) {
393 return (memcmp(item->
value, value, value_len) == 0);
401 const char *key_name1,
403 const char *key_name2)
407 if (map1 == NULL || key_name1 == NULL || map2 == NULL || key_name2 == NULL) {
411 item1 = qb_map_get(map1->
qb_map, key_name1);
412 item2 = qb_map_get(map2->
qb_map, key_name2);
414 if (item1 == NULL || item2 == NULL) {
423 const char *key_name,
430 size_t new_value_len;
431 size_t new_item_size;
433 if (value == NULL || key_name == NULL) {
437 if (icmap_check_value_len(value, value_len, type) != 0) {
441 item = qb_map_get(map->
qb_map, key_name);
446 if (icmap_item_eq(item, value, value_len, type)) {
450 if (icmap_check_key_name(key_name) != 0) {
457 new_value_len = strlen((
const char *)value);
458 if (new_value_len > value_len) {
466 new_value_len = icmap_get_valuetype_len(type);
469 new_item_size =
sizeof(
struct icmap_item) + new_value_len;
470 new_item = malloc(new_item_size);
471 if (new_item == NULL) {
474 memset(new_item, 0, new_item_size);
477 new_item->key_name = strdup(key_name);
478 if (new_item->key_name == NULL) {
483 new_item->key_name = item->
key_name;
487 new_item->type =
type;
488 new_item->value_len = new_value_len;
490 memcpy(new_item->value, value, new_value_len);
493 ((
char *)new_item->value)[new_value_len - 1] = 0;
496 qb_map_put(map->
qb_map, new_item->key_name, new_item);
502 const char *key_name,
508 return (
icmap_set_r(icmap_global_map, key_name, value, value_len, type));
651 if (key_name == NULL) {
655 item = qb_map_get(map->
qb_map, key_name);
675 const char *key_name,
682 if (key_name == NULL) {
686 item = qb_map_get(map->
qb_map, key_name);
695 if (value_len != NULL) {
700 *value = item->
value;
708 const char *key_name,
715 size_t tmp_value_len;
717 res = icmap_get_ref_r(map, key_name, &tmp_value, &tmp_value_len, type);
723 if (value_len != NULL) {
724 *value_len = tmp_value_len;
727 if (value_len == NULL || *value_len < tmp_value_len) {
731 *value_len = tmp_value_len;
733 memcpy(value, tmp_value, tmp_value_len);
740 const char *key_name,
746 return (
icmap_get_r(icmap_global_map, key_name, value, value_len, type));
751 const char *key_name,
760 key_size =
sizeof(key_value);
761 memset(key_value, 0, key_size);
763 err =
icmap_get(key_name, key_value, &key_size, &key_type);
767 if (key_type != type) {
771 memcpy(value, key_value, icmap_get_valuetype_len(key_type));
902 res =
icmap_get(key_name, NULL, &str_len, &type);
911 *str = malloc(str_len);
918 res =
icmap_get(key_name, *str, &str_len, &type);
932 const char *key_name,
942 if (key_name == NULL) {
946 item = qb_map_get(map->
qb_map, key_name);
951 switch (item->
type) {
954 memcpy(&u8, item->
value,
sizeof(u8));
960 memcpy(&u16, item->
value,
sizeof(u16));
966 memcpy(&u32, item->
value,
sizeof(u32));
972 memcpy(&u64, item->
value,
sizeof(u64));
988 const char *key_name,
997 const char *key_name,
1003 if (key_name == NULL) {
1007 item = qb_map_get(map->
qb_map, key_name);
1012 switch (item->
type) {
1015 *(uint8_t *)item->
value += step;
1019 *(uint16_t *)item->
value += step;
1023 *(uint32_t *)item->
value += step;
1027 *(uint64_t *)item->
value += step;
1045 const char *key_name,
1094 return (qb_map_pref_iter_create(map->
qb_map, prefix));
1108 res = qb_map_iter_next(iter, (
void **)&item);
1113 if (value_len != NULL) {
1126 qb_map_iter_free(iter);
1129 static void icmap_notify_fn(uint32_t event,
char *key,
void *old_value,
void *value,
void *user_data)
1137 if (value == NULL && old_value == NULL) {
1141 if (new_item != NULL) {
1144 new_val.data = new_item->
value;
1146 memset(&new_val, 0,
sizeof(new_val));
1152 if (old_item != NULL && old_item != new_item) {
1153 old_val.type = old_item->
type;
1155 old_val.data = old_item->
value;
1157 memset(&old_val, 0,
sizeof(old_val));
1160 icmap_track->
notify_fn(icmap_qbtt_to_tt(event),
1168 const char *key_name,
1176 if (notify_fn == NULL || icmap_track == NULL) {
1180 if ((track_type & ~(ICMAP_TRACK_ADD | ICMAP_TRACK_DELETE | ICMAP_TRACK_MODIFY | ICMAP_TRACK_PREFIX)) != 0) {
1184 *icmap_track = malloc(
sizeof(**icmap_track));
1185 if (*icmap_track == NULL) {
1188 memset(*icmap_track, 0,
sizeof(**icmap_track));
1190 if (key_name != NULL) {
1191 (*icmap_track)->key_name = strdup(key_name);
1194 (*icmap_track)->track_type = track_type;
1195 (*icmap_track)->notify_fn = notify_fn;
1198 if ((err = qb_map_notify_add(icmap_global_map->
qb_map, (*icmap_track)->key_name, icmap_notify_fn,
1199 icmap_tt_to_qbtt(track_type), *icmap_track)) != 0) {
1200 free((*icmap_track)->key_name);
1206 list_init(&(*icmap_track)->list);
1207 list_add (&(*icmap_track)->list, &icmap_track_list_head);
1216 if ((err = qb_map_notify_del_2(icmap_global_map->
qb_map, icmap_track->
key_name,
1217 icmap_notify_fn, icmap_tt_to_qbtt(icmap_track->
track_type), icmap_track)) != 0) {
1221 list_del(&icmap_track->
list);
1238 for (iter = icmap_ro_access_item_list_head.
next; iter != &icmap_ro_access_item_list_head; iter = iter->
next) {
1241 if (icmap_ro_ai->
prefix == prefix && strcmp(key_name, icmap_ro_ai->
key_name) == 0) {
1248 list_del(&icmap_ro_ai->
list);
1261 icmap_ro_ai = malloc(
sizeof(*icmap_ro_ai));
1262 if (icmap_ro_ai == NULL) {
1266 memset(icmap_ro_ai, 0,
sizeof(*icmap_ro_ai));
1267 icmap_ro_ai->
key_name = strdup(key_name);
1268 if (icmap_ro_ai->
key_name == NULL) {
1274 list_init(&icmap_ro_ai->
list);
1275 list_add (&icmap_ro_ai->
list, &icmap_ro_access_item_list_head);
1285 for (iter = icmap_ro_access_item_list_head.
next; iter != &icmap_ro_access_item_list_head; iter = iter->
next) {
1288 if (icmap_ro_ai->
prefix) {
1289 if (strlen(icmap_ro_ai->
key_name) > strlen(key_name))
1292 if (strncmp(icmap_ro_ai->
key_name, key_name, strlen(icmap_ro_ai->
key_name)) == 0) {
1296 if (strcmp(icmap_ro_ai->
key_name, key_name) == 0) {
1322 while ((key_name =
icmap_iter_next(iter, &value_len, &value_type)) != NULL) {
1323 err = icmap_get_ref_r(src_map, key_name, &value, &value_len, &value_type);
1325 goto exit_iter_finalize;
1328 err =
icmap_set_r(dst_map, key_name, value, value_len, value_type);
1330 goto exit_iter_finalize;