1 // This file is under GNU General Public License 3.0
4 #include "pEp_internal.h"
10 #include "stringpair.h"
12 DYNAMIC_API stringpair_t * new_stringpair(const char *key, const char *value)
14 stringpair_t *pair = NULL;
16 // key and value should not be NULL, that's bad style (while legal)
21 pair = calloc(1, sizeof(stringpair_t));
26 pair->key = key ? strdup(key) : strdup("");
28 if (pair->key == NULL)
31 pair->value = value ? strdup(value) : strdup("");
33 if (pair->value == NULL)
39 free_stringpair(pair);
43 DYNAMIC_API void free_stringpair(stringpair_t * pair)
52 DYNAMIC_API stringpair_t * stringpair_dup(const stringpair_t *src)
58 return new_stringpair(src->key, src->value);
61 DYNAMIC_API stringpair_list_t *new_stringpair_list(stringpair_t *value)
63 stringpair_list_t *result = calloc(1, sizeof(stringpair_list_t));
67 result->value = value;
72 DYNAMIC_API stringpair_list_t *stringpair_list_dup(
73 const stringpair_list_t *src
80 stringpair_t* copy_pair = stringpair_dup(src->value);
82 stringpair_list_t *dst = new_stringpair_list(copy_pair);
86 stringpair_list_t* src_curr = src->next;
87 stringpair_list_t** dst_curr_ptr = &dst->next;
90 copy_pair = stringpair_dup(src_curr->value);
91 if (copy_pair == NULL) {
92 free_stringpair_list(dst);
95 *dst_curr_ptr = new_stringpair_list(copy_pair);
96 if (*dst_curr_ptr == NULL) {
97 free_stringpair(copy_pair);
98 free_stringpair_list(dst);
101 src_curr = src_curr->next;
102 dst_curr_ptr = &((*dst_curr_ptr)->next);
109 DYNAMIC_API stringpair_list_t *stringpair_list_add(
110 stringpair_list_t *stringpair_list,
116 // empty list (no nodes)
117 if (stringpair_list == NULL)
118 return new_stringpair_list(value);
120 // empty list (one node, no value)
121 if (stringpair_list->value == NULL) {
122 if (stringpair_list->next)
123 return NULL; // invalid list
125 stringpair_list->value = value;
126 assert(stringpair_list->value);
128 if (stringpair_list->value == NULL)
131 return stringpair_list;
134 stringpair_list_t* list_curr = stringpair_list;
136 while (list_curr->next)
137 list_curr = list_curr->next;
139 list_curr->next = new_stringpair_list(value);
141 assert(list_curr->next);
142 if (list_curr->next == NULL)
145 return list_curr->next;
149 DYNAMIC_API stringpair_list_t *stringpair_list_append(
150 stringpair_list_t *stringpair_list,
151 stringpair_list_t *second
154 assert(stringpair_list);
155 if (stringpair_list == NULL)
158 // second list is empty
159 if (second == NULL || second->value == NULL)
160 return stringpair_list;
162 stringpair_list_t *_s = stringpair_list;
163 for (stringpair_list_t *_s2 = second; _s2 != NULL; _s2 = _s2->next) {
164 stringpair_t *_sp = stringpair_dup(_s2->value);
167 _s = stringpair_list_add(_s, _sp);
169 free_stringpair(_sp);
176 DYNAMIC_API int stringpair_list_length(
177 const stringpair_list_t *stringpair_list
182 for (const stringpair_list_t *_sl = stringpair_list; _sl && _sl->value; _sl = _sl->next)
188 DYNAMIC_API void free_stringpair_list(stringpair_list_t *stringpair_list)
190 if (stringpair_list) {
191 free_stringpair_list(stringpair_list->next);
192 free_stringpair(stringpair_list->value);
193 free(stringpair_list);
198 DYNAMIC_API stringpair_list_t *stringpair_list_delete_by_key(
199 stringpair_list_t *sp_list,
206 if (sp_list->value == NULL) {
207 free_stringpair_list(sp_list);
214 stringpair_list_t *_sl;
215 stringpair_list_t *last = NULL;
216 for (_sl = sp_list; _sl && _sl->value && _sl->value->key; _sl = _sl->next) {
217 if (strcmp(_sl->value->key, key) == 0) {
219 sp_list = sp_list->next;
221 last->next = _sl->next;
223 free_stringpair_list(_sl);
232 DYNAMIC_API stringpair_list_t *stringpair_list_find(
233 stringpair_list_t *stringpair_list,
239 for (stringpair_list_t *_l = stringpair_list; _l; _l = _l->next) {
240 if (strcoll(key, _l->value->key) == 0)