Merge branch 'stable' into 'main'
[ladish.git] / daemon / dict.c
blobce45a0703dcb2aa430bb01311cfc996a0e488dff
1 /* -*- Mode: C ; c-basic-offset: 2 -*- */
2 /*
3 * LADI Session Handler (ladish)
5 * Copyright (C) 2009, 2010 Nedko Arnaudov <nedko@arnaudov.name>
7 **************************************************************************
8 * This file contains the implementation of the dictionary objects
9 **************************************************************************
11 * LADI Session Handler is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * LADI Session Handler is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with LADI Session Handler. If not, see <http://www.gnu.org/licenses/>
23 * or write to the Free Software Foundation, Inc.,
24 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
27 #include "dict.h"
29 struct ladish_dict_entry
31 struct list_head siblings;
32 char * key;
33 char * value;
36 struct ladish_dict
38 struct list_head entries;
41 bool ladish_dict_create(ladish_dict_handle * dict_handle_ptr)
43 struct ladish_dict * dict_ptr;
45 dict_ptr = malloc(sizeof(struct ladish_dict));
46 if (dict_ptr == NULL)
48 log_error("malloc() failed to allocate struct ladish_dict");
49 return false;
52 INIT_LIST_HEAD(&dict_ptr->entries);
54 *dict_handle_ptr = (ladish_dict_handle)dict_ptr;
56 return true;
59 static struct ladish_dict_entry * ladish_dict_find_key(struct ladish_dict * dict_ptr, const char * key)
61 struct list_head * node_ptr;
62 struct ladish_dict_entry * entry_ptr;
64 list_for_each(node_ptr, &dict_ptr->entries)
66 entry_ptr = list_entry(node_ptr, struct ladish_dict_entry, siblings);
67 if (strcmp(entry_ptr->key, key) == 0)
69 return entry_ptr;
73 return NULL;
76 static void ladish_dict_drop_entry(struct ladish_dict_entry * entry_ptr)
78 list_del(&entry_ptr->siblings);
79 free(entry_ptr->key);
80 free(entry_ptr->value);
81 free(entry_ptr);
84 #define dict_ptr ((struct ladish_dict *)dict_handle)
86 void ladish_dict_destroy(ladish_dict_handle dict_handle)
88 ladish_dict_clear(dict_handle);
89 free(dict_ptr);
92 bool ladish_dict_set(ladish_dict_handle dict_handle, const char * key, const char * value)
94 struct ladish_dict_entry * entry_ptr;
95 char * new_value;
97 entry_ptr = ladish_dict_find_key(dict_ptr, key);
98 if (entry_ptr != NULL)
100 new_value = strdup(value);
101 if (new_value == NULL)
103 log_error("strdup() failed to duplicate dict value");
104 return false;
107 free(entry_ptr->value);
108 entry_ptr->value = new_value;
109 return true;
112 entry_ptr = malloc(sizeof(struct ladish_dict_entry));
113 if (entry_ptr == NULL)
115 log_error("malloc() failed to allocate struct ladish_dict_entry");
116 return false;
119 entry_ptr->key = strdup(key);
120 if (entry_ptr->key == NULL)
122 log_error("strdup() failed to duplicate dict key");
123 free(entry_ptr);
124 return false;
127 entry_ptr->value = strdup(value);
128 if (entry_ptr->value == NULL)
130 log_error("strdup() failed to duplicate dict value");
131 free(entry_ptr->key);
132 free(entry_ptr);
133 return false;
136 list_add_tail(&entry_ptr->siblings, &dict_ptr->entries);
138 return true;
141 const char * ladish_dict_get(ladish_dict_handle dict_handle, const char * key)
143 struct ladish_dict_entry * entry_ptr;
145 entry_ptr = ladish_dict_find_key(dict_ptr, key);
146 if (entry_ptr == NULL)
148 return NULL;
151 ASSERT(entry_ptr->value != NULL);
152 return entry_ptr->value;
155 void ladish_dict_drop(ladish_dict_handle dict_handle, const char * key)
157 struct ladish_dict_entry * entry_ptr;
159 entry_ptr = ladish_dict_find_key(dict_ptr, key);
160 if (entry_ptr != NULL)
162 ladish_dict_drop_entry(entry_ptr);
166 void ladish_dict_clear(ladish_dict_handle dict_handle)
168 struct ladish_dict_entry * entry_ptr;
170 while (!list_empty(&dict_ptr->entries))
172 entry_ptr = list_entry(dict_ptr->entries.next, struct ladish_dict_entry, siblings);
173 ladish_dict_drop_entry(entry_ptr);
177 bool ladish_dict_iterate(ladish_dict_handle dict_handle, void * context, bool (* callback)(void * context, const char * key, const char * value))
179 struct list_head * node_ptr;
180 struct ladish_dict_entry * entry_ptr;
182 list_for_each(node_ptr, &dict_ptr->entries)
184 entry_ptr = list_entry(node_ptr, struct ladish_dict_entry, siblings);
185 if (!callback(context, entry_ptr->key, entry_ptr->value))
187 return false;
191 return true;
194 bool ladish_dict_is_empty(ladish_dict_handle dict_handle)
196 return list_empty(&dict_ptr->entries);
199 #undef dict_ptr
201 static bool dup_key(void * context, const char * key, const char * value)
203 return ladish_dict_set(context, key, value);
206 bool ladish_dict_dup(ladish_dict_handle src, ladish_dict_handle * dst_ptr)
208 ladish_dict_handle dst;
210 if (!ladish_dict_create(&dst))
212 return false;
215 if (!ladish_dict_iterate(src, dst, dup_key))
217 ladish_dict_destroy(dst);
218 return false;
221 *dst_ptr = dst;
222 return true;