4976a3b6c866d102fc8e1899fc44f0dbf2d2cd94
[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)
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_section_extend(section_t *base, section_t *extension,
88 array_t *contents)
89 {
90 enumerator_t *enumerator;
91 section_t *sec;
92 kv_t *kv;
93
94 enumerator = array_create_enumerator(extension->sections);
95 while (enumerator->enumerate(enumerator, (void**)&sec))
96 {
97 section_t *found;
98 if (array_bsearch(base->sections, sec->name, settings_section_find,
99 &found) != -1)
100 {
101 settings_section_extend(found, sec, contents);
102 }
103 else
104 {
105 array_remove_at(extension->sections, enumerator);
106 array_insert_create(&base->sections, ARRAY_TAIL, sec);
107 array_sort(base->sections, settings_section_sort, NULL);
108 }
109 }
110 enumerator->destroy(enumerator);
111
112 enumerator = array_create_enumerator(extension->kv);
113 while (enumerator->enumerate(enumerator, (void**)&kv))
114 {
115 kv_t *found;
116 if (array_bsearch(base->kv, kv->key, settings_kv_find, &found) != -1)
117 {
118 if (contents)
119 {
120 array_insert(contents, ARRAY_TAIL, found->value);
121 }
122 else
123 {
124 free(found->value);
125 }
126 found->value = kv->value;
127 kv->value = NULL;
128 }
129 else
130 {
131 array_remove_at(extension->kv, enumerator);
132 array_insert_create(&base->kv, ARRAY_TAIL, kv);
133 array_sort(base->kv, settings_kv_sort, NULL);
134 }
135 }
136 enumerator->destroy(enumerator);
137 }
138
139 /*
140 * Described in header
141 */
142 int settings_section_find(const void *a, const void *b)
143 {
144 const char *key = a;
145 const section_t *item = b;
146 return strcmp(key, item->name);
147 }
148
149 /*
150 * Described in header
151 */
152 int settings_section_sort(const void *a, const void *b, void *user)
153 {
154 const section_t *sa = a, *sb = b;
155 return strcmp(sa->name, sb->name);
156 }
157
158 /*
159 * Described in header
160 */
161 int settings_kv_find(const void *a, const void *b)
162 {
163 const char *key = a;
164 const kv_t *item = b;
165 return strcmp(key, item->key);
166 }
167
168 /*
169 * Described in header
170 */
171 int settings_kv_sort(const void *a, const void *b, void *user)
172 {
173 const kv_t *kva = a, *kvb = b;
174 return strcmp(kva->key, kvb->key);
175 }