1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <platform/cbassert.h>
5 
6 #include <libconflate/conflate.h>
7 
mk_kvpair(const char* k, char** v)8 kvpair_t* mk_kvpair(const char* k, char** v)
9 {
10     kvpair_t* rv = calloc(1, sizeof(kvpair_t));
11     cb_assert(rv);
12 
13     rv->key = safe_strdup(k);
14     if (v) {
15         int i = 0;
16         for (i = 0; v[i]; i++) {
17             add_kvpair_value(rv, v[i]);
18         }
19     } else {
20         rv->allocated_values = 4;
21         rv->values = calloc(4, sizeof(char*));
22         cb_assert(rv->values);
23     }
24 
25     return rv;
26 }
27 
add_kvpair_value(kvpair_t* pair, const char* value)28 void add_kvpair_value(kvpair_t* pair, const char* value)
29 {
30     cb_assert(pair);
31     cb_assert(value);
32 
33     /* The last item in the values list must be null as it acts a sentinal */
34     if (pair->allocated_values == 0 ||
35             (pair->used_values + 1) == pair->allocated_values) {
36         pair->allocated_values = pair->allocated_values << 1;
37         if (pair->allocated_values == 0) {
38             pair->allocated_values = 4;
39         }
40 
41         pair->values = realloc(pair->values,
42                                sizeof(char*) * pair->allocated_values);
43         cb_assert(pair->values);
44     }
45 
46     pair->values[pair->used_values++] = safe_strdup(value);
47     pair->values[pair->used_values] = 0;
48 }
49 
free_kvpair(kvpair_t* pair)50 void free_kvpair(kvpair_t* pair)
51 {
52     if (pair) {
53         free_kvpair(pair->next);
54         free(pair->key);
55         free_string_list(pair->values);
56         free(pair);
57     }
58 }
59 
walk_kvpair(kvpair_t *pair, void *opaque, kvpair_visitor_t visitor)60 void walk_kvpair(kvpair_t *pair, void *opaque, kvpair_visitor_t visitor)
61 {
62     bool keep_going = true;
63     while (keep_going && pair) {
64         keep_going = visitor(opaque,
65                              (const char*)pair->key,
66                              (const char **)pair->values);
67         pair = pair->next;
68     }
69 }
70 
find_kvpair(kvpair_t* pair, const char* key)71 kvpair_t* find_kvpair(kvpair_t* pair, const char* key)
72 {
73     cb_assert(key);
74 
75     while (pair && strcmp(pair->key, key) != 0) {
76         pair = pair->next;
77     }
78 
79     return pair;
80 }
81 
get_simple_kvpair_val(kvpair_t *pair, const char *key)82 char *get_simple_kvpair_val(kvpair_t *pair, const char *key)
83 {
84     char *rv = NULL;
85     kvpair_t *found;
86     cb_assert(key);
87     found = find_kvpair(pair, key);
88 
89     if (found) {
90         rv = found->values[0];
91     }
92 
93     return rv;
94 }
95 
dup_kvpair(kvpair_t *pair)96 kvpair_t *dup_kvpair(kvpair_t *pair)
97 {
98     kvpair_t *copy;
99     cb_assert(pair);
100     copy = mk_kvpair(pair->key, pair->values);
101     if (pair->next) {
102         copy->next = dup_kvpair(pair->next);
103     }
104     return copy;
105 }
106