Introduce domain manager
[profile/ivi/genivi/genivi-audio-manager.git] / domain-manager / ini-parser.c
1 /*
2 Copyright (c) 2014, Intel Corporation
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are
6 met:
7
8     * Redistributions of source code must retain the above copyright
9       notice, this list of conditions and the following disclaimer.
10
11     * Redistributions in binary form must reproduce the above copyright
12       notice, this list of conditions and the following disclaimer in
13       the documentation and/or other materials provided with the
14       distribution.
15
16     * Neither the name of Intel Corporation nor the names of its
17       contributors may be used to endorse or promote products derived
18       from this software without specific prior written permission.
19
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
21 IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
24 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 #include <murphy/common.h>
34
35 #include "ini-parser.h"
36
37
38 int initialize_parser_buffer(ini_parser_context_t *ctx)
39 {
40     /* buffers points to the array of buffers. End points to the last
41      * character position in the buffer, and current points to the
42      * buffer position that will be written next. */
43
44     int i;
45
46     for (i = 0; i < 10; i++) {
47         ctx->buffers[i] = NULL;
48     }
49
50     ctx->buffers[0] = mrp_alloc(CHARACTER_BUFFER_SIZE * sizeof(char));
51     if (!ctx->buffers[0]) {
52         return -1;
53     }
54
55     ctx->end = ctx->buffers[0] + CHARACTER_BUFFER_SIZE-1;
56     ctx->current = ctx->buffers[0];
57     ctx->buffer_i = 0;
58
59     ctx->error = 0;
60
61     return 0;
62 }
63
64
65 char *new_parser_str(ini_parser_context_t *ctx, char *input)
66 {
67     int len = strlen(input);
68     char *newend, *p;
69
70     if (ctx->buffers[ctx->buffer_i] == NULL) {
71         return NULL;
72     }
73
74     /* newend points to the last character position required for the
75      * input */
76
77     newend = ctx->current + len;
78
79     if (newend > ctx->end) {
80         /* OOM, let's allocate a new buffer */
81         if (++(ctx->buffer_i) >= MAX_BUFFERS) {
82             return NULL;
83         }
84
85         ctx->buffers[ctx->buffer_i] = mrp_alloc(CHARACTER_BUFFER_SIZE * sizeof(char));
86         if (ctx->buffers[ctx->buffer_i] == NULL) {
87             return NULL;
88         }
89         ctx->end = ctx->buffers[ctx->buffer_i] + CHARACTER_BUFFER_SIZE-1;
90         ctx->current = ctx->buffers[ctx->buffer_i];
91
92         newend = ctx->current + len;
93
94         if (newend > ctx->end) {
95             /* input is longer than the MAX buffer size */
96             return NULL;
97         }
98     }
99
100     strncpy(ctx->current, input, len);
101
102     p = ctx->current;
103     *newend = '\0';
104     ctx->current = newend + 1;
105
106     return p;
107 }
108
109
110 void delete_parser_buffer(ini_parser_context_t *ctx)
111 {
112     int i;
113
114     for (i = 0; i < MAX_BUFFERS; i++) {
115         mrp_free(ctx->buffers[i]);
116         ctx->buffers[i] = NULL;
117     }
118     ctx->buffer_i = 0;
119     ctx->current = NULL;
120     ctx->end = NULL;
121 }
122
123
124 void init_result(ini_parser_result_t *result)
125 {
126     /* printf("> init_result (%p)\n", result); */
127     mrp_list_init(&result->sections);
128     result->current = NULL;
129 }
130
131
132 void add_section(ini_parser_result_t *result, const char *name)
133 {
134     ini_parser_section_t *section;
135
136     if (!result)
137         goto error;
138
139     section = mrp_allocz(sizeof(ini_parser_section_t));
140     if (!section)
141         goto error;
142
143     section->name = strdup(name);
144     if (!section->name)
145         goto error;
146
147     mrp_list_init(&section->pairs);
148     mrp_list_init(&section->hook);
149     mrp_list_append(&result->sections, &section->hook);
150
151     result->current = section;
152
153     return;
154
155 error:
156     mrp_log_error("add_section ERROR (%s)", name);
157     return;
158 }
159
160
161 void add_key(ini_parser_result_t *result, const char *key)
162 {
163     ini_parser_section_t *section;
164     ini_parser_keyvaluepair_t *pair;
165
166     if (!result)
167         goto error;
168
169     section = result->current;
170
171     if (!section || section->current) {
172         mrp_log_error("add_key section error %p", section);
173         goto error;
174     }
175
176     pair = mrp_allocz(sizeof(ini_parser_keyvaluepair_t));
177     if (!pair)
178         goto error;
179
180     mrp_list_init(&pair->hook);
181     mrp_list_append(&section->pairs, &pair->hook);
182
183     pair->key = mrp_strdup(key);
184     if (!pair->key)
185         goto error;
186
187     section->current = pair;
188
189     return;
190
191 error:
192     mrp_log_error("add_key ERROR (%s)", key);
193     return;
194 }
195
196
197 void add_modifier(ini_parser_result_t *result, const char *modifier)
198 {
199     ini_parser_section_t *section;
200     ini_parser_keyvaluepair_t *pair;
201
202     /* printf("> add_modifier (%s)\n", modifier); */
203
204     if (!result)
205         goto error;
206
207     section = result->current;
208     if (!section)
209         goto error;
210
211     pair = section->current;
212     if (!pair)
213         goto error;
214
215     pair->modifier = mrp_strdup(modifier);
216     if (!pair->modifier)
217         goto error;
218
219     return;
220
221 error:
222     mrp_log_error("add_modifier ERROR (%s)", modifier);
223     return;
224 }
225
226
227 void add_value(ini_parser_result_t *result, const char *value)
228 {
229     ini_parser_section_t *section;
230     ini_parser_keyvaluepair_t *pair;
231
232     /* printf("> add_value (%s)\n", value); */
233
234     if (!result)
235         goto error;
236
237     section = result->current;
238     if (!section)
239         goto error;
240
241     pair = section->current;
242     if (!pair)
243         goto error;
244
245     pair->value = mrp_strdup(value);
246     if (!pair->value)
247         goto error;
248
249     section->current = NULL;
250
251     return;
252
253 error:
254     mrp_log_error("add_value ERROR (%s)", value);
255     return;
256 }
257
258
259 void deinit_result(ini_parser_result_t *result)
260 {
261     mrp_list_hook_t *sp, *sn, *kp, *kn;
262
263     if (!result)
264         return;
265
266     mrp_list_foreach(&result->sections, sp, sn) {
267         ini_parser_section_t *section;
268
269         section = mrp_list_entry(sp, typeof(*section), hook);
270         mrp_list_delete(&section->hook);
271
272         mrp_list_foreach(&section->pairs, kp, kn) {
273             ini_parser_keyvaluepair_t *pair;
274
275             pair = mrp_list_entry(kp, typeof(*pair), hook);
276             mrp_list_delete(&pair->hook);
277
278             mrp_free(pair->key);
279             mrp_free(pair->modifier);
280             mrp_free(pair->value);
281             mrp_free(pair);
282         }
283
284         mrp_free(section->name);
285         mrp_free(section);
286     }
287
288     return;
289 }
290
291
292 static void print_pair(ini_parser_keyvaluepair_t *pair)
293 {
294     mrp_debug("%s[%s]=%s", pair->key, pair->modifier ? pair->modifier : "",
295         pair->value);
296 }
297
298
299 void print_result(ini_parser_result_t *result)
300 {
301     mrp_list_hook_t *sp, *sn, *kp, *kn;
302
303     if (!result)
304         return;
305
306     mrp_list_foreach(&result->sections, sp, sn) {
307
308         ini_parser_section_t *section;
309
310         section = mrp_list_entry(sp, typeof(*section), hook);
311
312         mrp_debug("[%s]", section->name);
313
314         mrp_list_foreach(&section->pairs, kp, kn) {
315             ini_parser_keyvaluepair_t *pair;
316
317             pair = mrp_list_entry(kp, typeof(*pair), hook);
318             print_pair(pair);
319         }
320         mrp_debug("");
321     }
322
323     return;
324 }