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 * Function implementation
130 static int32_t icmap_tt_to_qbtt(int32_t track_type
)
134 if (track_type
& ICMAP_TRACK_DELETE
) {
135 res
|= QB_MAP_NOTIFY_DELETED
;
138 if (track_type
& ICMAP_TRACK_MODIFY
) {
139 res
|= QB_MAP_NOTIFY_REPLACED
;
142 if (track_type
& ICMAP_TRACK_ADD
) {
143 res
|= QB_MAP_NOTIFY_INSERTED
;
146 if (track_type
& ICMAP_TRACK_PREFIX
) {
147 res
|= QB_MAP_NOTIFY_RECURSIVE
;
153 static int32_t icmap_qbtt_to_tt(int32_t track_type
)
157 if (track_type
& QB_MAP_NOTIFY_DELETED
) {
158 res
|= ICMAP_TRACK_DELETE
;
161 if (track_type
& QB_MAP_NOTIFY_REPLACED
) {
162 res
|= ICMAP_TRACK_MODIFY
;
165 if (track_type
& QB_MAP_NOTIFY_INSERTED
) {
166 res
|= ICMAP_TRACK_ADD
;
169 if (track_type
& QB_MAP_NOTIFY_RECURSIVE
) {
170 res
|= ICMAP_TRACK_PREFIX
;
176 static void icmap_map_free_cb(uint32_t event
,
177 char* key
, void* old_value
,
178 void* value
, void* user_data
)
180 struct icmap_item
*item
= (struct icmap_item
*)old_value
;
183 * value == old_value -> fast_adjust_int was used, don't free data
185 if (item
!= NULL
&& value
!= old_value
) {
186 free(item
->key_name
);
191 cs_error_t
icmap_init_r(icmap_map_t
*result
)
195 *result
= malloc(sizeof(struct icmap_map
));
196 if (*result
== NULL
) {
197 return (CS_ERR_NO_MEMORY
);
200 (*result
)->qb_map
= qb_trie_create();
201 if ((*result
)->qb_map
== NULL
)
202 return (CS_ERR_INIT
);
204 err
= qb_map_notify_add((*result
)->qb_map
, NULL
, icmap_map_free_cb
, QB_MAP_NOTIFY_FREE
, NULL
);
206 return (qb_to_cs_error(err
));
209 cs_error_t
icmap_init(void)
211 return (icmap_init_r(&icmap_global_map
));
214 static void icmap_set_ro_access_free(void)
216 struct list_head
*iter
= icmap_ro_access_item_list_head
.next
;
217 struct icmap_ro_access_item
*icmap_ro_ai
;
219 while (iter
!= &icmap_ro_access_item_list_head
) {
220 icmap_ro_ai
= list_entry(iter
, struct icmap_ro_access_item
, list
);
221 list_del(&icmap_ro_ai
->list
);
222 free(icmap_ro_ai
->key_name
);
224 iter
= icmap_ro_access_item_list_head
.next
;
228 static void icmap_del_all_track(void)
230 struct list_head
*iter
= icmap_track_list_head
.next
;
231 struct icmap_track
*icmap_track
;
233 while (iter
!= &icmap_track_list_head
) {
234 icmap_track
= list_entry(iter
, struct icmap_track
, list
);
235 icmap_track_delete(icmap_track
);
236 iter
= icmap_track_list_head
.next
;
240 void icmap_fini_r(const icmap_map_t map
)
243 qb_map_destroy(map
->qb_map
);
249 void icmap_fini(void)
252 icmap_del_all_track();
255 * We need to drop this notify but we can't because it calls icmap_map_free_cb
256 * while destroying the tree to free icmap_item(s).
257 * -> qb_map_notify_del_2(icmap_map, NULL, icmap_map_free_cb, QB_MAP_NOTIFY_FREE, NULL);
258 * and we cannot call it after map_destroy. joy! :)
260 icmap_fini_r(icmap_global_map
);
261 icmap_set_ro_access_free();
266 icmap_map_t
icmap_get_global_map(void)
269 return (icmap_global_map
);
272 static int icmap_is_valid_name_char(char c
)
274 return ((c
>= 'a' && c
<= 'z') ||
275 (c
>= 'A' && c
<= 'Z') ||
276 (c
>= '0' && c
<= '9') ||
277 c
== '.' || c
== '_' || c
== '-' || c
== '/' || c
== ':');
280 void icmap_convert_name_to_valid_name(char *key_name
)
284 for (i
= 0; i
< strlen(key_name
); i
++) {
285 if (!icmap_is_valid_name_char(key_name
[i
])) {
291 static int icmap_check_key_name(const char *key_name
)
295 if ((strlen(key_name
) < ICMAP_KEYNAME_MINLEN
) || strlen(key_name
) > ICMAP_KEYNAME_MAXLEN
) {
299 for (i
= 0; i
< strlen(key_name
); i
++) {
300 if (!icmap_is_valid_name_char(key_name
[i
])) {
308 static size_t icmap_get_valuetype_len(icmap_value_types_t type
)
313 case ICMAP_VALUETYPE_INT8
: res
= sizeof(int8_t); break;
314 case ICMAP_VALUETYPE_UINT8
: res
= sizeof(uint8_t); break;
315 case ICMAP_VALUETYPE_INT16
: res
= sizeof(int16_t); break;
316 case ICMAP_VALUETYPE_UINT16
: res
= sizeof(uint16_t); break;
317 case ICMAP_VALUETYPE_INT32
: res
= sizeof(int32_t); break;
318 case ICMAP_VALUETYPE_UINT32
: res
= sizeof(uint32_t); break;
319 case ICMAP_VALUETYPE_INT64
: res
= sizeof(int64_t); break;
320 case ICMAP_VALUETYPE_UINT64
: res
= sizeof(uint64_t); break;
321 case ICMAP_VALUETYPE_FLOAT
: res
= sizeof(float); break;
322 case ICMAP_VALUETYPE_DOUBLE
: res
= sizeof(double); break;
323 case ICMAP_VALUETYPE_STRING
:
324 case ICMAP_VALUETYPE_BINARY
:
332 static int icmap_check_value_len(const void *value
, size_t value_len
, icmap_value_types_t type
)
335 if (value_len
> ICMAP_MAX_VALUE_LEN
) {
339 if (type
!= ICMAP_VALUETYPE_STRING
&& type
!= ICMAP_VALUETYPE_BINARY
) {
340 if (icmap_get_valuetype_len(type
) == value_len
) {
347 if (type
== ICMAP_VALUETYPE_STRING
) {
348 if (value_len
> strlen((const char *)value
)) {
358 static int icmap_item_eq(const struct icmap_item
*item
, const void *value
, size_t value_len
, icmap_value_types_t type
)
362 if (item
->type
!= type
) {
366 if (item
->type
== ICMAP_VALUETYPE_STRING
) {
367 ptr_len
= strlen((const char *)value
);
368 if (ptr_len
> value_len
) {
376 if (item
->value_len
== ptr_len
) {
377 return (memcmp(item
->value
, value
, value_len
) == 0);
383 cs_error_t
icmap_set_r(
384 const icmap_map_t map
,
385 const char *key_name
,
388 icmap_value_types_t type
)
390 struct icmap_item
*item
;
391 struct icmap_item
*new_item
;
392 size_t new_value_len
;
393 size_t new_item_size
;
395 if (value
== NULL
|| key_name
== NULL
) {
396 return (CS_ERR_INVALID_PARAM
);
399 if (icmap_check_value_len(value
, value_len
, type
) != 0) {
400 return (CS_ERR_INVALID_PARAM
);
403 item
= qb_map_get(map
->qb_map
, key_name
);
406 * Check that key is really changed
408 if (icmap_item_eq(item
, value
, value_len
, type
)) {
412 if (icmap_check_key_name(key_name
) != 0) {
413 return (CS_ERR_NAME_TOO_LONG
);
417 if (type
== ICMAP_VALUETYPE_BINARY
|| type
== ICMAP_VALUETYPE_STRING
) {
418 if (type
== ICMAP_VALUETYPE_STRING
) {
419 new_value_len
= strlen((const char *)value
);
420 if (new_value_len
> value_len
) {
421 new_value_len
= value_len
;
425 new_value_len
= value_len
;
428 new_value_len
= icmap_get_valuetype_len(type
);
431 new_item_size
= sizeof(struct icmap_item
) + new_value_len
;
432 new_item
= malloc(new_item_size
);
433 if (new_item
== NULL
) {
434 return (CS_ERR_NO_MEMORY
);
436 memset(new_item
, 0, new_item_size
);
439 new_item
->key_name
= strdup(key_name
);
440 if (new_item
->key_name
== NULL
) {
442 return (CS_ERR_NO_MEMORY
);
445 new_item
->key_name
= item
->key_name
;
446 item
->key_name
= NULL
;
449 new_item
->type
= type
;
450 new_item
->value_len
= new_value_len
;
452 memcpy(new_item
->value
, value
, new_value_len
);
454 if (new_item
->type
== ICMAP_VALUETYPE_STRING
) {
455 ((char *)new_item
->value
)[new_value_len
- 1] = 0;
458 qb_map_put(map
->qb_map
, new_item
->key_name
, new_item
);
463 cs_error_t
icmap_set(
464 const char *key_name
,
467 icmap_value_types_t type
)
470 return (icmap_set_r(icmap_global_map
, key_name
, value
, value_len
, type
));
473 cs_error_t
icmap_set_int8_r(const icmap_map_t map
, const char *key_name
, int8_t value
)
476 return (icmap_set_r(map
, key_name
, &value
, sizeof(value
), ICMAP_VALUETYPE_INT8
));
479 cs_error_t
icmap_set_uint8_r(const icmap_map_t map
, const char *key_name
, uint8_t value
)
482 return (icmap_set_r(map
, key_name
, &value
, sizeof(value
), ICMAP_VALUETYPE_UINT8
));
485 cs_error_t
icmap_set_int16_r(const icmap_map_t map
, const char *key_name
, int16_t value
)
488 return (icmap_set_r(map
,key_name
, &value
, sizeof(value
), ICMAP_VALUETYPE_INT16
));
491 cs_error_t
icmap_set_uint16_r(const icmap_map_t map
, const char *key_name
, uint16_t value
)
494 return (icmap_set_r(map
, key_name
, &value
, sizeof(value
), ICMAP_VALUETYPE_UINT16
));
497 cs_error_t
icmap_set_int32_r(const icmap_map_t map
, const char *key_name
, int32_t value
)
500 return (icmap_set_r(map
, key_name
, &value
, sizeof(value
), ICMAP_VALUETYPE_INT32
));
503 cs_error_t
icmap_set_uint32_r(const icmap_map_t map
, const char *key_name
, uint32_t value
)
506 return (icmap_set_r(map
, key_name
, &value
, sizeof(value
), ICMAP_VALUETYPE_UINT32
));
509 cs_error_t
icmap_set_int64_r(const icmap_map_t map
, const char *key_name
, int64_t value
)
512 return (icmap_set_r(map
, key_name
, &value
, sizeof(value
), ICMAP_VALUETYPE_INT64
));
515 cs_error_t
icmap_set_uint64_r(const icmap_map_t map
, const char *key_name
, uint64_t value
)
518 return (icmap_set_r(map
, key_name
, &value
, sizeof(value
), ICMAP_VALUETYPE_UINT64
));
521 cs_error_t
icmap_set_float_r(const icmap_map_t map
, const char *key_name
, float value
)
524 return (icmap_set_r(map
, key_name
, &value
, sizeof(value
), ICMAP_VALUETYPE_FLOAT
));
527 cs_error_t
icmap_set_double_r(const icmap_map_t map
, const char *key_name
, double value
)
530 return (icmap_set_r(map
, key_name
, &value
, sizeof(value
), ICMAP_VALUETYPE_DOUBLE
));
533 cs_error_t
icmap_set_string_r(const icmap_map_t map
, const char *key_name
, const char *value
)
537 return (CS_ERR_INVALID_PARAM
);
540 return (icmap_set_r(map
, key_name
, value
, strlen(value
), ICMAP_VALUETYPE_STRING
));
543 cs_error_t
icmap_set_int8(const char *key_name
, int8_t value
)
546 return (icmap_set_int8_r(icmap_global_map
, key_name
, value
));
549 cs_error_t
icmap_set_uint8(const char *key_name
, uint8_t value
)
552 return (icmap_set_uint8_r(icmap_global_map
, key_name
, value
));
555 cs_error_t
icmap_set_int16(const char *key_name
, int16_t value
)
558 return (icmap_set_int16_r(icmap_global_map
, key_name
, value
));
561 cs_error_t
icmap_set_uint16(const char *key_name
, uint16_t value
)
564 return (icmap_set_uint16_r(icmap_global_map
, key_name
, value
));
567 cs_error_t
icmap_set_int32(const char *key_name
, int32_t value
)
570 return (icmap_set_int32_r(icmap_global_map
, key_name
, value
));
573 cs_error_t
icmap_set_uint32(const char *key_name
, uint32_t value
)
576 return (icmap_set_uint32_r(icmap_global_map
, key_name
, value
));
579 cs_error_t
icmap_set_int64(const char *key_name
, int64_t value
)
582 return (icmap_set_int64_r(icmap_global_map
, key_name
, value
));
585 cs_error_t
icmap_set_uint64(const char *key_name
, uint64_t value
)
588 return (icmap_set_uint64_r(icmap_global_map
, key_name
, value
));
591 cs_error_t
icmap_set_float(const char *key_name
, float value
)
594 return (icmap_set_float_r(icmap_global_map
, key_name
, value
));
597 cs_error_t
icmap_set_double(const char *key_name
, double value
)
600 return (icmap_set_double_r(icmap_global_map
, key_name
, value
));
603 cs_error_t
icmap_set_string(const char *key_name
, const char *value
)
606 return (icmap_set_string_r(icmap_global_map
, key_name
, value
));
609 cs_error_t
icmap_delete_r(const icmap_map_t map
, const char *key_name
)
611 struct icmap_item
*item
;
613 if (key_name
== NULL
) {
614 return (CS_ERR_INVALID_PARAM
);
617 item
= qb_map_get(map
->qb_map
, key_name
);
619 return (CS_ERR_NOT_EXIST
);
622 if (qb_map_rm(map
->qb_map
, item
->key_name
) != QB_TRUE
) {
623 return (CS_ERR_NOT_EXIST
);
629 cs_error_t
icmap_delete(const char *key_name
)
632 return (icmap_delete_r(icmap_global_map
, key_name
));
635 cs_error_t
icmap_get_r(
636 const icmap_map_t map
,
637 const char *key_name
,
640 icmap_value_types_t
*type
)
642 struct icmap_item
*item
;
644 if (key_name
== NULL
) {
645 return (CS_ERR_INVALID_PARAM
);
648 item
= qb_map_get(map
->qb_map
, key_name
);
650 return (CS_ERR_NOT_EXIST
);
658 if (value_len
!= NULL
) {
659 *value_len
= item
->value_len
;
662 if (value_len
== NULL
|| *value_len
< item
->value_len
) {
663 return (CS_ERR_INVALID_PARAM
);
666 *value_len
= item
->value_len
;
668 memcpy(value
, item
->value
, item
->value_len
);
674 cs_error_t
icmap_get(
675 const char *key_name
,
678 icmap_value_types_t
*type
)
681 return (icmap_get_r(icmap_global_map
, key_name
, value
, value_len
, type
));
684 static cs_error_t
icmap_get_int_r(
685 const icmap_map_t map
,
686 const char *key_name
,
688 icmap_value_types_t type
)
693 icmap_value_types_t key_type
;
695 key_size
= sizeof(key_value
);
696 memset(key_value
, 0, key_size
);
698 err
= icmap_get(key_name
, key_value
, &key_size
, &key_type
);
702 if (key_type
!= type
) {
703 return (CS_ERR_INVALID_PARAM
);
706 memcpy(value
, key_value
, icmap_get_valuetype_len(key_type
));
711 cs_error_t
icmap_get_int8_r(const icmap_map_t map
, const char *key_name
, int8_t *i8
)
714 return (icmap_get_int_r(map
, key_name
, i8
, ICMAP_VALUETYPE_INT8
));
717 cs_error_t
icmap_get_uint8_r(const icmap_map_t map
, const char *key_name
, uint8_t *u8
)
720 return (icmap_get_int_r(map
, key_name
, u8
, ICMAP_VALUETYPE_UINT8
));
723 cs_error_t
icmap_get_int16_r(const icmap_map_t map
, const char *key_name
, int16_t *i16
)
726 return (icmap_get_int_r(map
, key_name
, i16
, ICMAP_VALUETYPE_INT16
));
729 cs_error_t
icmap_get_uint16_r(const icmap_map_t map
, const char *key_name
, uint16_t *u16
)
732 return (icmap_get_int_r(map
, key_name
, u16
, ICMAP_VALUETYPE_UINT16
));
735 cs_error_t
icmap_get_int32_r(const icmap_map_t map
, const char *key_name
, int32_t *i32
)
738 return (icmap_get_int_r(map
, key_name
, i32
, ICMAP_VALUETYPE_INT32
));
741 cs_error_t
icmap_get_uint32_r(const icmap_map_t map
, const char *key_name
, uint32_t *u32
)
744 return (icmap_get_int_r(map
, key_name
, u32
, ICMAP_VALUETYPE_UINT32
));
747 cs_error_t
icmap_get_int64_r(const icmap_map_t map
, const char *key_name
, int64_t *i64
)
750 return(icmap_get_int_r(map
, key_name
, i64
, ICMAP_VALUETYPE_INT64
));
753 cs_error_t
icmap_get_uint64_r(const icmap_map_t map
, const char *key_name
, uint64_t *u64
)
756 return (icmap_get_int_r(map
, key_name
, u64
, ICMAP_VALUETYPE_UINT64
));
759 cs_error_t
icmap_get_float_r(const icmap_map_t map
, const char *key_name
, float *flt
)
762 return (icmap_get_int_r(map
, key_name
, flt
, ICMAP_VALUETYPE_FLOAT
));
765 cs_error_t
icmap_get_double_r(const icmap_map_t map
, const char *key_name
, double *dbl
)
768 return (icmap_get_int_r(map
, key_name
, dbl
, ICMAP_VALUETYPE_DOUBLE
));
771 cs_error_t
icmap_get_int8(const char *key_name
, int8_t *i8
)
774 return (icmap_get_int8_r(icmap_global_map
, key_name
, i8
));
777 cs_error_t
icmap_get_uint8(const char *key_name
, uint8_t *u8
)
780 return (icmap_get_uint8_r(icmap_global_map
, key_name
, u8
));
783 cs_error_t
icmap_get_int16(const char *key_name
, int16_t *i16
)
786 return (icmap_get_int16_r(icmap_global_map
, key_name
, i16
));
789 cs_error_t
icmap_get_uint16(const char *key_name
, uint16_t *u16
)
792 return (icmap_get_uint16_r(icmap_global_map
, key_name
, u16
));
795 cs_error_t
icmap_get_int32(const char *key_name
, int32_t *i32
)
798 return (icmap_get_int32_r(icmap_global_map
, key_name
, i32
));
801 cs_error_t
icmap_get_uint32(const char *key_name
, uint32_t *u32
)
804 return (icmap_get_uint32_r(icmap_global_map
, key_name
, u32
));
807 cs_error_t
icmap_get_int64(const char *key_name
, int64_t *i64
)
810 return(icmap_get_int64_r(icmap_global_map
, key_name
, i64
));
813 cs_error_t
icmap_get_uint64(const char *key_name
, uint64_t *u64
)
816 return (icmap_get_uint64_r(icmap_global_map
, key_name
, u64
));
819 cs_error_t
icmap_get_float(const char *key_name
, float *flt
)
822 return (icmap_get_float_r(icmap_global_map
, key_name
, flt
));
825 cs_error_t
icmap_get_double(const char *key_name
, double *dbl
)
828 return (icmap_get_double_r(icmap_global_map
, key_name
, dbl
));
831 cs_error_t
icmap_get_string(const char *key_name
, char **str
)
835 icmap_value_types_t type
;
837 res
= icmap_get(key_name
, NULL
, &str_len
, &type
);
838 if (res
!= CS_OK
|| type
!= ICMAP_VALUETYPE_STRING
) {
840 res
= CS_ERR_INVALID_PARAM
;
846 *str
= malloc(str_len
);
848 res
= CS_ERR_NO_MEMORY
;
853 res
= icmap_get(key_name
, *str
, &str_len
, &type
);
865 cs_error_t
icmap_adjust_int_r(
866 const icmap_map_t map
,
867 const char *key_name
,
870 struct icmap_item
*item
;
875 cs_error_t err
= CS_OK
;
877 if (key_name
== NULL
) {
878 return (CS_ERR_INVALID_PARAM
);
881 item
= qb_map_get(map
->qb_map
, key_name
);
883 return (CS_ERR_NOT_EXIST
);
886 switch (item
->type
) {
887 case ICMAP_VALUETYPE_INT8
:
888 case ICMAP_VALUETYPE_UINT8
:
889 memcpy(&u8
, item
->value
, sizeof(u8
));
891 err
= icmap_set(key_name
, &u8
, sizeof(u8
), item
->type
);
893 case ICMAP_VALUETYPE_INT16
:
894 case ICMAP_VALUETYPE_UINT16
:
895 memcpy(&u16
, item
->value
, sizeof(u16
));
897 err
= icmap_set(key_name
, &u16
, sizeof(u16
), item
->type
);
899 case ICMAP_VALUETYPE_INT32
:
900 case ICMAP_VALUETYPE_UINT32
:
901 memcpy(&u32
, item
->value
, sizeof(u32
));
903 err
= icmap_set(key_name
, &u32
, sizeof(u32
), item
->type
);
905 case ICMAP_VALUETYPE_INT64
:
906 case ICMAP_VALUETYPE_UINT64
:
907 memcpy(&u64
, item
->value
, sizeof(u64
));
909 err
= icmap_set(key_name
, &u64
, sizeof(u64
), item
->type
);
911 case ICMAP_VALUETYPE_FLOAT
:
912 case ICMAP_VALUETYPE_DOUBLE
:
913 case ICMAP_VALUETYPE_STRING
:
914 case ICMAP_VALUETYPE_BINARY
:
915 err
= CS_ERR_INVALID_PARAM
;
922 cs_error_t
icmap_adjust_int(
923 const char *key_name
,
927 return (icmap_adjust_int_r(icmap_global_map
, key_name
, step
));
930 cs_error_t
icmap_fast_adjust_int_r(
931 const icmap_map_t map
,
932 const char *key_name
,
935 struct icmap_item
*item
;
936 cs_error_t err
= CS_OK
;
938 if (key_name
== NULL
) {
939 return (CS_ERR_INVALID_PARAM
);
942 item
= qb_map_get(map
->qb_map
, key_name
);
944 return (CS_ERR_NOT_EXIST
);
947 switch (item
->type
) {
948 case ICMAP_VALUETYPE_INT8
:
949 case ICMAP_VALUETYPE_UINT8
:
950 *(uint8_t *)item
->value
+= step
;
952 case ICMAP_VALUETYPE_INT16
:
953 case ICMAP_VALUETYPE_UINT16
:
954 *(uint16_t *)item
->value
+= step
;
956 case ICMAP_VALUETYPE_INT32
:
957 case ICMAP_VALUETYPE_UINT32
:
958 *(uint32_t *)item
->value
+= step
;
960 case ICMAP_VALUETYPE_INT64
:
961 case ICMAP_VALUETYPE_UINT64
:
962 *(uint64_t *)item
->value
+= step
;
964 case ICMAP_VALUETYPE_FLOAT
:
965 case ICMAP_VALUETYPE_DOUBLE
:
966 case ICMAP_VALUETYPE_STRING
:
967 case ICMAP_VALUETYPE_BINARY
:
968 err
= CS_ERR_INVALID_PARAM
;
973 qb_map_put(map
->qb_map
, item
->key_name
, item
);
979 cs_error_t
icmap_fast_adjust_int(
980 const char *key_name
,
984 return (icmap_fast_adjust_int_r(icmap_global_map
, key_name
, step
));
987 cs_error_t
icmap_inc_r(const icmap_map_t map
, const char *key_name
)
989 return (icmap_adjust_int_r(map
, key_name
, 1));
992 cs_error_t
icmap_inc(const char *key_name
)
994 return (icmap_inc_r(icmap_global_map
, key_name
));
997 cs_error_t
icmap_dec_r(const icmap_map_t map
, const char *key_name
)
999 return (icmap_adjust_int_r(map
, key_name
, -1));
1002 cs_error_t
icmap_dec(const char *key_name
)
1004 return (icmap_dec_r(icmap_global_map
, key_name
));
1007 cs_error_t
icmap_fast_inc_r(const icmap_map_t map
, const char *key_name
)
1009 return (icmap_fast_adjust_int_r(map
, key_name
, 1));
1012 cs_error_t
icmap_fast_inc(const char *key_name
)
1014 return (icmap_fast_inc_r(icmap_global_map
, key_name
));
1017 cs_error_t
icmap_fast_dec_r(const icmap_map_t map
, const char *key_name
)
1019 return (icmap_fast_adjust_int_r(map
, key_name
, -1));
1022 cs_error_t
icmap_fast_dec(const char *key_name
)
1024 return (icmap_fast_dec_r(icmap_global_map
, key_name
));
1027 icmap_iter_t
icmap_iter_init_r(const icmap_map_t map
, const char *prefix
)
1029 return (qb_map_pref_iter_create(map
->qb_map
, prefix
));
1032 icmap_iter_t
icmap_iter_init(const char *prefix
)
1034 return (icmap_iter_init_r(icmap_global_map
, prefix
));
1038 const char *icmap_iter_next(icmap_iter_t iter
, size_t *value_len
, icmap_value_types_t
*type
)
1040 struct icmap_item
*item
;
1043 res
= qb_map_iter_next(iter
, (void **)&item
);
1048 if (value_len
!= NULL
) {
1049 *value_len
= item
->value_len
;
1059 void icmap_iter_finalize(icmap_iter_t iter
)
1061 qb_map_iter_free(iter
);
1064 static void icmap_notify_fn(uint32_t event
, char *key
, void *old_value
, void *value
, void *user_data
)
1066 icmap_track_t icmap_track
= (icmap_track_t
)user_data
;
1067 struct icmap_item
*new_item
= (struct icmap_item
*)value
;
1068 struct icmap_item
*old_item
= (struct icmap_item
*)old_value
;
1069 struct icmap_notify_value new_val
;
1070 struct icmap_notify_value old_val
;
1072 if (value
== NULL
&& old_value
== NULL
) {
1076 if (new_item
!= NULL
) {
1077 new_val
.type
= new_item
->type
;
1078 new_val
.len
= new_item
->value_len
;
1079 new_val
.data
= new_item
->value
;
1081 memset(&new_val
, 0, sizeof(new_val
));
1085 * old_item == new_item if fast functions are used -> don't fill old value
1087 if (old_item
!= NULL
&& old_item
!= new_item
) {
1088 old_val
.type
= old_item
->type
;
1089 old_val
.len
= old_item
->value_len
;
1090 old_val
.data
= old_item
->value
;
1092 memset(&old_val
, 0, sizeof(old_val
));
1095 icmap_track
->notify_fn(icmap_qbtt_to_tt(event
),
1099 icmap_track
->user_data
);
1102 cs_error_t
icmap_track_add(
1103 const char *key_name
,
1105 icmap_notify_fn_t notify_fn
,
1107 icmap_track_t
*icmap_track
)
1111 if (notify_fn
== NULL
|| icmap_track
== NULL
) {
1112 return (CS_ERR_INVALID_PARAM
);
1115 if ((track_type
& ~(ICMAP_TRACK_ADD
| ICMAP_TRACK_DELETE
| ICMAP_TRACK_MODIFY
| ICMAP_TRACK_PREFIX
)) != 0) {
1116 return (CS_ERR_INVALID_PARAM
);
1119 *icmap_track
= malloc(sizeof(**icmap_track
));
1120 if (*icmap_track
== NULL
) {
1121 return (CS_ERR_NO_MEMORY
);
1123 memset(*icmap_track
, 0, sizeof(**icmap_track
));
1125 if (key_name
!= NULL
) {
1126 (*icmap_track
)->key_name
= strdup(key_name
);
1129 (*icmap_track
)->track_type
= track_type
;
1130 (*icmap_track
)->notify_fn
= notify_fn
;
1131 (*icmap_track
)->user_data
= user_data
;
1133 if ((err
= qb_map_notify_add(icmap_global_map
->qb_map
, (*icmap_track
)->key_name
, icmap_notify_fn
,
1134 icmap_tt_to_qbtt(track_type
), *icmap_track
)) != 0) {
1135 free((*icmap_track
)->key_name
);
1138 return (qb_to_cs_error(err
));
1141 list_init(&(*icmap_track
)->list
);
1142 list_add (&(*icmap_track
)->list
, &icmap_track_list_head
);
1147 cs_error_t
icmap_track_delete(icmap_track_t icmap_track
)
1151 if ((err
= qb_map_notify_del_2(icmap_global_map
->qb_map
, icmap_track
->key_name
,
1152 icmap_notify_fn
, icmap_tt_to_qbtt(icmap_track
->track_type
), icmap_track
)) != 0) {
1153 return (qb_to_cs_error(err
));
1156 list_del(&icmap_track
->list
);
1157 free(icmap_track
->key_name
);
1163 void *icmap_track_get_user_data(icmap_track_t icmap_track
)
1165 return (icmap_track
->user_data
);
1168 cs_error_t
icmap_set_ro_access(const char *key_name
, int prefix
, int ro_access
)
1170 struct list_head
*iter
;
1171 struct icmap_ro_access_item
*icmap_ro_ai
;
1173 for (iter
= icmap_ro_access_item_list_head
.next
; iter
!= &icmap_ro_access_item_list_head
; iter
= iter
->next
) {
1174 icmap_ro_ai
= list_entry(iter
, struct icmap_ro_access_item
, list
);
1176 if (icmap_ro_ai
->prefix
== prefix
&& strcmp(key_name
, icmap_ro_ai
->key_name
) == 0) {
1181 return (CS_ERR_EXIST
);
1183 list_del(&icmap_ro_ai
->list
);
1184 free(icmap_ro_ai
->key_name
);
1193 return (CS_ERR_NOT_EXIST
);
1196 icmap_ro_ai
= malloc(sizeof(*icmap_ro_ai
));
1197 if (icmap_ro_ai
== NULL
) {
1198 return (CS_ERR_NO_MEMORY
);
1201 memset(icmap_ro_ai
, 0, sizeof(*icmap_ro_ai
));
1202 icmap_ro_ai
->key_name
= strdup(key_name
);
1203 if (icmap_ro_ai
->key_name
== NULL
) {
1205 return (CS_ERR_NO_MEMORY
);
1208 icmap_ro_ai
->prefix
= prefix
;
1209 list_init(&icmap_ro_ai
->list
);
1210 list_add (&icmap_ro_ai
->list
, &icmap_ro_access_item_list_head
);
1215 int icmap_is_key_ro(const char *key_name
)
1217 struct list_head
*iter
;
1218 struct icmap_ro_access_item
*icmap_ro_ai
;
1220 for (iter
= icmap_ro_access_item_list_head
.next
; iter
!= &icmap_ro_access_item_list_head
; iter
= iter
->next
) {
1221 icmap_ro_ai
= list_entry(iter
, struct icmap_ro_access_item
, list
);
1223 if (icmap_ro_ai
->prefix
) {
1224 if (strlen(icmap_ro_ai
->key_name
) > strlen(key_name
))
1227 if (strncmp(icmap_ro_ai
->key_name
, key_name
, strlen(icmap_ro_ai
->key_name
)) == 0) {
1231 if (strcmp(icmap_ro_ai
->key_name
, key_name
) == 0) {