2 * Copyright (c) 2011 Red Hat, Inc.
6 * Author: Jan Friesse (jfriesse@redhat.com)
8 * This software licensed under BSD license, the text of which follows:
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions are met:
13 * - Redistributions of source code must retain the above copyright notice,
14 * this list of conditions and the following disclaimer.
15 * - Redistributions in binary form must reproduce the above copyright notice,
16 * this list of conditions and the following disclaimer in the documentation
17 * and/or other materials provided with the distribution.
18 * - Neither the name of the Red Hat, Inc. nor the names of its
19 * contributors may be used to endorse or promote products derived from this
20 * software without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
32 * THE POSSIBILITY OF SUCH DAMAGE.
40 #include <corosync/corotypes.h>
42 #include <qb/qbdefs.h>
43 #include <corosync/list.h>
44 #include <corosync/icmap.h>
46 #define ICMAP_MAX_VALUE_LEN (16*1024)
50 icmap_value_types_t type
;
59 static icmap_map_t icmap_global_map
;
64 icmap_notify_fn_t notify_fn
;
66 struct list_head list
;
69 struct icmap_ro_access_item
{
72 struct list_head list
;
75 DECLARE_LIST_INIT(icmap_ro_access_item_list_head
);
76 DECLARE_LIST_INIT(icmap_track_list_head
);
79 * Static functions declarations
83 * Check if key_name is valid icmap key name. Returns 0 on success, and -1 on fail
85 static int icmap_check_key_name(const char *key_name
);
88 * Check that value with given type has correct length value_len. Returns 0 on success,
91 static int icmap_check_value_len(const void *value
, size_t value_len
, icmap_value_types_t type
);
94 * Returns length of value of given type, or 0 for string and binary data type
96 static size_t icmap_get_valuetype_len(icmap_value_types_t type
);
99 * Converts track type of icmap to qb
101 static int32_t icmap_tt_to_qbtt(int32_t track_type
);
104 * Convert track type of qb to icmap
106 static int32_t icmap_qbtt_to_tt(int32_t track_type
);
109 * Checks if item has same value as value with value_len and given type. Returns 0 if not, otherwise !0.
111 static int icmap_item_eq(const struct icmap_item
*item
, const void *value
, size_t value_len
, icmap_value_types_t type
);
114 * Checks if given character is valid in key name. Returns 0 if not, otherwise !0.
116 static int icmap_is_valid_name_char(char c
);
119 * Helper for getting integer and float value with given type for key key_name and store it in value.
121 static cs_error_t
icmap_get_int_r(
122 const icmap_map_t map
,
123 const char *key_name
,
125 icmap_value_types_t type
);
128 * Return raw item value data. Internal function used by icmap_get_r which does most
129 * of arguments validity checks but doesn't copy data (it returns raw item data
130 * pointer). It's not very safe tho it's static.
132 static cs_error_t
icmap_get_ref_r(
133 const icmap_map_t map
,
134 const char *key_name
,
137 icmap_value_types_t
*type
);
140 * Function implementation
142 static int32_t icmap_tt_to_qbtt(int32_t track_type
)
146 if (track_type
& ICMAP_TRACK_DELETE
) {
147 res
|= QB_MAP_NOTIFY_DELETED
;
150 if (track_type
& ICMAP_TRACK_MODIFY
) {
151 res
|= QB_MAP_NOTIFY_REPLACED
;
154 if (track_type
& ICMAP_TRACK_ADD
) {
155 res
|= QB_MAP_NOTIFY_INSERTED
;
158 if (track_type
& ICMAP_TRACK_PREFIX
) {
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
) {
170 res
|= ICMAP_TRACK_DELETE
;
173 if (track_type
& QB_MAP_NOTIFY_REPLACED
) {
174 res
|= ICMAP_TRACK_MODIFY
;
177 if (track_type
& QB_MAP_NOTIFY_INSERTED
) {
178 res
|= ICMAP_TRACK_ADD
;
181 if (track_type
& QB_MAP_NOTIFY_RECURSIVE
) {
182 res
|= ICMAP_TRACK_PREFIX
;
188 static void icmap_map_free_cb(uint32_t event
,
189 char* key
, void* old_value
,
190 void* value
, void* user_data
)
192 struct icmap_item
*item
= (struct icmap_item
*)old_value
;
195 * value == old_value -> fast_adjust_int was used, don't free data
197 if (item
!= NULL
&& value
!= old_value
) {
198 free(item
->key_name
);
203 cs_error_t
icmap_init_r(icmap_map_t
*result
)
207 *result
= malloc(sizeof(struct icmap_map
));
208 if (*result
== NULL
) {
209 return (CS_ERR_NO_MEMORY
);
212 (*result
)->qb_map
= qb_trie_create();
213 if ((*result
)->qb_map
== NULL
)
214 return (CS_ERR_INIT
);
216 err
= qb_map_notify_add((*result
)->qb_map
, NULL
, icmap_map_free_cb
, QB_MAP_NOTIFY_FREE
, NULL
);
218 return (qb_to_cs_error(err
));
221 cs_error_t
icmap_init(void)
223 return (icmap_init_r(&icmap_global_map
));
226 static void icmap_set_ro_access_free(void)
228 struct list_head
*iter
= icmap_ro_access_item_list_head
.next
;
229 struct icmap_ro_access_item
*icmap_ro_ai
;
231 while (iter
!= &icmap_ro_access_item_list_head
) {
232 icmap_ro_ai
= list_entry(iter
, struct icmap_ro_access_item
, list
);
233 list_del(&icmap_ro_ai
->list
);
234 free(icmap_ro_ai
->key_name
);
236 iter
= icmap_ro_access_item_list_head
.next
;
240 static void icmap_del_all_track(void)
242 struct list_head
*iter
= icmap_track_list_head
.next
;
243 struct icmap_track
*icmap_track
;
245 while (iter
!= &icmap_track_list_head
) {
246 icmap_track
= list_entry(iter
, struct icmap_track
, list
);
247 icmap_track_delete(icmap_track
);
248 iter
= icmap_track_list_head
.next
;
252 void icmap_fini_r(const icmap_map_t map
)
255 qb_map_destroy(map
->qb_map
);
261 void icmap_fini(void)
264 icmap_del_all_track();
267 * We need to drop this notify but we can't because it calls icmap_map_free_cb
268 * while destroying the tree to free icmap_item(s).
269 * -> qb_map_notify_del_2(icmap_map, NULL, icmap_map_free_cb, QB_MAP_NOTIFY_FREE, NULL);
270 * and we cannot call it after map_destroy. joy! :)
272 icmap_fini_r(icmap_global_map
);
273 icmap_set_ro_access_free();
278 icmap_map_t
icmap_get_global_map(void)
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
== ':');
292 void icmap_convert_name_to_valid_name(char *key_name
)
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
)
307 if ((strlen(key_name
) < ICMAP_KEYNAME_MINLEN
) || strlen(key_name
) > ICMAP_KEYNAME_MAXLEN
) {
311 for (i
= 0; i
< strlen(key_name
); i
++) {
312 if (!icmap_is_valid_name_char(key_name
[i
])) {
320 static size_t icmap_get_valuetype_len(icmap_value_types_t type
)
325 case ICMAP_VALUETYPE_INT8
: res
= sizeof(int8_t); break;
326 case ICMAP_VALUETYPE_UINT8
: res
= sizeof(uint8_t); break;
327 case ICMAP_VALUETYPE_INT16
: res
= sizeof(int16_t); break;
328 case ICMAP_VALUETYPE_UINT16
: res
= sizeof(uint16_t); break;
329 case ICMAP_VALUETYPE_INT32
: res
= sizeof(int32_t); break;
330 case ICMAP_VALUETYPE_UINT32
: res
= sizeof(uint32_t); break;
331 case ICMAP_VALUETYPE_INT64
: res
= sizeof(int64_t); break;
332 case ICMAP_VALUETYPE_UINT64
: res
= sizeof(uint64_t); break;
333 case ICMAP_VALUETYPE_FLOAT
: res
= sizeof(float); break;
334 case ICMAP_VALUETYPE_DOUBLE
: res
= sizeof(double); break;
335 case ICMAP_VALUETYPE_STRING
:
336 case ICMAP_VALUETYPE_BINARY
:
344 static int icmap_check_value_len(const void *value
, size_t value_len
, icmap_value_types_t type
)
347 if (value_len
> ICMAP_MAX_VALUE_LEN
) {
351 if (type
!= ICMAP_VALUETYPE_STRING
&& type
!= ICMAP_VALUETYPE_BINARY
) {
352 if (icmap_get_valuetype_len(type
) == value_len
) {
359 if (type
== ICMAP_VALUETYPE_STRING
) {
361 * value_len can be shorter then real string length, but never
362 * longer (+ 1 is because of 0 at the end of string)
364 if (value_len
> strlen((const char *)value
) + 1) {
374 static int icmap_item_eq(const struct icmap_item
*item
, const void *value
, size_t value_len
, icmap_value_types_t type
)
378 if (item
->type
!= type
) {
382 if (item
->type
== ICMAP_VALUETYPE_STRING
) {
383 ptr_len
= strlen((const char *)value
);
384 if (ptr_len
> value_len
) {
392 if (item
->value_len
== ptr_len
) {
393 return (memcmp(item
->value
, value
, value_len
) == 0);
399 int icmap_key_value_eq(
400 const icmap_map_t map1
,
401 const char *key_name1
,
402 const icmap_map_t map2
,
403 const char *key_name2
)
405 struct icmap_item
*item1
, *item2
;
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
) {
418 return (icmap_item_eq(item1
, item2
->value
, item2
->value_len
, item2
->type
));
421 cs_error_t
icmap_set_r(
422 const icmap_map_t map
,
423 const char *key_name
,
426 icmap_value_types_t type
)
428 struct icmap_item
*item
;
429 struct icmap_item
*new_item
;
430 size_t new_value_len
;
431 size_t new_item_size
;
433 if (value
== NULL
|| key_name
== NULL
) {
434 return (CS_ERR_INVALID_PARAM
);
437 if (icmap_check_value_len(value
, value_len
, type
) != 0) {
438 return (CS_ERR_INVALID_PARAM
);
441 item
= qb_map_get(map
->qb_map
, key_name
);
444 * Check that key is really changed
446 if (icmap_item_eq(item
, value
, value_len
, type
)) {
450 if (icmap_check_key_name(key_name
) != 0) {
451 return (CS_ERR_NAME_TOO_LONG
);
455 if (type
== ICMAP_VALUETYPE_BINARY
|| type
== ICMAP_VALUETYPE_STRING
) {
456 if (type
== ICMAP_VALUETYPE_STRING
) {
457 new_value_len
= strlen((const char *)value
);
458 if (new_value_len
> value_len
) {
459 new_value_len
= value_len
;
463 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
) {
472 return (CS_ERR_NO_MEMORY
);
474 memset(new_item
, 0, new_item_size
);
477 new_item
->key_name
= strdup(key_name
);
478 if (new_item
->key_name
== NULL
) {
480 return (CS_ERR_NO_MEMORY
);
483 new_item
->key_name
= item
->key_name
;
484 item
->key_name
= NULL
;
487 new_item
->type
= type
;
488 new_item
->value_len
= new_value_len
;
490 memcpy(new_item
->value
, value
, new_value_len
);
492 if (new_item
->type
== ICMAP_VALUETYPE_STRING
) {
493 ((char *)new_item
->value
)[new_value_len
- 1] = 0;
496 qb_map_put(map
->qb_map
, new_item
->key_name
, new_item
);
501 cs_error_t
icmap_set(
502 const char *key_name
,
505 icmap_value_types_t type
)
508 return (icmap_set_r(icmap_global_map
, key_name
, value
, value_len
, type
));
511 cs_error_t
icmap_set_int8_r(const icmap_map_t map
, const char *key_name
, int8_t value
)
514 return (icmap_set_r(map
, key_name
, &value
, sizeof(value
), ICMAP_VALUETYPE_INT8
));
517 cs_error_t
icmap_set_uint8_r(const icmap_map_t map
, const char *key_name
, uint8_t value
)
520 return (icmap_set_r(map
, key_name
, &value
, sizeof(value
), ICMAP_VALUETYPE_UINT8
));
523 cs_error_t
icmap_set_int16_r(const icmap_map_t map
, const char *key_name
, int16_t value
)
526 return (icmap_set_r(map
,key_name
, &value
, sizeof(value
), ICMAP_VALUETYPE_INT16
));
529 cs_error_t
icmap_set_uint16_r(const icmap_map_t map
, const char *key_name
, uint16_t value
)
532 return (icmap_set_r(map
, key_name
, &value
, sizeof(value
), ICMAP_VALUETYPE_UINT16
));
535 cs_error_t
icmap_set_int32_r(const icmap_map_t map
, const char *key_name
, int32_t value
)
538 return (icmap_set_r(map
, key_name
, &value
, sizeof(value
), ICMAP_VALUETYPE_INT32
));
541 cs_error_t
icmap_set_uint32_r(const icmap_map_t map
, const char *key_name
, uint32_t value
)
544 return (icmap_set_r(map
, key_name
, &value
, sizeof(value
), ICMAP_VALUETYPE_UINT32
));
547 cs_error_t
icmap_set_int64_r(const icmap_map_t map
, const char *key_name
, int64_t value
)
550 return (icmap_set_r(map
, key_name
, &value
, sizeof(value
), ICMAP_VALUETYPE_INT64
));
553 cs_error_t
icmap_set_uint64_r(const icmap_map_t map
, const char *key_name
, uint64_t value
)
556 return (icmap_set_r(map
, key_name
, &value
, sizeof(value
), ICMAP_VALUETYPE_UINT64
));
559 cs_error_t
icmap_set_float_r(const icmap_map_t map
, const char *key_name
, float value
)
562 return (icmap_set_r(map
, key_name
, &value
, sizeof(value
), ICMAP_VALUETYPE_FLOAT
));
565 cs_error_t
icmap_set_double_r(const icmap_map_t map
, const char *key_name
, double value
)
568 return (icmap_set_r(map
, key_name
, &value
, sizeof(value
), ICMAP_VALUETYPE_DOUBLE
));
571 cs_error_t
icmap_set_string_r(const icmap_map_t map
, const char *key_name
, const char *value
)
575 return (CS_ERR_INVALID_PARAM
);
578 return (icmap_set_r(map
, key_name
, value
, strlen(value
), ICMAP_VALUETYPE_STRING
));
581 cs_error_t
icmap_set_int8(const char *key_name
, int8_t value
)
584 return (icmap_set_int8_r(icmap_global_map
, key_name
, value
));
587 cs_error_t
icmap_set_uint8(const char *key_name
, uint8_t value
)
590 return (icmap_set_uint8_r(icmap_global_map
, key_name
, value
));
593 cs_error_t
icmap_set_int16(const char *key_name
, int16_t value
)
596 return (icmap_set_int16_r(icmap_global_map
, key_name
, value
));
599 cs_error_t
icmap_set_uint16(const char *key_name
, uint16_t value
)
602 return (icmap_set_uint16_r(icmap_global_map
, key_name
, value
));
605 cs_error_t
icmap_set_int32(const char *key_name
, int32_t value
)
608 return (icmap_set_int32_r(icmap_global_map
, key_name
, value
));
611 cs_error_t
icmap_set_uint32(const char *key_name
, uint32_t value
)
614 return (icmap_set_uint32_r(icmap_global_map
, key_name
, value
));
617 cs_error_t
icmap_set_int64(const char *key_name
, int64_t value
)
620 return (icmap_set_int64_r(icmap_global_map
, key_name
, value
));
623 cs_error_t
icmap_set_uint64(const char *key_name
, uint64_t value
)
626 return (icmap_set_uint64_r(icmap_global_map
, key_name
, value
));
629 cs_error_t
icmap_set_float(const char *key_name
, float value
)
632 return (icmap_set_float_r(icmap_global_map
, key_name
, value
));
635 cs_error_t
icmap_set_double(const char *key_name
, double value
)
638 return (icmap_set_double_r(icmap_global_map
, key_name
, value
));
641 cs_error_t
icmap_set_string(const char *key_name
, const char *value
)
644 return (icmap_set_string_r(icmap_global_map
, key_name
, value
));
647 cs_error_t
icmap_delete_r(const icmap_map_t map
, const char *key_name
)
649 struct icmap_item
*item
;
651 if (key_name
== NULL
) {
652 return (CS_ERR_INVALID_PARAM
);
655 item
= qb_map_get(map
->qb_map
, key_name
);
657 return (CS_ERR_NOT_EXIST
);
660 if (qb_map_rm(map
->qb_map
, item
->key_name
) != QB_TRUE
) {
661 return (CS_ERR_NOT_EXIST
);
667 cs_error_t
icmap_delete(const char *key_name
)
670 return (icmap_delete_r(icmap_global_map
, key_name
));
673 static cs_error_t
icmap_get_ref_r(
674 const icmap_map_t map
,
675 const char *key_name
,
678 icmap_value_types_t
*type
)
680 struct icmap_item
*item
;
682 if (key_name
== NULL
) {
683 return (CS_ERR_INVALID_PARAM
);
686 item
= qb_map_get(map
->qb_map
, key_name
);
688 return (CS_ERR_NOT_EXIST
);
695 if (value_len
!= NULL
) {
696 *value_len
= item
->value_len
;
700 *value
= item
->value
;
706 cs_error_t
icmap_get_r(
707 const icmap_map_t map
,
708 const char *key_name
,
711 icmap_value_types_t
*type
)
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
) {
728 return (CS_ERR_INVALID_PARAM
);
731 *value_len
= tmp_value_len
;
733 memcpy(value
, tmp_value
, tmp_value_len
);
739 cs_error_t
icmap_get(
740 const char *key_name
,
743 icmap_value_types_t
*type
)
746 return (icmap_get_r(icmap_global_map
, key_name
, value
, value_len
, type
));
749 static cs_error_t
icmap_get_int_r(
750 const icmap_map_t map
,
751 const char *key_name
,
753 icmap_value_types_t type
)
758 icmap_value_types_t key_type
;
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
) {
768 return (CS_ERR_INVALID_PARAM
);
771 memcpy(value
, key_value
, icmap_get_valuetype_len(key_type
));
776 cs_error_t
icmap_get_int8_r(const icmap_map_t map
, const char *key_name
, int8_t *i8
)
779 return (icmap_get_int_r(map
, key_name
, i8
, ICMAP_VALUETYPE_INT8
));
782 cs_error_t
icmap_get_uint8_r(const icmap_map_t map
, const char *key_name
, uint8_t *u8
)
785 return (icmap_get_int_r(map
, key_name
, u8
, ICMAP_VALUETYPE_UINT8
));
788 cs_error_t
icmap_get_int16_r(const icmap_map_t map
, const char *key_name
, int16_t *i16
)
791 return (icmap_get_int_r(map
, key_name
, i16
, ICMAP_VALUETYPE_INT16
));
794 cs_error_t
icmap_get_uint16_r(const icmap_map_t map
, const char *key_name
, uint16_t *u16
)
797 return (icmap_get_int_r(map
, key_name
, u16
, ICMAP_VALUETYPE_UINT16
));
800 cs_error_t
icmap_get_int32_r(const icmap_map_t map
, const char *key_name
, int32_t *i32
)
803 return (icmap_get_int_r(map
, key_name
, i32
, ICMAP_VALUETYPE_INT32
));
806 cs_error_t
icmap_get_uint32_r(const icmap_map_t map
, const char *key_name
, uint32_t *u32
)
809 return (icmap_get_int_r(map
, key_name
, u32
, ICMAP_VALUETYPE_UINT32
));
812 cs_error_t
icmap_get_int64_r(const icmap_map_t map
, const char *key_name
, int64_t *i64
)
815 return(icmap_get_int_r(map
, key_name
, i64
, ICMAP_VALUETYPE_INT64
));
818 cs_error_t
icmap_get_uint64_r(const icmap_map_t map
, const char *key_name
, uint64_t *u64
)
821 return (icmap_get_int_r(map
, key_name
, u64
, ICMAP_VALUETYPE_UINT64
));
824 cs_error_t
icmap_get_float_r(const icmap_map_t map
, const char *key_name
, float *flt
)
827 return (icmap_get_int_r(map
, key_name
, flt
, ICMAP_VALUETYPE_FLOAT
));
830 cs_error_t
icmap_get_double_r(const icmap_map_t map
, const char *key_name
, double *dbl
)
833 return (icmap_get_int_r(map
, key_name
, dbl
, ICMAP_VALUETYPE_DOUBLE
));
836 cs_error_t
icmap_get_int8(const char *key_name
, int8_t *i8
)
839 return (icmap_get_int8_r(icmap_global_map
, key_name
, i8
));
842 cs_error_t
icmap_get_uint8(const char *key_name
, uint8_t *u8
)
845 return (icmap_get_uint8_r(icmap_global_map
, key_name
, u8
));
848 cs_error_t
icmap_get_int16(const char *key_name
, int16_t *i16
)
851 return (icmap_get_int16_r(icmap_global_map
, key_name
, i16
));
854 cs_error_t
icmap_get_uint16(const char *key_name
, uint16_t *u16
)
857 return (icmap_get_uint16_r(icmap_global_map
, key_name
, u16
));
860 cs_error_t
icmap_get_int32(const char *key_name
, int32_t *i32
)
863 return (icmap_get_int32_r(icmap_global_map
, key_name
, i32
));
866 cs_error_t
icmap_get_uint32(const char *key_name
, uint32_t *u32
)
869 return (icmap_get_uint32_r(icmap_global_map
, key_name
, u32
));
872 cs_error_t
icmap_get_int64(const char *key_name
, int64_t *i64
)
875 return(icmap_get_int64_r(icmap_global_map
, key_name
, i64
));
878 cs_error_t
icmap_get_uint64(const char *key_name
, uint64_t *u64
)
881 return (icmap_get_uint64_r(icmap_global_map
, key_name
, u64
));
884 cs_error_t
icmap_get_float(const char *key_name
, float *flt
)
887 return (icmap_get_float_r(icmap_global_map
, key_name
, flt
));
890 cs_error_t
icmap_get_double(const char *key_name
, double *dbl
)
893 return (icmap_get_double_r(icmap_global_map
, key_name
, dbl
));
896 cs_error_t
icmap_get_string(const char *key_name
, char **str
)
900 icmap_value_types_t type
;
902 res
= icmap_get(key_name
, NULL
, &str_len
, &type
);
903 if (res
!= CS_OK
|| type
!= ICMAP_VALUETYPE_STRING
) {
905 res
= CS_ERR_INVALID_PARAM
;
911 *str
= malloc(str_len
);
913 res
= CS_ERR_NO_MEMORY
;
918 res
= icmap_get(key_name
, *str
, &str_len
, &type
);
930 cs_error_t
icmap_adjust_int_r(
931 const icmap_map_t map
,
932 const char *key_name
,
935 struct icmap_item
*item
;
940 cs_error_t err
= CS_OK
;
942 if (key_name
== NULL
) {
943 return (CS_ERR_INVALID_PARAM
);
946 item
= qb_map_get(map
->qb_map
, key_name
);
948 return (CS_ERR_NOT_EXIST
);
951 switch (item
->type
) {
952 case ICMAP_VALUETYPE_INT8
:
953 case ICMAP_VALUETYPE_UINT8
:
954 memcpy(&u8
, item
->value
, sizeof(u8
));
956 err
= icmap_set(key_name
, &u8
, sizeof(u8
), item
->type
);
958 case ICMAP_VALUETYPE_INT16
:
959 case ICMAP_VALUETYPE_UINT16
:
960 memcpy(&u16
, item
->value
, sizeof(u16
));
962 err
= icmap_set(key_name
, &u16
, sizeof(u16
), item
->type
);
964 case ICMAP_VALUETYPE_INT32
:
965 case ICMAP_VALUETYPE_UINT32
:
966 memcpy(&u32
, item
->value
, sizeof(u32
));
968 err
= icmap_set(key_name
, &u32
, sizeof(u32
), item
->type
);
970 case ICMAP_VALUETYPE_INT64
:
971 case ICMAP_VALUETYPE_UINT64
:
972 memcpy(&u64
, item
->value
, sizeof(u64
));
974 err
= icmap_set(key_name
, &u64
, sizeof(u64
), item
->type
);
976 case ICMAP_VALUETYPE_FLOAT
:
977 case ICMAP_VALUETYPE_DOUBLE
:
978 case ICMAP_VALUETYPE_STRING
:
979 case ICMAP_VALUETYPE_BINARY
:
980 err
= CS_ERR_INVALID_PARAM
;
987 cs_error_t
icmap_adjust_int(
988 const char *key_name
,
992 return (icmap_adjust_int_r(icmap_global_map
, key_name
, step
));
995 cs_error_t
icmap_fast_adjust_int_r(
996 const icmap_map_t map
,
997 const char *key_name
,
1000 struct icmap_item
*item
;
1001 cs_error_t err
= CS_OK
;
1003 if (key_name
== NULL
) {
1004 return (CS_ERR_INVALID_PARAM
);
1007 item
= qb_map_get(map
->qb_map
, key_name
);
1009 return (CS_ERR_NOT_EXIST
);
1012 switch (item
->type
) {
1013 case ICMAP_VALUETYPE_INT8
:
1014 case ICMAP_VALUETYPE_UINT8
:
1015 *(uint8_t *)item
->value
+= step
;
1017 case ICMAP_VALUETYPE_INT16
:
1018 case ICMAP_VALUETYPE_UINT16
:
1019 *(uint16_t *)item
->value
+= step
;
1021 case ICMAP_VALUETYPE_INT32
:
1022 case ICMAP_VALUETYPE_UINT32
:
1023 *(uint32_t *)item
->value
+= step
;
1025 case ICMAP_VALUETYPE_INT64
:
1026 case ICMAP_VALUETYPE_UINT64
:
1027 *(uint64_t *)item
->value
+= step
;
1029 case ICMAP_VALUETYPE_FLOAT
:
1030 case ICMAP_VALUETYPE_DOUBLE
:
1031 case ICMAP_VALUETYPE_STRING
:
1032 case ICMAP_VALUETYPE_BINARY
:
1033 err
= CS_ERR_INVALID_PARAM
;
1038 qb_map_put(map
->qb_map
, item
->key_name
, item
);
1044 cs_error_t
icmap_fast_adjust_int(
1045 const char *key_name
,
1049 return (icmap_fast_adjust_int_r(icmap_global_map
, key_name
, step
));
1052 cs_error_t
icmap_inc_r(const icmap_map_t map
, const char *key_name
)
1054 return (icmap_adjust_int_r(map
, key_name
, 1));
1057 cs_error_t
icmap_inc(const char *key_name
)
1059 return (icmap_inc_r(icmap_global_map
, key_name
));
1062 cs_error_t
icmap_dec_r(const icmap_map_t map
, const char *key_name
)
1064 return (icmap_adjust_int_r(map
, key_name
, -1));
1067 cs_error_t
icmap_dec(const char *key_name
)
1069 return (icmap_dec_r(icmap_global_map
, key_name
));
1072 cs_error_t
icmap_fast_inc_r(const icmap_map_t map
, const char *key_name
)
1074 return (icmap_fast_adjust_int_r(map
, key_name
, 1));
1077 cs_error_t
icmap_fast_inc(const char *key_name
)
1079 return (icmap_fast_inc_r(icmap_global_map
, key_name
));
1082 cs_error_t
icmap_fast_dec_r(const icmap_map_t map
, const char *key_name
)
1084 return (icmap_fast_adjust_int_r(map
, key_name
, -1));
1087 cs_error_t
icmap_fast_dec(const char *key_name
)
1089 return (icmap_fast_dec_r(icmap_global_map
, key_name
));
1092 icmap_iter_t
icmap_iter_init_r(const icmap_map_t map
, const char *prefix
)
1094 return (qb_map_pref_iter_create(map
->qb_map
, prefix
));
1097 icmap_iter_t
icmap_iter_init(const char *prefix
)
1099 return (icmap_iter_init_r(icmap_global_map
, prefix
));
1103 const char *icmap_iter_next(icmap_iter_t iter
, size_t *value_len
, icmap_value_types_t
*type
)
1105 struct icmap_item
*item
;
1108 res
= qb_map_iter_next(iter
, (void **)&item
);
1113 if (value_len
!= NULL
) {
1114 *value_len
= item
->value_len
;
1124 void icmap_iter_finalize(icmap_iter_t iter
)
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
)
1131 icmap_track_t icmap_track
= (icmap_track_t
)user_data
;
1132 struct icmap_item
*new_item
= (struct icmap_item
*)value
;
1133 struct icmap_item
*old_item
= (struct icmap_item
*)old_value
;
1134 struct icmap_notify_value new_val
;
1135 struct icmap_notify_value old_val
;
1137 if (value
== NULL
&& old_value
== NULL
) {
1141 if (new_item
!= NULL
) {
1142 new_val
.type
= new_item
->type
;
1143 new_val
.len
= new_item
->value_len
;
1144 new_val
.data
= new_item
->value
;
1146 memset(&new_val
, 0, sizeof(new_val
));
1150 * old_item == new_item if fast functions are used -> don't fill old value
1152 if (old_item
!= NULL
&& old_item
!= new_item
) {
1153 old_val
.type
= old_item
->type
;
1154 old_val
.len
= old_item
->value_len
;
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
),
1164 icmap_track
->user_data
);
1167 cs_error_t
icmap_track_add(
1168 const char *key_name
,
1170 icmap_notify_fn_t notify_fn
,
1172 icmap_track_t
*icmap_track
)
1176 if (notify_fn
== NULL
|| icmap_track
== NULL
) {
1177 return (CS_ERR_INVALID_PARAM
);
1180 if ((track_type
& ~(ICMAP_TRACK_ADD
| ICMAP_TRACK_DELETE
| ICMAP_TRACK_MODIFY
| ICMAP_TRACK_PREFIX
)) != 0) {
1181 return (CS_ERR_INVALID_PARAM
);
1184 *icmap_track
= malloc(sizeof(**icmap_track
));
1185 if (*icmap_track
== NULL
) {
1186 return (CS_ERR_NO_MEMORY
);
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
;
1196 (*icmap_track
)->user_data
= user_data
;
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
);
1203 return (qb_to_cs_error(err
));
1206 list_init(&(*icmap_track
)->list
);
1207 list_add (&(*icmap_track
)->list
, &icmap_track_list_head
);
1212 cs_error_t
icmap_track_delete(icmap_track_t icmap_track
)
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) {
1218 return (qb_to_cs_error(err
));
1221 list_del(&icmap_track
->list
);
1222 free(icmap_track
->key_name
);
1228 void *icmap_track_get_user_data(icmap_track_t icmap_track
)
1230 return (icmap_track
->user_data
);
1233 cs_error_t
icmap_set_ro_access(const char *key_name
, int prefix
, int ro_access
)
1235 struct list_head
*iter
;
1236 struct icmap_ro_access_item
*icmap_ro_ai
;
1238 for (iter
= icmap_ro_access_item_list_head
.next
; iter
!= &icmap_ro_access_item_list_head
; iter
= iter
->next
) {
1239 icmap_ro_ai
= list_entry(iter
, struct icmap_ro_access_item
, list
);
1241 if (icmap_ro_ai
->prefix
== prefix
&& strcmp(key_name
, icmap_ro_ai
->key_name
) == 0) {
1246 return (CS_ERR_EXIST
);
1248 list_del(&icmap_ro_ai
->list
);
1249 free(icmap_ro_ai
->key_name
);
1258 return (CS_ERR_NOT_EXIST
);
1261 icmap_ro_ai
= malloc(sizeof(*icmap_ro_ai
));
1262 if (icmap_ro_ai
== NULL
) {
1263 return (CS_ERR_NO_MEMORY
);
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
) {
1270 return (CS_ERR_NO_MEMORY
);
1273 icmap_ro_ai
->prefix
= prefix
;
1274 list_init(&icmap_ro_ai
->list
);
1275 list_add (&icmap_ro_ai
->list
, &icmap_ro_access_item_list_head
);
1280 int icmap_is_key_ro(const char *key_name
)
1282 struct list_head
*iter
;
1283 struct icmap_ro_access_item
*icmap_ro_ai
;
1285 for (iter
= icmap_ro_access_item_list_head
.next
; iter
!= &icmap_ro_access_item_list_head
; iter
= iter
->next
) {
1286 icmap_ro_ai
= list_entry(iter
, struct icmap_ro_access_item
, list
);
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) {
1306 cs_error_t
icmap_copy_map(icmap_map_t dst_map
, const icmap_map_t src_map
)
1310 icmap_value_types_t value_type
;
1311 const char *key_name
;
1315 iter
= icmap_iter_init_r(src_map
, NULL
);
1317 return (CS_ERR_NO_MEMORY
);
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
;
1335 icmap_iter_finalize(iter
);