settings: Add functions to add sections and key/value pairs to a section
[strongswan.git] / src / libstrongswan / settings / settings_types.c
1 /*
2 * Copyright (C) 2010-2014 Tobias Brunner
3 * Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include "settings_types.h"
17
18 /*
19 * Described in header
20 */
21 kv_t *settings_kv_create(char *key, char *value)
22 {
23 kv_t *this;
24
25 INIT(this,
26 .key = key,
27 .value = value,
28 );
29 return this;
30 }
31
32 /*
33 * Described in header
34 */
35 void settings_kv_destroy(kv_t *this, array_t *contents)
36 {
37 free(this->key);
38 if (contents && this->value)
39 {
40 array_insert(contents, ARRAY_TAIL, this->value);
41 }
42 else
43 {
44 free(this->value);
45 }
46 free(this);
47 }
48
49 /*
50 * Described in header
51 */
52 section_t *settings_section_create(char *name)
53 {
54 section_t *this;
55
56 INIT(this,
57 .name = name,
58 );
59 return this;
60 }
61
62 static void section_destroy(section_t *section, int idx, array_t *contents)
63 {
64 settings_section_destroy(section, contents);
65 }
66
67 static void kv_destroy(kv_t *kv, int idx, array_t *contents)
68 {
69 settings_kv_destroy(kv, contents);
70 }
71
72 /*
73 * Described in header
74 */
75 void settings_section_destroy(section_t *this, array_t *contents)
76 {
77 array_destroy_function(this->sections, (void*)section_destroy, contents);
78 array_destroy_function(this->kv, (void*)kv_destroy, contents);
79 array_destroy(this->fallbacks);
80 free(this->name);
81 free(this);
82 }
83
84 /*
85 * Described in header
86 */
87 void settings_kv_add(section_t *section, kv_t *kv, array_t *contents)
88 {
89 kv_t *found;
90
91 if (array_bsearch(section->kv, kv->key, settings_kv_find, &found) == -1)
92 {
93 array_insert_create(&section->kv, ARRAY_TAIL, kv);
94 array_sort(section->kv, settings_kv_sort, NULL);
95 }
96 else
97 {
98 if (contents && found->value)
99 {
100 array_insert(contents, ARRAY_TAIL, found->value);
101 }
102 else
103 {
104 free(found->value);
105 }
106 found->value = kv->value;
107 kv->value = NULL;
108 settings_kv_destroy(kv, NULL);
109 }
110 }
111
112 /*
113 * Described in header
114 */
115 void settings_section_add(section_t *parent, section_t *section,
116 array_t *contents)
117 {
118 section_t *found;
119
120 if (array_bsearch(parent->sections, section->name, settings_section_find,
121 &found) == -1)
122 {
123 array_insert_create(&parent->sections, ARRAY_TAIL, section);
124 array_sort(parent->sections, settings_section_sort, NULL);
125 }
126 else
127 {
128 settings_section_extend(found, section, contents);
129 settings_section_destroy(section, contents);
130 }
131 }
132
133 /*
134 * Described in header
135 */
136 void settings_section_extend(section_t *base, section_t *extension,
137 array_t *contents)
138 {
139 enumerator_t *enumerator;
140 section_t *section;
141 kv_t *kv;
142
143 enumerator = array_create_enumerator(extension->sections);
144 while (enumerator->enumerate(enumerator, (void**)&section))
145 {
146 array_remove_at(extension->sections, enumerator);
147 settings_section_add(base, section, contents);
148 }
149 enumerator->destroy(enumerator);
150
151 enumerator = array_create_enumerator(extension->kv);
152 while (enumerator->enumerate(enumerator, (void**)&kv))
153 {
154 array_remove_at(extension->kv, enumerator);
155 settings_kv_add(base, kv, contents);
156 }
157 enumerator->destroy(enumerator);
158 }
159
160 /*
161 * Described in header
162 */
163 int settings_section_find(const void *a, const void *b)
164 {
165 const char *key = a;
166 const section_t *item = b;
167 return strcmp(key, item->name);
168 }
169
170 /*
171 * Described in header
172 */
173 int settings_section_sort(const void *a, const void *b, void *user)
174 {
175 const section_t *sa = a, *sb = b;
176 return strcmp(sa->name, sb->name);
177 }
178
179 /*
180 * Described in header
181 */
182 int settings_kv_find(const void *a, const void *b)
183 {
184 const char *key = a;
185 const kv_t *item = b;
186 return strcmp(key, item->key);
187 }
188
189 /*
190 * Described in header
191 */
192 int settings_kv_sort(const void *a, const void *b, void *user)
193 {
194 const kv_t *kva = a, *kvb = b;
195 return strcmp(kva->key, kvb->key);
196 }