Line | Branch | Exec | Source |
---|---|---|---|
1 | /* GATE PROJECT LICENSE: | ||
2 | +----------------------------------------------------------------------------+ | ||
3 | | Copyright(c) 2018-2025, Stefan Meislinger <sm@opengate.at> | | ||
4 | | All rights reserved. | | ||
5 | | | | ||
6 | | Redistribution and use in source and binary forms, with or without | | ||
7 | | modification, are permitted provided that the following conditions are met:| | ||
8 | | | | ||
9 | | 1. Redistributions of source code must retain the above copyright notice, | | ||
10 | | this list of conditions and the following disclaimer. | | ||
11 | | 2. Redistributions in binary form must reproduce the above copyright | | ||
12 | | notice, this list of conditions and the following disclaimer in the | | ||
13 | | documentation and/or other materials provided with the distribution. | | ||
14 | | | | ||
15 | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"| | ||
16 | | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | | ||
17 | | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | | ||
18 | | ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | | ||
19 | | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | | ||
20 | | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | ||
21 | | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | ||
22 | | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | ||
23 | | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | ||
24 | | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF | | ||
25 | | THE POSSIBILITY OF SUCH DAMAGE. | | ||
26 | +----------------------------------------------------------------------------+ | ||
27 | */ | ||
28 | |||
29 | #include "gate/encode/inifiles.h" | ||
30 | #include "gate/comparers.h" | ||
31 | #include "gate/results.h" | ||
32 | |||
33 | 71 | static gate_flatmap_iterator_t gate_inifile_store_use_section(gate_inifile_store_t* store, gate_string_t const* section) | |
34 | { | ||
35 | 71 | gate_flatmap_iterator_t iter = gate_flatmap_get(&store->sections, section); | |
36 | 71 | gate_flatmap_t content = GATE_INIT_EMPTY; | |
37 | |||
38 |
2/2✓ Branch 1 taken 28 times.
✓ Branch 2 taken 43 times.
|
71 | if (!gate_flatmap_iterator_valid(&store->sections, iter)) |
39 | { | ||
40 |
1/2✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
|
28 | if (NULL != gate_flatmap_create(&content, &gate_compare_string, |
41 | sizeof(gate_string_t), &gate_string_copy_constructor, &gate_string_destructor, | ||
42 | sizeof(gate_string_t), &gate_string_copy_constructor, &gate_string_destructor)) | ||
43 | { | ||
44 | 28 | iter = gate_flatmap_add(&store->sections, section, &content); | |
45 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 28 times.
|
28 | if (!iter) |
46 | { | ||
47 | ✗ | gate_flatmap_destroy(&content); | |
48 | } | ||
49 | } | ||
50 | } | ||
51 | 71 | return iter; | |
52 | } | ||
53 | |||
54 | 14 | gate_result_t gate_inifile_store_create(gate_inifile_store_t* store) | |
55 | { | ||
56 | 14 | gate_result_t ret = GATE_RESULT_FAILED; | |
57 | gate_flatmap_iterator_t global_section_entry; | ||
58 | static gate_string_t const empty_string = GATE_STRING_INIT_EMPTY; | ||
59 | |||
60 | do | ||
61 | { | ||
62 | 14 | gate_mem_clear(store, sizeof(gate_inifile_store_t)); | |
63 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
|
14 | if (NULL == gate_flatmap_create(&store->sections, &gate_compare_string, |
64 | sizeof(gate_string_t), &gate_string_copy_constructor, &gate_string_destructor, | ||
65 | sizeof(gate_flatmap_t), &gate_flatmap_copy_constructor, &gate_flatmap_destructor)) | ||
66 | { | ||
67 | ✗ | ret = GATE_RESULT_OUTOFMEMORY; | |
68 | ✗ | break; | |
69 | } | ||
70 | |||
71 | 14 | global_section_entry = gate_inifile_store_use_section(store, &empty_string); | |
72 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
|
14 | if (NULL == global_section_entry) |
73 | { | ||
74 | ✗ | gate_flatmap_destroy(&store->sections); | |
75 | ✗ | ret = GATE_RESULT_OUTOFMEMORY; | |
76 | ✗ | break; | |
77 | } | ||
78 | |||
79 | 14 | ret = GATE_RESULT_OK; | |
80 | } while (0); | ||
81 | |||
82 | 14 | return ret; | |
83 | } | ||
84 | ✗ | gate_result_t gate_inifile_store_copy(gate_inifile_store_t* store, gate_inifile_store_t const* source) | |
85 | { | ||
86 | ✗ | if (NULL == gate_flatmap_copy(&store->sections, &source->sections)) | |
87 | { | ||
88 | ✗ | return GATE_RESULT_OUTOFMEMORY; | |
89 | } | ||
90 | ✗ | return GATE_RESULT_OK; | |
91 | } | ||
92 | |||
93 | |||
94 | 14 | gate_result_t gate_inifile_store_destroy(gate_inifile_store_t* store) | |
95 | { | ||
96 | 14 | gate_result_t ret = GATE_RESULT_FAILED; | |
97 |
1/2✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
|
14 | if (store) |
98 | { | ||
99 | 14 | gate_flatmap_destroy(&store->sections); | |
100 | 14 | ret = GATE_RESULT_OK; | |
101 | } | ||
102 | 14 | return ret; | |
103 | } | ||
104 | |||
105 | |||
106 | 13 | gate_result_t gate_inifile_store_add_section(gate_inifile_store_t* store, gate_string_t const* section) | |
107 | { | ||
108 | 13 | gate_flatmap_iterator_t section_entry = gate_inifile_store_use_section(store, section); | |
109 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
|
13 | if (section_entry == NULL) |
110 | { | ||
111 | ✗ | return GATE_RESULT_OUTOFMEMORY; | |
112 | } | ||
113 | else | ||
114 | { | ||
115 | 13 | return GATE_RESULT_OK; | |
116 | } | ||
117 | } | ||
118 | ✗ | gate_result_t gate_inifile_store_remove_section(gate_inifile_store_t* store, gate_string_t const* section) | |
119 | { | ||
120 | ✗ | if (gate_flatmap_remove(&store->sections, section)) | |
121 | { | ||
122 | ✗ | return GATE_RESULT_OK; | |
123 | } | ||
124 | else | ||
125 | { | ||
126 | ✗ | return GATE_RESULT_OK_UNCHANGED; | |
127 | } | ||
128 | } | ||
129 | 44 | gate_result_t gate_inifile_store_set(gate_inifile_store_t* store, gate_string_t const* section, | |
130 | gate_string_t const* key, gate_string_t const* value) | ||
131 | { | ||
132 | 44 | gate_result_t ret = GATE_RESULT_OK; | |
133 | gate_flatmap_iterator_t section_entry; | ||
134 | gate_flatmap_t* entry_map; | ||
135 | |||
136 | do | ||
137 | { | ||
138 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 44 times.
|
44 | if (gate_string_is_empty(key)) |
139 | { | ||
140 | /* a key MUST NOT be empty */ | ||
141 | ✗ | ret = GATE_RESULT_INVALIDARG; | |
142 | ✗ | break; | |
143 | } | ||
144 | 44 | section_entry = gate_inifile_store_use_section(store, section); | |
145 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 44 times.
|
44 | if (NULL == section_entry) |
146 | { | ||
147 | /* failed to access or create section */ | ||
148 | ✗ | ret = GATE_RESULT_OUTOFMEMORY; | |
149 | ✗ | break; | |
150 | } | ||
151 | 44 | entry_map = (gate_flatmap_t*)gate_flatmap_iterator_value(section_entry); | |
152 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 44 times.
|
44 | if (NULL == entry_map) |
153 | { | ||
154 | /* section entry is invalid */ | ||
155 | ✗ | ret = GATE_RESULT_INVALIDCONTENT; | |
156 | ✗ | break; | |
157 | } | ||
158 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 44 times.
|
44 | if (NULL == gate_flatmap_add(entry_map, key, value)) |
159 | { | ||
160 | /* failed to add */ | ||
161 | ✗ | ret = GATE_RESULT_OUTOFMEMORY; | |
162 | ✗ | break; | |
163 | } | ||
164 | /* new value successfully attached */ | ||
165 | 44 | ret = GATE_RESULT_OK; | |
166 | } while (0); | ||
167 | |||
168 | 44 | return ret; | |
169 | } | ||
170 | 8 | gate_result_t gate_inifile_store_get(gate_inifile_store_t const* store, gate_string_t const* section, | |
171 | gate_string_t const* key, gate_string_t* return_value) | ||
172 | { | ||
173 | 8 | gate_result_t ret = GATE_RESULT_OK; | |
174 | gate_flatmap_iterator_t section_entry; | ||
175 | gate_flatmap_t* entry_map; | ||
176 | gate_flatmap_iterator_t entry_iter; | ||
177 | |||
178 | do | ||
179 | { | ||
180 | 8 | section_entry = gate_flatmap_get(&store->sections, section); | |
181 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
|
8 | if (NULL == section_entry) |
182 | { | ||
183 | /* failed to access or create section */ | ||
184 | ✗ | ret = GATE_RESULT_OUTOFMEMORY; | |
185 | ✗ | break; | |
186 | } | ||
187 | 8 | entry_map = (gate_flatmap_t*)gate_flatmap_iterator_value(section_entry); | |
188 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
|
8 | if (NULL == entry_map) |
189 | { | ||
190 | /* section entry is invalid */ | ||
191 | ✗ | ret = GATE_RESULT_INVALIDCONTENT; | |
192 | ✗ | break; | |
193 | } | ||
194 | 8 | entry_iter = gate_flatmap_get(entry_map, key); | |
195 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
|
8 | if (NULL == entry_iter) |
196 | { | ||
197 | /* key does not exist in section */ | ||
198 | ✗ | ret = GATE_RESULT_NOMATCH; | |
199 | ✗ | break; | |
200 | } | ||
201 | |||
202 |
1/2✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
|
8 | if (NULL != return_value) |
203 | { | ||
204 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
|
8 | if (NULL == gate_string_duplicate(return_value, (gate_string_t const*)gate_flatmap_iterator_value(entry_iter))) |
205 | { | ||
206 | ✗ | ret = GATE_RESULT_OUTOFMEMORY; | |
207 | ✗ | break; | |
208 | } | ||
209 | } | ||
210 | /* value successfully retrieved */ | ||
211 | 8 | ret = GATE_RESULT_OK; | |
212 | } while (0); | ||
213 | |||
214 | 8 | return ret; | |
215 | } | ||
216 | |||
217 | 4 | gate_result_t gate_inifile_store_remove(gate_inifile_store_t* store, gate_string_t const* section, gate_string_t const* key) | |
218 | { | ||
219 | 4 | gate_result_t ret = GATE_RESULT_FAILED; | |
220 | gate_flatmap_iterator_t section_entry; | ||
221 | gate_flatmap_t* entry_map; | ||
222 | |||
223 | do | ||
224 | { | ||
225 | 4 | section_entry = gate_flatmap_get(&store->sections, section); | |
226 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | if (NULL == section_entry) |
227 | { | ||
228 | /* failed to access or create section */ | ||
229 | ✗ | ret = GATE_RESULT_OUTOFMEMORY; | |
230 | ✗ | break; | |
231 | } | ||
232 | 4 | entry_map = (gate_flatmap_t*)gate_flatmap_iterator_value(section_entry); | |
233 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | if (NULL == entry_map) |
234 | { | ||
235 | /* section entry is invalid */ | ||
236 | ✗ | ret = GATE_RESULT_INVALIDCONTENT; | |
237 | ✗ | break; | |
238 | } | ||
239 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
|
4 | if (!gate_flatmap_remove(entry_map, key)) |
240 | { | ||
241 | /* entry key does not exist */ | ||
242 | ✗ | ret = GATE_RESULT_NOMATCH; | |
243 | ✗ | break; | |
244 | } | ||
245 | |||
246 | /* entry successfully removed */ | ||
247 | 4 | ret = GATE_RESULT_OK; | |
248 | } while (0); | ||
249 | |||
250 | 4 | return ret; | |
251 | } | ||
252 | |||
253 | |||
254 | |||
255 | |||
256 | |||
257 | 13 | gate_result_t gate_inifile_store_load(gate_inifile_store_t* inistore, gate_stream_t* input) | |
258 | { | ||
259 | 13 | gate_result_t ret = GATE_RESULT_FAILED; | |
260 | 13 | gate_string_t current_section = GATE_STRING_INIT_EMPTY; | |
261 | char buffer[8192]; | ||
262 | 13 | gate_uint64_t comment_counter = 0; | |
263 | 13 | char comment_id[128] = ";;;;;;;;;;;;;;;;"; | |
264 | gate_size_t linelen; | ||
265 | 13 | gate_string_t comment_key = GATE_STRING_INIT_EMPTY; | |
266 | 13 | gate_string_t current_line = GATE_STRING_INIT_EMPTY; | |
267 | 13 | gate_string_t current_key = GATE_STRING_INIT_EMPTY; | |
268 | 13 | gate_string_t current_value = GATE_STRING_INIT_EMPTY; | |
269 | gate_size_t pos; | ||
270 | gate_char8_t chr; | ||
271 | gate_char8_t chr_last; | ||
272 | |||
273 | do | ||
274 | { | ||
275 | 13 | ret = GATE_RESULT_OK; | |
276 |
1/2✓ Branch 0 taken 80 times.
✗ Branch 1 not taken.
|
80 | while (GATE_SUCCEEDED(ret)) |
277 | { | ||
278 | 80 | ret = gate_stream_read_line(input, buffer, sizeof(buffer), &linelen); | |
279 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 80 times.
|
80 | GATE_BREAK_IF_FAILED(ret); |
280 |
2/2✓ Branch 0 taken 13 times.
✓ Branch 1 taken 67 times.
|
80 | if (linelen == 0) |
281 | { | ||
282 | /* end of stream reached */ | ||
283 | 13 | break; | |
284 | } | ||
285 | |||
286 | 67 | gate_string_create_static_len(¤t_line, buffer, linelen); | |
287 | 67 | gate_string_rtrim(¤t_line, ¤t_line); | |
288 | 67 | gate_string_ltrim(¤t_line, ¤t_line); | |
289 | |||
290 |
2/2✓ Branch 1 taken 20 times.
✓ Branch 2 taken 47 times.
|
67 | if (gate_string_is_empty(¤t_line)) |
291 | { | ||
292 | 20 | continue; | |
293 | } | ||
294 | |||
295 | 47 | chr = gate_string_char_at(¤t_line, 0); | |
296 |
2/3✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 36 times.
|
47 | switch (chr) |
297 | { | ||
298 | 11 | case '[': | |
299 | { | ||
300 | /* new section */ | ||
301 | 11 | chr_last = gate_string_char_at(¤t_line, gate_string_length(¤t_line) - 1); | |
302 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
|
11 | if (chr_last != ']') |
303 | { | ||
304 | ✗ | ret = GATE_RESULT_INVALIDINPUT; | |
305 | ✗ | break; | |
306 | } | ||
307 | 11 | gate_string_release(¤t_section); | |
308 |
1/2✗ Branch 3 not taken.
✓ Branch 4 taken 11 times.
|
11 | if (NULL == gate_string_create(¤t_section, gate_string_ptr(¤t_line, 1), gate_string_length(¤t_line) - 2)) |
309 | { | ||
310 | ✗ | ret = GATE_RESULT_OUTOFMEMORY; | |
311 | ✗ | break; | |
312 | } | ||
313 | 11 | ret = gate_inifile_store_add_section(inistore, ¤t_section); | |
314 | 11 | break; | |
315 | } | ||
316 | ✗ | case '#': | |
317 | case ';': | ||
318 | { | ||
319 | /* comment line */ | ||
320 | ✗ | gate_str_print_uint64(&comment_id[1], sizeof(comment_id) - 1, ++comment_counter); | |
321 | ✗ | gate_string_create_static(&comment_key, comment_id); | |
322 | ✗ | gate_inifile_store_set(inistore, ¤t_section, &comment_key, ¤t_line); | |
323 | ✗ | gate_string_release(&comment_key); | |
324 | ✗ | break; | |
325 | } | ||
326 | 36 | default: | |
327 | { | ||
328 | /* key-value entry */ | ||
329 | 36 | pos = gate_string_char_pos(¤t_line, '=', 0); | |
330 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 36 times.
|
36 | if (pos == GATE_STR_NPOS) |
331 | { | ||
332 | ✗ | gate_string_duplicate(¤t_key, ¤t_line); | |
333 | ✗ | gate_string_create_empty(¤t_value); | |
334 | } | ||
335 | else | ||
336 | { | ||
337 | 36 | gate_string_substr(¤t_key, ¤t_line, 0, pos); | |
338 | 36 | gate_string_rtrim(¤t_key, ¤t_key); | |
339 | 36 | gate_string_substr(¤t_value, ¤t_line, pos + 1, GATE_STR_NPOS); | |
340 | 36 | gate_string_ltrim(¤t_value, ¤t_value); | |
341 | } | ||
342 | 36 | ret = gate_inifile_store_set(inistore, ¤t_section, ¤t_key, ¤t_value); | |
343 | 36 | gate_string_release(¤t_value); | |
344 | 36 | gate_string_release(¤t_key); | |
345 | 36 | break; | |
346 | } | ||
347 | } | ||
348 | 47 | gate_string_release(¤t_line); | |
349 | } | ||
350 | |||
351 | } while (0); | ||
352 | |||
353 | 13 | gate_string_release(¤t_section); | |
354 | |||
355 | 13 | return ret; | |
356 | } | ||
357 | |||
358 | 9 | gate_result_t gate_inifile_store_save(gate_inifile_store_t const* inistore, gate_stream_t* output) | |
359 | { | ||
360 | 9 | gate_result_t ret = GATE_RESULT_FAILED; | |
361 | gate_flatmap_iterator_t section_iter; | ||
362 | gate_flatmap_iterator_t entry_iter; | ||
363 | gate_string_t const* ptr_section_name; | ||
364 | gate_flatmap_t const* ptr_section_content; | ||
365 | gate_string_t const* ptr_key; | ||
366 | gate_string_t const* ptr_value; | ||
367 | gate_size_t entry_count; | ||
368 | |||
369 | do | ||
370 | { | ||
371 | 9 | section_iter = gate_flatmap_first(&inistore->sections); | |
372 |
2/2✓ Branch 1 taken 17 times.
✓ Branch 2 taken 9 times.
|
26 | while (gate_flatmap_iterator_valid(&inistore->sections, section_iter)) |
373 | { | ||
374 | 17 | ptr_section_name = (gate_string_t const*)gate_flatmap_iterator_key(section_iter); | |
375 | 17 | ptr_section_content = (gate_flatmap_t const*)gate_flatmap_iterator_value(section_iter); | |
376 |
2/4✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 17 times.
✗ Branch 3 not taken.
|
17 | if (ptr_section_name && ptr_section_content) |
377 | { | ||
378 |
2/2✓ Branch 1 taken 8 times.
✓ Branch 2 taken 9 times.
|
17 | if (!gate_string_is_empty(ptr_section_name)) |
379 | { | ||
380 | 8 | gate_stream_print(output, | |
381 | GATE_PRINT_CHAR, '[', | ||
382 | GATE_PRINT_STRING, ptr_section_name, | ||
383 | GATE_PRINT_CHAR, ']', | ||
384 | GATE_PRINT_NEWLINE, | ||
385 | GATE_PRINT_END); | ||
386 | } | ||
387 | 17 | entry_count = gate_flatmap_count(ptr_section_content); | |
388 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 5 times.
|
17 | if (entry_count > 0) |
389 | { | ||
390 | 12 | entry_iter = gate_flatmap_first(ptr_section_content); | |
391 |
2/2✓ Branch 1 taken 20 times.
✓ Branch 2 taken 12 times.
|
32 | while (gate_flatmap_iterator_valid(ptr_section_content, entry_iter)) |
392 | { | ||
393 | 20 | ptr_key = (gate_string_t const*)gate_flatmap_iterator_key(entry_iter); | |
394 | 20 | ptr_value = (gate_string_t const*)gate_flatmap_iterator_value(entry_iter); | |
395 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 20 times.
|
20 | if (gate_string_starts_with_char(ptr_key, ';')) |
396 | { | ||
397 | ✗ | gate_stream_print(output, | |
398 | GATE_PRINT_STRING, ptr_value, | ||
399 | GATE_PRINT_NEWLINE, | ||
400 | GATE_PRINT_END); | ||
401 | } | ||
402 | else | ||
403 | { | ||
404 | 20 | gate_stream_print(output, | |
405 | GATE_PRINT_STRING, ptr_key, | ||
406 | GATE_PRINT_CSTR, " = ", | ||
407 | GATE_PRINT_STRING, ptr_value, | ||
408 | GATE_PRINT_NEWLINE, | ||
409 | GATE_PRINT_END); | ||
410 | } | ||
411 | 20 | entry_iter = gate_flatmap_iterator_next(entry_iter); | |
412 | } | ||
413 | 12 | gate_stream_print(output, | |
414 | GATE_PRINT_NEWLINE, | ||
415 | GATE_PRINT_END); | ||
416 | } | ||
417 | } | ||
418 | 17 | section_iter = gate_flatmap_iterator_next(section_iter); | |
419 | } | ||
420 | 9 | ret = GATE_RESULT_OK; | |
421 | } while (0); | ||
422 | |||
423 | 9 | return ret; | |
424 | } | ||
425 | |||
426 | ✗ | static gate_result_t gate_inifile_store_import_tree(gate_inifile_store_t* inistore, gate_property_t const* property_tree, gate_string_t const* section) | |
427 | { | ||
428 | ✗ | gate_result_t ret = GATE_RESULT_FAILED; | |
429 | gate_size_t count, ndx; | ||
430 | ✗ | gate_array_t names = GATE_INIT_EMPTY; | |
431 | gate_string_t const* ptr_name; | ||
432 | gate_property_t const* ptr_prop; | ||
433 | gate_property_typeid_t prop_type; | ||
434 | gate_string_t prop_value; | ||
435 | gate_strbuilder_t builder; | ||
436 | gate_string_t sub_section; | ||
437 | |||
438 | do | ||
439 | { | ||
440 | ✗ | if (NULL == gate_property_member_names(property_tree, &names)) | |
441 | { | ||
442 | ✗ | ret = GATE_RESULT_OUTOFMEMORY; | |
443 | ✗ | break; | |
444 | } | ||
445 | ✗ | count = gate_array_length(&names); | |
446 | ✗ | ret = GATE_RESULT_OK; | |
447 | ✗ | for (ndx = 0; GATE_SUCCEEDED(ret) && (ndx != count); ++ndx) | |
448 | { | ||
449 | ✗ | ptr_name = (gate_string_t const*)gate_array_get(&names, ndx); | |
450 | ✗ | if (!ptr_name) | |
451 | { | ||
452 | ✗ | continue; | |
453 | } | ||
454 | ✗ | ptr_prop = gate_property_member_get(property_tree, ptr_name); | |
455 | ✗ | if (!ptr_prop) | |
456 | { | ||
457 | ✗ | continue; | |
458 | } | ||
459 | ✗ | prop_type = gate_property_get_type(ptr_prop); | |
460 | ✗ | switch (prop_type) | |
461 | { | ||
462 | ✗ | case GATE_PROPERTY_TYPE_BOOL: | |
463 | case GATE_PROPERTY_TYPE_INT: | ||
464 | case GATE_PROPERTY_TYPE_REAL: | ||
465 | case GATE_PROPERTY_TYPE_STRING: | ||
466 | { | ||
467 | ✗ | ret = gate_property_get_string(ptr_prop, &prop_value); | |
468 | ✗ | GATE_BREAK_IF_FAILED(ret); | |
469 | ✗ | ret = gate_inifile_store_set(inistore, section, ptr_name, &prop_value); | |
470 | ✗ | gate_string_release(&prop_value); | |
471 | ✗ | break; | |
472 | } | ||
473 | ✗ | case GATE_PROPERTY_TYPE_ARRAY: | |
474 | { | ||
475 | ✗ | break; | |
476 | } | ||
477 | ✗ | case GATE_PROPERTY_TYPE_OBJECT: | |
478 | { | ||
479 | ✗ | gate_strbuilder_create(&builder, 0); | |
480 | ✗ | gate_strbuilder_append_string(&builder, section); | |
481 | ✗ | if (gate_strbuilder_length(&builder) != 0) | |
482 | { | ||
483 | ✗ | gate_strbuilder_append_cstr(&builder, "/"); | |
484 | } | ||
485 | ✗ | gate_strbuilder_append_string(&builder, ptr_name); | |
486 | ✗ | if (NULL == gate_strbuilder_to_string(&builder, &sub_section)) | |
487 | { | ||
488 | ✗ | ret = GATE_RESULT_OUTOFMEMORY; | |
489 | } | ||
490 | ✗ | gate_strbuilder_release(&builder); | |
491 | ✗ | GATE_BREAK_IF_FAILED(ret); | |
492 | ✗ | ret = gate_inifile_store_import_tree(inistore, ptr_prop, &sub_section); | |
493 | ✗ | gate_string_release(&sub_section); | |
494 | ✗ | break; | |
495 | } | ||
496 | } | ||
497 | ✗ | } | |
498 | |||
499 | } while (0); | ||
500 | |||
501 | ✗ | gate_array_release(&names); | |
502 | |||
503 | ✗ | return ret; | |
504 | } | ||
505 | |||
506 | ✗ | gate_result_t gate_inifile_store_import(gate_inifile_store_t* inistore, gate_property_t const* property_tree) | |
507 | { | ||
508 | ✗ | gate_string_t section = GATE_STRING_INIT_EMPTY; | |
509 | ✗ | if (gate_property_get_type(property_tree) != GATE_PROPERTY_TYPE_OBJECT) | |
510 | { | ||
511 | ✗ | return GATE_RESULT_INVALIDINPUT; | |
512 | } | ||
513 | else | ||
514 | { | ||
515 | ✗ | return gate_inifile_store_import_tree(inistore, property_tree, §ion); | |
516 | } | ||
517 | } | ||
518 | |||
519 | ✗ | gate_result_t gate_inifile_store_export(gate_inifile_store_t* inistore, gate_property_t* property_tree) | |
520 | { | ||
521 | /* TODO */ | ||
522 | ✗ | return GATE_RESULT_NOTIMPLEMENTED; | |
523 | } | ||
524 | |||
525 | |||
526 | |||
527 | ✗ | gate_result_t gate_inifile_parse_string(gate_string_t const* source, gate_property_t* property_tree) | |
528 | { | ||
529 | ✗ | gate_memstream_impl_t mem_stream = GATE_INIT_EMPTY; | |
530 | ✗ | gate_memstream_create_static_unmanaged_readonly(&mem_stream, gate_string_ptr(source, 0), gate_string_length(source), 0); | |
531 | ✗ | return gate_inifile_parse((gate_stream_t*)&mem_stream, property_tree); | |
532 | } | ||
533 | ✗ | gate_result_t gate_inifile_build_string(gate_property_t const* property_tree, gate_strbuilder_t* dest_builder) | |
534 | { | ||
535 | gate_result_t ret; | ||
536 | ✗ | gate_stringstream_t* stream = gate_stringstream_create_builder(dest_builder); | |
537 | ✗ | if (NULL == stream) | |
538 | { | ||
539 | ✗ | ret = GATE_RESULT_OUTOFMEMORY; | |
540 | } | ||
541 | else | ||
542 | { | ||
543 | ✗ | ret = gate_inifile_build(property_tree, (gate_stream_t*)stream); | |
544 | ✗ | gate_object_release(stream); | |
545 | } | ||
546 | ✗ | return ret; | |
547 | } | ||
548 | |||
549 | ✗ | gate_result_t gate_inifile_parse(gate_stream_t* source, gate_property_t* property_tree) | |
550 | { | ||
551 | ✗ | gate_result_t ret = GATE_RESULT_FAILED; | |
552 | ✗ | gate_inifile_store_t store = GATE_INIT_EMPTY; | |
553 | do | ||
554 | { | ||
555 | ✗ | ret = gate_inifile_store_create(&store); | |
556 | ✗ | GATE_BREAK_IF_FAILED(ret); | |
557 | |||
558 | ✗ | ret = gate_inifile_store_load(&store, source); | |
559 | ✗ | GATE_BREAK_IF_FAILED(ret); | |
560 | |||
561 | ✗ | ret = gate_inifile_store_export(&store, property_tree); | |
562 | } while (0); | ||
563 | |||
564 | ✗ | gate_inifile_store_destroy(&store); | |
565 | |||
566 | ✗ | return ret; | |
567 | } | ||
568 | ✗ | gate_result_t gate_inifile_build(gate_property_t const* property_tree, gate_stream_t* output) | |
569 | { | ||
570 | ✗ | gate_result_t ret = GATE_RESULT_FAILED; | |
571 | ✗ | gate_inifile_store_t store = GATE_INIT_EMPTY; | |
572 | do | ||
573 | { | ||
574 | ✗ | ret = gate_inifile_store_create(&store); | |
575 | ✗ | GATE_BREAK_IF_FAILED(ret); | |
576 | |||
577 | ✗ | ret = gate_inifile_store_import(&store, property_tree); | |
578 | ✗ | GATE_BREAK_IF_FAILED(ret); | |
579 | |||
580 | ✗ | ret = gate_inifile_store_save(&store, output); | |
581 | } while (0); | ||
582 | |||
583 | ✗ | gate_inifile_store_destroy(&store); | |
584 | |||
585 | ✗ | return ret; | |
586 | } | ||
587 |