1 // Copyright Maciej Sobczak 2008-2019.
2 // This file is part of YAMI4.
3 //
4 // YAMI4 is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // YAMI4 is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with YAMI4. If not, see <http://www.gnu.org/licenses/>.
16
17 #include "parameters.h"
18 #include "fatal_errors.h"
19 #include "parameter_entry.h"
20 #include "parameter_iterator.h"
21 #include "parameters-details.h"
22 #include <cstring>
23 #include <new>
24
25 using namespace yami;
26 using namespace yami::core;
27
parameters(void * working_area,std::size_t area_size)28 parameters::parameters(void * working_area, std::size_t area_size)
29 : own_allocator_(), allocator_(own_allocator_),
30 uses_private_area_(area_size > 0),
31 data_(NULL), num_of_entries_(0)
32 {
33 own_allocator_.set_working_area(working_area, area_size);
34 }
35
parameters(details::allocator & alloc,bool private_area)36 parameters::parameters(details::allocator & alloc, bool private_area)
37 : own_allocator_(), allocator_(alloc),
38 uses_private_area_(private_area),
39 data_(NULL), num_of_entries_(0)
40 {
41 }
42
~parameters()43 parameters::~parameters()
44 {
45 if (uses_private_area_ == false)
46 {
47 // this object uses global dynamic memory
48
49 clear();
50 }
51 }
52
clear()53 void parameters::clear()
54 {
55 for (size_t i = 0; i != num_of_entries_; ++i)
56 {
57 details::entry & e = data_[i];
58
59 if (e.type != unused)
60 {
61 e.clear_name(allocator_);
62
63 // this is recursive for nested parameters:
64 e.clear_item(allocator_);
65 }
66 }
67
68 if (data_ != NULL)
69 {
70 allocator_.deallocate(data_);
71 data_ = NULL;
72
73 num_of_entries_ = 0;
74 }
75 }
76
set_boolean(const char * name,std::size_t name_length,bool value)77 result parameters::set_boolean(const char * name, std::size_t name_length,
78 bool value)
79 {
80 std::size_t index;
81 const result res = details::prepare_for_set(data_, num_of_entries_,
82 name, name_length, index, allocator_);
83
84 if (res == ok)
85 {
86 details::entry & e = data_[index];
87
88 e.type = boolean;
89 e.item.b = value;
90 }
91
92 return res;
93 }
94
set_boolean(const char * name,bool value)95 result parameters::set_boolean(const char * name, bool value)
96 {
97 return set_boolean(name, std::strlen(name), value);
98 }
99
get_boolean(const char * name,std::size_t name_length,bool & value) const100 result parameters::get_boolean(const char * name, std::size_t name_length,
101 bool & value) const
102 {
103 result res;
104 const std::size_t index = details::find_entry(data_, num_of_entries_,
105 name, name_length);
106 if (index != num_of_entries_)
107 {
108 const details::entry & e = data_[index];
109 if (e.type == boolean)
110 {
111 value = e.item.b;
112 res = ok;
113 }
114 else
115 {
116 res = bad_type;
117 }
118 }
119 else
120 {
121 res = no_such_name;
122 }
123
124 return res;
125 }
126
get_boolean(const char * name,bool & value) const127 result parameters::get_boolean(const char * name, bool & value) const
128 {
129 return get_boolean(name, std::strlen(name), value);
130 }
131
set_integer(const char * name,std::size_t name_length,int value)132 result parameters::set_integer(const char * name, std::size_t name_length,
133 int value)
134 {
135 std::size_t index;
136 const result res = details::prepare_for_set(data_, num_of_entries_,
137 name, name_length, index, allocator_);
138
139 if (res == ok)
140 {
141 details::entry & e = data_[index];
142
143 e.type = integer;
144 e.item.i = value;
145 }
146
147 return res;
148 }
149
set_integer(const char * name,int value)150 result parameters::set_integer(const char * name, int value)
151 {
152 return set_integer(name, std::strlen(name), value);
153 }
154
get_integer(const char * name,std::size_t name_length,int & value) const155 result parameters::get_integer(const char * name, std::size_t name_length,
156 int & value) const
157 {
158 result res;
159 const std::size_t index = details::find_entry(data_, num_of_entries_,
160 name, name_length);
161 if (index != num_of_entries_)
162 {
163 const details::entry & e = data_[index];
164 if (e.type == integer)
165 {
166 value = e.item.i;
167 res = ok;
168 }
169 else
170 {
171 res = bad_type;
172 }
173 }
174 else
175 {
176 res = no_such_name;
177 }
178
179 return res;
180 }
181
get_integer(const char * name,int & value) const182 result parameters::get_integer(const char * name, int & value) const
183 {
184 return get_integer(name, std::strlen(name), value);
185 }
186
set_long_long(const char * name,std::size_t name_length,long long value)187 result parameters::set_long_long(const char * name, std::size_t name_length,
188 long long value)
189 {
190 std::size_t index;
191 const result res = details::prepare_for_set(data_, num_of_entries_,
192 name, name_length, index, allocator_);
193
194 if (res == ok)
195 {
196 details::entry & e = data_[index];
197
198 e.type = long_long;
199 e.item.L = value;
200 }
201
202 return res;
203 }
204
set_long_long(const char * name,long long value)205 result parameters::set_long_long(const char * name, long long value)
206 {
207 return set_long_long(name, std::strlen(name), value);
208 }
209
get_long_long(const char * name,std::size_t name_length,long long & value) const210 result parameters::get_long_long(const char * name, std::size_t name_length,
211 long long & value) const
212 {
213 result res;
214 const std::size_t index = details::find_entry(data_, num_of_entries_,
215 name, name_length);
216 if (index != num_of_entries_)
217 {
218 const details::entry & e = data_[index];
219 if (e.type == long_long)
220 {
221 value = e.item.L;
222 res = ok;
223 }
224 else
225 {
226 res = bad_type;
227 }
228 }
229 else
230 {
231 res = no_such_name;
232 }
233
234 return res;
235 }
236
get_long_long(const char * name,long long & value) const237 result parameters::get_long_long(const char * name, long long & value) const
238 {
239 return get_long_long(name, std::strlen(name), value);
240 }
241
set_double_float(const char * name,std::size_t name_length,double value)242 result parameters::set_double_float(
243 const char * name, std::size_t name_length, double value)
244 {
245 std::size_t index;
246 const result res = details::prepare_for_set(data_, num_of_entries_,
247 name, name_length, index, allocator_);
248
249 if (res == ok)
250 {
251 details::entry & e = data_[index];
252
253 e.type = double_float;
254 e.item.d = value;
255 }
256
257 return res;
258 }
259
set_double_float(const char * name,double value)260 result parameters::set_double_float(const char * name, double value)
261 {
262 return set_double_float(name, std::strlen(name), value);
263 }
264
get_double_float(const char * name,std::size_t name_length,double & value) const265 result parameters::get_double_float(
266 const char * name, std::size_t name_length, double & value) const
267 {
268 result res;
269 const std::size_t index = details::find_entry(data_, num_of_entries_,
270 name, name_length);
271 if (index != num_of_entries_)
272 {
273 const details::entry & e = data_[index];
274 if (e.type == double_float)
275 {
276 value = e.item.d;
277 res = ok;
278 }
279 else
280 {
281 res = bad_type;
282 }
283 }
284 else
285 {
286 res = no_such_name;
287 }
288
289 return res;
290 }
291
get_double_float(const char * name,double & value) const292 result parameters::get_double_float(const char * name, double & value) const
293 {
294 return get_double_float(name, std::strlen(name), value);
295 }
296
set_string(const char * name,std::size_t name_length,const char * value,std::size_t value_length)297 result parameters::set_string(const char * name, std::size_t name_length,
298 const char * value, std::size_t value_length)
299 {
300 result res;
301
302 char * new_buffer =
303 static_cast<char *>(allocator_.allocate(value_length));
304 if (new_buffer != NULL)
305 {
306 std::memcpy(new_buffer, value, value_length);
307
308 res = details::do_set_string(name, name_length,
309 new_buffer, value_length,
310 data_, num_of_entries_, allocator_, true);
311
312 if (res != ok)
313 {
314 allocator_.deallocate(new_buffer);
315 }
316 }
317 else
318 {
319 res = no_memory;
320 }
321
322 return res;
323 }
324
set_string(const char * name,const char * value)325 result parameters::set_string(const char * name, const char * value)
326 {
327 return set_string(name, std::strlen(name), value, std::strlen(value));
328 }
329
set_string_shallow(const char * name,std::size_t name_length,const char * value,std::size_t value_length)330 result parameters::set_string_shallow(
331 const char * name, std::size_t name_length,
332 const char * value, std::size_t value_length)
333 {
334 const result res = details::do_set_string(name, name_length,
335 value, value_length,
336 data_, num_of_entries_, allocator_, false);
337
338 return res;
339 }
340
set_string_shallow(const char * name,const char * value)341 result parameters::set_string_shallow(const char * name, const char * value)
342 {
343 return set_string_shallow(name, std::strlen(name),
344 value, std::strlen(value));
345 }
346
get_string(const char * name,std::size_t name_length,const char * & value,std::size_t & value_length) const347 result parameters::get_string(const char * name, std::size_t name_length,
348 const char * & value, std::size_t & value_length) const
349 {
350 result res;
351 const std::size_t index = details::find_entry(data_, num_of_entries_,
352 name, name_length);
353 if (index != num_of_entries_)
354 {
355 const details::entry & e = data_[index];
356 if (e.type == string)
357 {
358 value = e.item.str.value;
359 value_length = e.item.str.length;
360 res = ok;
361 }
362 else
363 {
364 res = bad_type;
365 }
366 }
367 else
368 {
369 res = no_such_name;
370 }
371
372 return res;
373 }
374
get_string(const char * name,const char * & value,std::size_t & value_length) const375 result parameters::get_string(const char * name,
376 const char * & value, std::size_t & value_length) const
377 {
378 return get_string(name, std::strlen(name), value, value_length);
379 }
380
set_binary(const char * name,std::size_t name_length,const void * value,std::size_t value_length)381 result parameters::set_binary(const char * name, std::size_t name_length,
382 const void * value, std::size_t value_length)
383 {
384 result res;
385
386 void * new_buffer = allocator_.allocate(value_length);
387 if (new_buffer != NULL)
388 {
389 std::memcpy(new_buffer, value, value_length);
390
391 res = details::do_set_binary(name, name_length,
392 new_buffer, value_length,
393 data_, num_of_entries_, allocator_, true);
394
395 if (res != ok)
396 {
397 allocator_.deallocate(new_buffer);
398 }
399 }
400 else
401 {
402 res = no_memory;
403 }
404
405 return res;
406 }
407
set_binary(const char * name,const void * value,std::size_t value_length)408 result parameters::set_binary(const char * name,
409 const void * value, std::size_t value_length)
410 {
411 return set_binary(name, std::strlen(name), value, value_length);
412 }
413
set_binary_shallow(const char * name,std::size_t name_length,const void * value,std::size_t value_length)414 result parameters::set_binary_shallow(
415 const char * name, std::size_t name_length,
416 const void * value, std::size_t value_length)
417 {
418 const result res = details::do_set_binary(name, name_length,
419 value, value_length,
420 data_, num_of_entries_, allocator_, false);
421
422 return res;
423 }
424
set_binary_shallow(const char * name,const void * value,std::size_t value_length)425 result parameters::set_binary_shallow(const char * name,
426 const void * value, std::size_t value_length)
427 {
428 return set_binary_shallow(name, std::strlen(name),
429 value, value_length);
430 }
431
get_binary(const char * name,std::size_t name_length,const void * & value,std::size_t & value_length) const432 result parameters::get_binary(const char * name, std::size_t name_length,
433 const void * & value, std::size_t & value_length) const
434 {
435 result res;
436 const std::size_t index = details::find_entry(data_, num_of_entries_,
437 name, name_length);
438 if (index != num_of_entries_)
439 {
440 const details::entry & e = data_[index];
441 if (e.type == binary)
442 {
443 value = e.item.bin.value;
444 value_length = e.item.bin.length;
445 res = ok;
446 }
447 else
448 {
449 res = bad_type;
450 }
451 }
452 else
453 {
454 res = no_such_name;
455 }
456
457 return res;
458 }
459
get_binary(const char * name,const void * & value,std::size_t & value_length) const460 result parameters::get_binary(const char * name,
461 const void * & value, std::size_t & value_length) const
462 {
463 return get_binary(name, std::strlen(name), value, value_length);
464 }
465
set_boolean_array(const char * name,std::size_t name_length,const bool * values,std::size_t array_length)466 result parameters::set_boolean_array(
467 const char * name, std::size_t name_length,
468 const bool * values, std::size_t array_length)
469 {
470 result res;
471
472 const std::size_t raw_length = array_length * sizeof(bool);
473 bool * new_array =
474 static_cast<bool *>(allocator_.allocate(raw_length));
475 if (new_array != NULL)
476 {
477 std::memcpy(new_array, values, raw_length);
478
479 res = details::do_set_boolean_array(name, name_length,
480 new_array, array_length,
481 data_, num_of_entries_, allocator_, true);
482
483 if (res != ok)
484 {
485 allocator_.deallocate(new_array);
486 }
487 }
488 else
489 {
490 res = no_memory;
491 }
492
493 return res;
494 }
495
set_boolean_array(const char * name,const bool * values,std::size_t array_length)496 result parameters::set_boolean_array(const char * name,
497 const bool * values, std::size_t array_length)
498 {
499 return set_boolean_array(name, std::strlen(name), values, array_length);
500 }
501
set_boolean_array_shallow(const char * name,std::size_t name_length,const bool * values,std::size_t array_length)502 result parameters::set_boolean_array_shallow(
503 const char * name, std::size_t name_length,
504 const bool * values, std::size_t array_length)
505 {
506 const result res = details::do_set_boolean_array(name, name_length,
507 values, array_length,
508 data_, num_of_entries_, allocator_, false);
509
510 return res;
511 }
512
set_boolean_array_shallow(const char * name,const bool * values,std::size_t array_length)513 result parameters::set_boolean_array_shallow(const char * name,
514 const bool * values, std::size_t array_length)
515 {
516 return set_boolean_array_shallow(name, std::strlen(name),
517 values, array_length);
518 }
519
create_boolean_array(const char * name,std::size_t name_length,std::size_t array_length,bool * & array)520 result parameters::create_boolean_array(
521 const char * name, std::size_t name_length,
522 std::size_t array_length, bool * & array)
523 {
524 result res;
525
526 const std::size_t raw_length = array_length * sizeof(bool);
527 bool * new_array =
528 static_cast<bool *>(allocator_.allocate(raw_length));
529 if (new_array != NULL)
530 {
531 res = details::do_set_boolean_array(name, name_length,
532 new_array, array_length,
533 data_, num_of_entries_, allocator_, true);
534
535 if (res == ok)
536 {
537 array = new_array;
538 }
539 else
540 {
541 allocator_.deallocate(new_array);
542 }
543 }
544 else
545 {
546 res = no_memory;
547 }
548
549 return res;
550 }
551
create_boolean_array(const char * name,std::size_t array_length,bool * & array)552 result parameters::create_boolean_array(const char * name,
553 std::size_t array_length, bool * & array)
554 {
555 return create_boolean_array(name, std::strlen(name), array_length, array);
556 }
557
get_boolean_array(const char * name,std::size_t name_length,bool * & values,std::size_t & array_length) const558 result parameters::get_boolean_array(
559 const char * name, std::size_t name_length,
560 bool * & values, std::size_t & array_length) const
561 {
562 result res;
563 const std::size_t index = details::find_entry(data_, num_of_entries_,
564 name, name_length);
565 if (index != num_of_entries_)
566 {
567 const details::entry & e = data_[index];
568 if (e.type == boolean_array)
569 {
570 values = e.item.ba.values;
571 array_length = e.item.ba.length;
572 res = ok;
573 }
574 else
575 {
576 res = bad_type;
577 }
578 }
579 else
580 {
581 res = no_such_name;
582 }
583
584 return res;
585 }
586
get_boolean_array(const char * name,bool * & values,std::size_t & array_length) const587 result parameters::get_boolean_array(const char * name,
588 bool * & values, std::size_t & array_length) const
589 {
590 return get_boolean_array(name, std::strlen(name), values, array_length);
591 }
592
set_integer_array(const char * name,std::size_t name_length,const int * values,std::size_t array_length)593 result parameters::set_integer_array(
594 const char * name, std::size_t name_length,
595 const int * values, std::size_t array_length)
596 {
597 result res;
598
599 const std::size_t raw_length = array_length * sizeof(int);
600 int * new_array =
601 static_cast<int *>(allocator_.allocate(raw_length));
602 if (new_array != NULL)
603 {
604 std::memcpy(new_array, values, raw_length);
605
606 res = details::do_set_integer_array(name, name_length,
607 new_array, array_length,
608 data_, num_of_entries_, allocator_, true);
609
610 if (res != ok)
611 {
612 allocator_.deallocate(new_array);
613 }
614 }
615 else
616 {
617 res = no_memory;
618 }
619
620 return res;
621 }
622
set_integer_array(const char * name,const int * values,std::size_t array_length)623 result parameters::set_integer_array(const char * name,
624 const int * values, std::size_t array_length)
625 {
626 return set_integer_array(name, std::strlen(name), values, array_length);
627 }
628
set_integer_array_shallow(const char * name,std::size_t name_length,const int * values,std::size_t array_length)629 result parameters::set_integer_array_shallow(
630 const char * name, std::size_t name_length,
631 const int * values, std::size_t array_length)
632 {
633 const result res = details::do_set_integer_array(name, name_length,
634 values, array_length,
635 data_, num_of_entries_, allocator_, false);
636
637 return res;
638 }
639
set_integer_array_shallow(const char * name,const int * values,std::size_t array_length)640 result parameters::set_integer_array_shallow(const char * name,
641 const int * values, std::size_t array_length)
642 {
643 return set_integer_array_shallow(name, std::strlen(name),
644 values, array_length);
645 }
646
create_integer_array(const char * name,std::size_t name_length,std::size_t array_length,int * & array)647 result parameters::create_integer_array(
648 const char * name, std::size_t name_length,
649 std::size_t array_length, int * & array)
650 {
651 result res;
652
653 const std::size_t raw_length = array_length * sizeof(int);
654 int * new_array =
655 static_cast<int *>(allocator_.allocate(raw_length));
656 if (new_array != NULL)
657 {
658 res = details::do_set_integer_array(name, name_length,
659 new_array, array_length,
660 data_, num_of_entries_, allocator_, true);
661
662 if (res == ok)
663 {
664 array = new_array;
665 }
666 else
667 {
668 allocator_.deallocate(new_array);
669 }
670 }
671 else
672 {
673 res = no_memory;
674 }
675
676 return res;
677 }
678
create_integer_array(const char * name,std::size_t array_length,int * & array)679 result parameters::create_integer_array(const char * name,
680 std::size_t array_length, int * & array)
681 {
682 return create_integer_array(name, std::strlen(name), array_length, array);
683 }
684
get_integer_array(const char * name,std::size_t name_length,int * & values,std::size_t & array_length) const685 result parameters::get_integer_array(
686 const char * name, std::size_t name_length,
687 int * & values, std::size_t & array_length) const
688 {
689 result res;
690 const std::size_t index = details::find_entry(data_, num_of_entries_,
691 name, name_length);
692 if (index != num_of_entries_)
693 {
694 const details::entry & e = data_[index];
695 if (e.type == integer_array)
696 {
697 values = e.item.ia.values;
698 array_length = e.item.ia.length;
699 res = ok;
700 }
701 else
702 {
703 res = bad_type;
704 }
705 }
706 else
707 {
708 res = no_such_name;
709 }
710
711 return res;
712 }
713
get_integer_array(const char * name,int * & values,std::size_t & array_length) const714 result parameters::get_integer_array(const char * name,
715 int * & values, std::size_t & array_length) const
716 {
717 return get_integer_array(name, std::strlen(name), values, array_length);
718 }
719
set_long_long_array(const char * name,std::size_t name_length,const long long * values,std::size_t array_length)720 result parameters::set_long_long_array(
721 const char * name, std::size_t name_length,
722 const long long * values, std::size_t array_length)
723 {
724 result res;
725
726 const std::size_t raw_length = array_length * sizeof(long long);
727 long long * new_array =
728 static_cast<long long *>(allocator_.allocate(raw_length));
729 if (new_array != NULL)
730 {
731 std::memcpy(new_array, values, raw_length);
732
733 res = details::do_set_long_long_array(name, name_length,
734 new_array, array_length,
735 data_, num_of_entries_, allocator_, true);
736
737 if (res != ok)
738 {
739 allocator_.deallocate(new_array);
740 }
741 }
742 else
743 {
744 res = no_memory;
745 }
746
747 return res;
748 }
749
set_long_long_array(const char * name,const long long * values,std::size_t array_length)750 result parameters::set_long_long_array(const char * name,
751 const long long * values, std::size_t array_length)
752 {
753 return set_long_long_array(name, std::strlen(name), values, array_length);
754 }
755
set_long_long_array_shallow(const char * name,std::size_t name_length,const long long * values,std::size_t array_length)756 result parameters::set_long_long_array_shallow(
757 const char * name, std::size_t name_length,
758 const long long * values, std::size_t array_length)
759 {
760 const result res = details::do_set_long_long_array(name, name_length,
761 values, array_length,
762 data_, num_of_entries_, allocator_, false);
763
764 return res;
765 }
766
set_long_long_array_shallow(const char * name,const long long * values,std::size_t array_length)767 result parameters::set_long_long_array_shallow(const char * name,
768 const long long * values, std::size_t array_length)
769 {
770 return set_long_long_array_shallow(name, std::strlen(name),
771 values, array_length);
772 }
773
create_long_long_array(const char * name,std::size_t name_length,std::size_t array_length,long long * & array)774 result parameters::create_long_long_array(
775 const char * name, std::size_t name_length,
776 std::size_t array_length, long long * & array)
777 {
778 result res;
779
780 const std::size_t raw_length = array_length * sizeof(long long);
781 long long * new_array =
782 static_cast<long long *>(allocator_.allocate(raw_length));
783 if (new_array != NULL)
784 {
785 res = details::do_set_long_long_array(name, name_length,
786 new_array, array_length,
787 data_, num_of_entries_, allocator_, true);
788
789 if (res == ok)
790 {
791 array = new_array;
792 }
793 else
794 {
795 allocator_.deallocate(new_array);
796 }
797 }
798 else
799 {
800 res = no_memory;
801 }
802
803 return res;
804 }
805
create_long_long_array(const char * name,std::size_t array_length,long long * & array)806 result parameters::create_long_long_array(const char * name,
807 std::size_t array_length, long long * & array)
808 {
809 return create_long_long_array(name, std::strlen(name),
810 array_length, array);
811 }
812
get_long_long_array(const char * name,std::size_t name_length,long long * & values,std::size_t & array_length) const813 result parameters::get_long_long_array(
814 const char * name, std::size_t name_length,
815 long long * & values, std::size_t & array_length) const
816 {
817 result res;
818 const std::size_t index = details::find_entry(data_, num_of_entries_,
819 name, name_length);
820 if (index != num_of_entries_)
821 {
822 const details::entry & e = data_[index];
823 if (e.type == long_long_array)
824 {
825 values = e.item.La.values;
826 array_length = e.item.La.length;
827 res = ok;
828 }
829 else
830 {
831 res = bad_type;
832 }
833 }
834 else
835 {
836 res = no_such_name;
837 }
838
839 return res;
840 }
841
get_long_long_array(const char * name,long long * & values,std::size_t & array_length) const842 result parameters::get_long_long_array(const char * name,
843 long long * & values, std::size_t & array_length) const
844 {
845 return get_long_long_array(name, std::strlen(name), values, array_length);
846 }
847
set_double_float_array(const char * name,std::size_t name_length,const double * values,std::size_t array_length)848 result parameters::set_double_float_array(
849 const char * name, std::size_t name_length,
850 const double * values, std::size_t array_length)
851 {
852 result res;
853
854 const std::size_t raw_length = array_length * sizeof(double);
855 double * new_array =
856 static_cast<double *>(allocator_.allocate(raw_length));
857 if (new_array != NULL)
858 {
859 std::memcpy(new_array, values, raw_length);
860
861 res = details::do_set_double_float_array(name, name_length,
862 new_array, array_length,
863 data_, num_of_entries_, allocator_, true);
864
865 if (res != ok)
866 {
867 allocator_.deallocate(new_array);
868 }
869 }
870 else
871 {
872 res = no_memory;
873 }
874
875 return res;
876 }
877
set_double_float_array(const char * name,const double * values,std::size_t array_length)878 result parameters::set_double_float_array(const char * name,
879 const double * values, std::size_t array_length)
880 {
881 return set_double_float_array(
882 name, std::strlen(name), values, array_length);
883 }
884
set_double_float_array_shallow(const char * name,std::size_t name_length,const double * values,std::size_t array_length)885 result parameters::set_double_float_array_shallow(
886 const char * name, std::size_t name_length,
887 const double * values, std::size_t array_length)
888 {
889 const result res = details::do_set_double_float_array(name, name_length,
890 values, array_length,
891 data_, num_of_entries_, allocator_, false);
892
893 return res;
894 }
895
set_double_float_array_shallow(const char * name,const double * values,std::size_t array_length)896 result parameters::set_double_float_array_shallow(const char * name,
897 const double * values, std::size_t array_length)
898 {
899 return set_double_float_array_shallow(name, std::strlen(name),
900 values, array_length);
901 }
902
create_double_float_array(const char * name,std::size_t name_length,std::size_t array_length,double * & array)903 result parameters::create_double_float_array(
904 const char * name, std::size_t name_length,
905 std::size_t array_length, double * & array)
906 {
907 result res;
908
909 const std::size_t raw_length = array_length * sizeof(double);
910 double * new_array =
911 static_cast<double *>(allocator_.allocate(raw_length));
912 if (new_array != NULL)
913 {
914 res = details::do_set_double_float_array(name, name_length,
915 new_array, array_length,
916 data_, num_of_entries_, allocator_, true);
917
918 if (res == ok)
919 {
920 array = new_array;
921 }
922 else
923 {
924 allocator_.deallocate(new_array);
925 }
926 }
927 else
928 {
929 res = no_memory;
930 }
931
932 return res;
933 }
934
create_double_float_array(const char * name,std::size_t array_length,double * & array)935 result parameters::create_double_float_array(const char * name,
936 std::size_t array_length, double * & array)
937 {
938 return create_double_float_array(name, std::strlen(name),
939 array_length, array);
940 }
941
get_double_float_array(const char * name,std::size_t name_length,double * & values,std::size_t & array_length) const942 result parameters::get_double_float_array(
943 const char * name, std::size_t name_length,
944 double * & values, std::size_t & array_length) const
945 {
946 result res;
947 const std::size_t index = details::find_entry(data_, num_of_entries_,
948 name, name_length);
949 if (index != num_of_entries_)
950 {
951 const details::entry & e = data_[index];
952 if (e.type == double_float_array)
953 {
954 values = e.item.da.values;
955 array_length = e.item.da.length;
956 res = ok;
957 }
958 else
959 {
960 res = bad_type;
961 }
962 }
963 else
964 {
965 res = no_such_name;
966 }
967
968 return res;
969 }
970
get_double_float_array(const char * name,double * & values,std::size_t & array_length) const971 result parameters::get_double_float_array(const char * name,
972 double * & values, std::size_t & array_length) const
973 {
974 return get_double_float_array(
975 name, std::strlen(name), values, array_length);
976 }
977
create_string_array(const char * name,std::size_t name_length,std::size_t array_length)978 result parameters::create_string_array(
979 const char * name, std::size_t name_length,
980 std::size_t array_length)
981 {
982 std::size_t dummy_index;
983 const result res = details::do_create_string_array(
984 name, name_length, array_length, dummy_index,
985 data_, num_of_entries_, allocator_);
986
987 return res;
988 }
989
create_string_array(const char * name,std::size_t array_length)990 result parameters::create_string_array(
991 const char * name, std::size_t array_length)
992 {
993 return create_string_array(name, std::strlen(name), array_length);
994 }
995
set_string_in_array(const char * name,std::size_t name_length,std::size_t index,const char * value,std::size_t value_length)996 result parameters::set_string_in_array(
997 const char * name, std::size_t name_length,
998 std::size_t index, const char * value, std::size_t value_length)
999 {
1000 result res;
1001 const std::size_t item_index = details::find_entry(
1002 data_, num_of_entries_, name, name_length);
1003 if (item_index != num_of_entries_)
1004 {
1005 res = details::do_set_string_in_array(item_index, index,
1006 value, value_length, data_, allocator_);
1007 }
1008 else
1009 {
1010 res = no_such_name;
1011 }
1012
1013 return res;
1014 }
1015
set_string_in_array(const char * name,std::size_t index,const char * value)1016 result parameters::set_string_in_array(const char * name,
1017 std::size_t index, const char * value)
1018 {
1019 return set_string_in_array(name, std::strlen(name),
1020 index, value, std::strlen(value));
1021 }
1022
get_string_array_length(const char * name,std::size_t name_length,std::size_t & array_length) const1023 result parameters::get_string_array_length(
1024 const char * name, std::size_t name_length,
1025 std::size_t & array_length) const
1026 {
1027 result res;
1028 const std::size_t index = details::find_entry(data_, num_of_entries_,
1029 name, name_length);
1030 if (index != num_of_entries_)
1031 {
1032 const details::entry & e = data_[index];
1033 if (e.type == string_array)
1034 {
1035 array_length = e.item.sa.length;
1036 res = ok;
1037 }
1038 else
1039 {
1040 res = bad_type;
1041 }
1042 }
1043 else
1044 {
1045 res = no_such_name;
1046 }
1047
1048 return res;
1049 }
1050
get_string_array_length(const char * name,std::size_t & array_length) const1051 result parameters::get_string_array_length(const char * name,
1052 std::size_t & array_length) const
1053 {
1054 return get_string_array_length(name, std::strlen(name), array_length);
1055 }
1056
get_string_in_array(const char * name,std::size_t name_length,std::size_t index,const char * & value,std::size_t & value_length) const1057 result parameters::get_string_in_array(
1058 const char * name, std::size_t name_length,
1059 std::size_t index,
1060 const char * & value, std::size_t & value_length) const
1061 {
1062 result res;
1063 const std::size_t item_index = details::find_entry(
1064 data_, num_of_entries_, name, name_length);
1065 if (item_index != num_of_entries_)
1066 {
1067 const details::entry & e = data_[item_index];
1068 if (e.type == string_array)
1069 {
1070 if (index < e.item.sa.length)
1071 {
1072 value = e.item.sa.values[index].value;
1073 value_length = e.item.sa.values[index].length;
1074 res = ok;
1075 }
1076 else
1077 {
1078 res = no_such_index;
1079 }
1080 }
1081 else
1082 {
1083 res = bad_type;
1084 }
1085 }
1086 else
1087 {
1088 res = no_such_name;
1089 }
1090
1091 return res;
1092 }
1093
get_string_in_array(const char * name,std::size_t index,const char * & value,std::size_t & value_length) const1094 result parameters::get_string_in_array(const char * name, std::size_t index,
1095 const char * & value, std::size_t & value_length) const
1096 {
1097 return get_string_in_array(name, std::strlen(name),
1098 index, value, value_length);
1099 }
1100
create_binary_array(const char * name,std::size_t name_length,std::size_t array_length)1101 result parameters::create_binary_array(
1102 const char * name, std::size_t name_length,
1103 std::size_t array_length)
1104 {
1105 std::size_t dummy_index;
1106 const result res = details::do_create_binary_array(
1107 name, name_length, array_length, dummy_index,
1108 data_, num_of_entries_, allocator_);
1109
1110 return res;
1111 }
1112
create_binary_array(const char * name,std::size_t array_length)1113 result parameters::create_binary_array(
1114 const char * name, std::size_t array_length)
1115 {
1116 return create_binary_array(name, std::strlen(name), array_length);
1117 }
1118
set_binary_in_array(const char * name,std::size_t name_length,std::size_t index,const void * value,std::size_t value_length)1119 result parameters::set_binary_in_array(
1120 const char * name, std::size_t name_length,
1121 std::size_t index, const void * value, std::size_t value_length)
1122 {
1123 result res;
1124 const std::size_t item_index = details::find_entry(
1125 data_, num_of_entries_, name, name_length);
1126 if (item_index != num_of_entries_)
1127 {
1128 res = details::do_set_binary_in_array(item_index, index,
1129 value, value_length, data_, allocator_);
1130 }
1131 else
1132 {
1133 res = no_such_name;
1134 }
1135
1136 return res;
1137 }
1138
set_binary_in_array(const char * name,std::size_t index,const void * value,std::size_t value_length)1139 result parameters::set_binary_in_array(const char * name,
1140 std::size_t index, const void * value, std::size_t value_length)
1141 {
1142 return set_binary_in_array(name, std::strlen(name),
1143 index, value, value_length);
1144 }
1145
get_binary_array_length(const char * name,std::size_t name_length,std::size_t & array_length) const1146 result parameters::get_binary_array_length(
1147 const char * name, std::size_t name_length,
1148 std::size_t & array_length) const
1149 {
1150 result res;
1151 const std::size_t index = details::find_entry(data_, num_of_entries_,
1152 name, name_length);
1153 if (index != num_of_entries_)
1154 {
1155 const details::entry & e = data_[index];
1156 if (e.type == binary_array)
1157 {
1158 array_length = e.item.bina.length;
1159 res = ok;
1160 }
1161 else
1162 {
1163 res = bad_type;
1164 }
1165 }
1166 else
1167 {
1168 res = no_such_name;
1169 }
1170
1171 return res;
1172 }
1173
get_binary_array_length(const char * name,std::size_t & array_length) const1174 result parameters::get_binary_array_length(const char * name,
1175 std::size_t & array_length) const
1176 {
1177 return get_binary_array_length(name, std::strlen(name), array_length);
1178 }
1179
get_binary_in_array(const char * name,std::size_t name_length,std::size_t index,const void * & value,std::size_t & value_length) const1180 result parameters::get_binary_in_array(
1181 const char * name, std::size_t name_length,
1182 std::size_t index,
1183 const void * & value, std::size_t & value_length) const
1184 {
1185 result res;
1186 const std::size_t item_index = details::find_entry(
1187 data_, num_of_entries_, name, name_length);
1188 if (item_index != num_of_entries_)
1189 {
1190 const details::entry & e = data_[item_index];
1191 if (e.type == binary_array)
1192 {
1193 if (index < e.item.bina.length)
1194 {
1195 value = e.item.bina.values[index].value;
1196 value_length = e.item.bina.values[index].length;
1197 res = ok;
1198 }
1199 else
1200 {
1201 res = no_such_index;
1202 }
1203 }
1204 else
1205 {
1206 res = bad_type;
1207 }
1208 }
1209 else
1210 {
1211 res = no_such_name;
1212 }
1213
1214 return res;
1215 }
1216
get_binary_in_array(const char * name,std::size_t index,const void * & value,std::size_t & value_length) const1217 result parameters::get_binary_in_array(const char * name, std::size_t index,
1218 const void * & value, std::size_t & value_length) const
1219 {
1220 return get_binary_in_array(name, std::strlen(name),
1221 index, value, value_length);
1222 }
1223
create_nested_parameters(const char * name,std::size_t name_length,parameters * & params)1224 result parameters::create_nested_parameters(
1225 const char * name, std::size_t name_length, parameters * & params)
1226 {
1227 result res;
1228
1229 void * new_buffer = allocator_.allocate(sizeof(parameters));
1230 if (new_buffer != NULL)
1231 {
1232 std::size_t index;
1233 res = details::prepare_for_set(data_, num_of_entries_,
1234 name, name_length, index, allocator_);
1235
1236 if (res == ok)
1237 {
1238 parameters * nested =
1239 new (new_buffer) parameters(allocator_, uses_private_area_);
1240
1241 details::entry & e = data_[index];
1242
1243 e.type = nested_parameters;
1244 e.item.nested = nested;
1245
1246 params = nested;
1247 }
1248 else
1249 {
1250 allocator_.deallocate(new_buffer);
1251 }
1252 }
1253 else
1254 {
1255 res = no_memory;
1256 }
1257
1258 return res;
1259 }
1260
create_nested_parameters(const char * name,parameters * & params)1261 result parameters::create_nested_parameters(
1262 const char * name, parameters * & params)
1263 {
1264 return create_nested_parameters(name, std::strlen(name), params);
1265 }
1266
get_nested_parameters(const char * name,std::size_t name_length,parameters * & params) const1267 result parameters::get_nested_parameters(
1268 const char * name, std::size_t name_length, parameters * & params) const
1269 {
1270 result res;
1271 const std::size_t index = details::find_entry(
1272 data_, num_of_entries_, name, name_length);
1273 if (index != num_of_entries_)
1274 {
1275 const details::entry & e = data_[index];
1276 if (e.type == nested_parameters)
1277 {
1278 params = e.item.nested;
1279 res = ok;
1280 }
1281 else
1282 {
1283 res = bad_type;
1284 }
1285 }
1286 else
1287 {
1288 res = no_such_name;
1289 }
1290
1291 return res;
1292 }
1293
get_nested_parameters(const char * name,parameters * & params) const1294 result parameters::get_nested_parameters(
1295 const char * name, parameters * & params) const
1296 {
1297 return get_nested_parameters(name, std::strlen(name), params);
1298 }
1299
create_nested_array(const char * name,std::size_t name_length,std::size_t array_length)1300 result parameters::create_nested_array(
1301 const char * name, std::size_t name_length,
1302 std::size_t array_length)
1303 {
1304 std::size_t dummy_index;
1305 const result res = details::do_create_nested_array(
1306 name, name_length, array_length, dummy_index,
1307 data_, num_of_entries_, allocator_);
1308
1309 return res;
1310 }
1311
create_nested_array(const char * name,std::size_t array_length)1312 result parameters::create_nested_array(
1313 const char * name, std::size_t array_length)
1314 {
1315 return create_nested_array(name, std::strlen(name), array_length);
1316 }
1317
get_nested_array_length(const char * name,std::size_t name_length,std::size_t & array_length) const1318 result parameters::get_nested_array_length(
1319 const char * name, std::size_t name_length,
1320 std::size_t & array_length) const
1321 {
1322 result res;
1323 const std::size_t index = details::find_entry(data_, num_of_entries_,
1324 name, name_length);
1325 if (index != num_of_entries_)
1326 {
1327 const details::entry & e = data_[index];
1328 if (e.type == nested_parameters_array)
1329 {
1330 array_length = e.item.nesteda.length;
1331 res = ok;
1332 }
1333 else
1334 {
1335 res = bad_type;
1336 }
1337 }
1338 else
1339 {
1340 res = no_such_name;
1341 }
1342
1343 return res;
1344 }
1345
get_nested_array_length(const char * name,std::size_t & array_length) const1346 result parameters::get_nested_array_length(const char * name,
1347 std::size_t & array_length) const
1348 {
1349 return get_nested_array_length(name, std::strlen(name), array_length);
1350 }
1351
get_nested_in_array(const char * name,std::size_t name_length,std::size_t index,parameters * & nested) const1352 result parameters::get_nested_in_array(
1353 const char * name, std::size_t name_length,
1354 std::size_t index,
1355 parameters * & nested) const
1356 {
1357 result res;
1358 const std::size_t item_index = details::find_entry(
1359 data_, num_of_entries_, name, name_length);
1360 if (item_index != num_of_entries_)
1361 {
1362 const details::entry & e = data_[item_index];
1363 if (e.type == nested_parameters_array)
1364 {
1365 if (index < e.item.nesteda.length)
1366 {
1367 nested = &e.item.nesteda.values[index];
1368 res = ok;
1369 }
1370 else
1371 {
1372 res = no_such_index;
1373 }
1374 }
1375 else
1376 {
1377 res = bad_type;
1378 }
1379 }
1380 else
1381 {
1382 res = no_such_name;
1383 }
1384
1385 return res;
1386 }
1387
get_nested_in_array(const char * name,std::size_t index,parameters * & nested) const1388 result parameters::get_nested_in_array(
1389 const char * name, std::size_t index,
1390 parameters * & nested) const
1391 {
1392 return get_nested_in_array(name, std::strlen(name), index, nested);
1393 }
1394
remove(const char * name,std::size_t name_length)1395 result parameters::remove(const char * name, std::size_t name_length)
1396 {
1397 result res;
1398 const std::size_t index = details::find_entry(
1399 data_, num_of_entries_, name, name_length);
1400 if (index != num_of_entries_)
1401 {
1402 details::entry & e = data_[index];
1403
1404 e.clear_name(allocator_);
1405 e.clear_item(allocator_);
1406 e.type = unused;
1407 res = ok;
1408 }
1409 else
1410 {
1411 res = no_such_name;
1412 }
1413
1414 return res;
1415 }
1416
remove(const char * name)1417 result parameters::remove(const char * name)
1418 {
1419 return remove(name, std::strlen(name));
1420 }
1421
size() const1422 std::size_t parameters::size() const
1423 {
1424 std::size_t count = 0;
1425 for (std::size_t i = 0; i != num_of_entries_; ++i)
1426 {
1427 if (data_[i].type != unused)
1428 {
1429 ++count;
1430 }
1431 }
1432
1433 return count;
1434 }
1435
get_type(const char * name,std::size_t name_length,parameter_type & t) const1436 result parameters::get_type(const char * name, std::size_t name_length,
1437 parameter_type & t) const
1438 {
1439 result res;
1440 const std::size_t index = details::find_entry(
1441 data_, num_of_entries_, name, name_length);
1442 if (index != num_of_entries_)
1443 {
1444 t = data_[index].type;
1445 res = ok;
1446 }
1447 else
1448 {
1449 res = no_such_name;
1450 }
1451
1452 return res;
1453 }
1454
get_type(const char * name,parameter_type & t) const1455 result parameters::get_type(const char * name, parameter_type & t) const
1456 {
1457 return get_type(name, std::strlen(name), t);
1458 }
1459
get_iterator(parameter_iterator & it) const1460 result parameters::get_iterator(parameter_iterator & it) const
1461 {
1462 result res;
1463
1464 std::size_t first_used_index = num_of_entries_;
1465 for (std::size_t i = 0; i != num_of_entries_; ++i)
1466 {
1467 if (data_[i].type != unused)
1468 {
1469 first_used_index = i;
1470 break;
1471 }
1472 }
1473
1474 if (first_used_index != num_of_entries_)
1475 {
1476 it.data_ = data_;
1477 it.current_index_ = first_used_index;
1478 it.num_of_entries_ = num_of_entries_;
1479 it.allocator_ = &allocator_;
1480 res = ok;
1481 }
1482 else
1483 {
1484 res = no_entries;
1485 }
1486
1487 return res;
1488 }
1489
find(const char * name,std::size_t name_length,parameter_entry & entry) const1490 result parameters::find(const char * name, std::size_t name_length,
1491 parameter_entry & entry) const
1492 {
1493 result res;
1494 const std::size_t index = details::find_entry(
1495 data_, num_of_entries_, name, name_length);
1496 if (index != num_of_entries_)
1497 {
1498 entry.e_ = data_ + index;
1499 res = ok;
1500 }
1501 else
1502 {
1503 res = no_such_name;
1504 }
1505
1506 return res;
1507 }
1508
find(const char * name,parameter_entry & entry) const1509 result parameters::find(const char * name, parameter_entry & entry) const
1510 {
1511 return find(name, std::strlen(name), entry);
1512 }
1513
merge_from(const parameters & other)1514 result parameters::merge_from(const parameters & other)
1515 {
1516 // merge is performed as serialize of other
1517 // followed by deserialize into this
1518
1519 result res = ok;
1520
1521 if (other.size() != 0)
1522 {
1523 std::size_t buffer_size;
1524 res = other.get_serialize_buffer_size(buffer_size);
1525 if (res == ok)
1526 {
1527 char * buffer = static_cast<char *>(
1528 allocator_.allocate(buffer_size));
1529 if (buffer != NULL)
1530 {
1531 res = other.serialize(&buffer, &buffer_size, 1);
1532 if (res == ok)
1533 {
1534 const char * buffers[1];
1535 buffers[0] = buffer;
1536 std::size_t buffer_sizes[1];
1537 buffer_sizes[0] = buffer_size;
1538
1539 res = deserialize(buffers, buffer_sizes, 1);
1540 }
1541
1542 allocator_.deallocate(buffer);
1543 }
1544 else
1545 {
1546 res = no_memory;
1547 }
1548 }
1549 }
1550
1551 return res;
1552 }
1553
get_serialize_buffer_size(std::size_t & buffer_size) const1554 result parameters::get_serialize_buffer_size(std::size_t & buffer_size) const
1555 {
1556 // the serialized format is:
1557 // 1. number of entries
1558 // 2. for each entry:
1559 // 1. name length
1560 // 2. name
1561 // 3. type
1562 // 4. value
1563 // depending on type, value is:
1564 // - boolean: 0 or 1 in 4 bytes
1565 // - integer: as is 4 bytets
1566 // - long_long: as is 8 bytes
1567 // - double_float: as is 8 bytes
1568 // - string: length followed by value
1569 // - boolean_array: length followed by packed (per bit) values
1570 // - integer_array: length followed by values
1571 // - long_long_array: length followed by values
1572 // - double_float_array: length followed by values
1573 // - string_array: length followed by values as for string
1574 // - nested: as the whole
1575
1576 // recurively for nested parameters:
1577
1578 buffer_size = 0;
1579 details::get_serialize_buffer_size(*this, buffer_size);
1580
1581 return ok;
1582 }
1583
serialize(char ** buffers,const std::size_t * buffer_sizes,std::size_t num_of_buffers) const1584 result parameters::serialize(char * * buffers,
1585 const std::size_t * buffer_sizes,
1586 std::size_t num_of_buffers) const
1587 {
1588 std::size_t current_buffer = 0;
1589 char * buffer_position = &buffers[0][0];
1590
1591 return details::serialize(*this,
1592 buffers, buffer_sizes, num_of_buffers,
1593 current_buffer, buffer_position);
1594 }
1595
deserialize(const char ** buffers,const std::size_t * buffer_sizes,std::size_t num_of_buffers)1596 result parameters::deserialize(
1597 const char * * buffers, const std::size_t * buffer_sizes,
1598 std::size_t num_of_buffers)
1599 {
1600 std::size_t current_buffer = 0;
1601 const char * buffer_position = &buffers[0][0];
1602
1603 return details::deserialize(*this,
1604 buffers, buffer_sizes, num_of_buffers,
1605 current_buffer, buffer_position);
1606 }
1607
dump(details::dump_sink & sink,std::size_t indent_length) const1608 void parameters::dump(
1609 details::dump_sink & sink, std::size_t indent_length) const
1610 {
1611 for (std::size_t i = 0; i != num_of_entries_; ++i)
1612 {
1613 bool add_newline = true;
1614 sink.indent(indent_length);
1615 sink.dump("entry ");
1616 sink.dump(i);
1617 sink.dump(":\n");
1618 switch (data_[i].type)
1619 {
1620 case unused:
1621 sink.indent(indent_length);
1622 sink.dump("unused");
1623 break;
1624 case boolean:
1625 sink.indent(indent_length);
1626 sink.dump("name: ");
1627 data_[i].name.dump(sink);
1628 sink.dump("\n");
1629 sink.indent(indent_length);
1630 sink.dump("boolean: ");
1631 sink.dump(data_[i].item.b);
1632 break;
1633 case integer:
1634 sink.indent(indent_length);
1635 sink.dump("name: ");
1636 data_[i].name.dump(sink);
1637 sink.dump("\n");
1638 sink.indent(indent_length);
1639 sink.dump("integer: ");
1640 sink.dump(data_[i].item.i);
1641 break;
1642 case long_long:
1643 sink.indent(indent_length);
1644 sink.dump("name: ");
1645 data_[i].name.dump(sink);
1646 sink.dump("\n");
1647 sink.indent(indent_length);
1648 sink.dump("long_long: ");
1649 sink.dump(data_[i].item.L);
1650 break;
1651 case double_float:
1652 sink.indent(indent_length);
1653 sink.dump("name: ");
1654 data_[i].name.dump(sink);
1655 sink.dump("\n");
1656 sink.indent(indent_length);
1657 sink.dump("double: ");
1658 sink.dump(data_[i].item.d);
1659 break;
1660 case string:
1661 sink.indent(indent_length);
1662 sink.dump("name: ");
1663 data_[i].name.dump(sink);
1664 sink.dump("\n");
1665 sink.indent(indent_length);
1666 sink.dump("string: ");
1667 sink.dump(data_[i].item.str.value,
1668 data_[i].item.str.length);
1669 break;
1670 case binary:
1671 sink.indent(indent_length);
1672 sink.dump("name: ");
1673 data_[i].name.dump(sink);
1674 sink.dump("\n");
1675 sink.indent(indent_length);
1676 sink.dump("binary of length ");
1677 sink.dump(data_[i].item.bin.length);
1678 break;
1679 case boolean_array:
1680 sink.indent(indent_length);
1681 sink.dump("name: ");
1682 data_[i].name.dump(sink);
1683 sink.dump("\n");
1684 sink.indent(indent_length);
1685 sink.dump("boolean array:");
1686 for (std::size_t j = 0; j != data_[i].item.ba.length; ++j)
1687 {
1688 sink.dump(" ");
1689 sink.dump(data_[i].item.ba.values[j]);
1690 }
1691 break;
1692 case integer_array:
1693 sink.indent(indent_length);
1694 sink.dump("name: ");
1695 data_[i].name.dump(sink);
1696 sink.dump("\n");
1697 sink.indent(indent_length);
1698 sink.dump("integer array:");
1699 for (std::size_t j = 0; j != data_[i].item.ia.length; ++j)
1700 {
1701 sink.dump(" ");
1702 sink.dump(data_[i].item.ia.values[j]);
1703 }
1704 break;
1705 case long_long_array:
1706 sink.indent(indent_length);
1707 sink.dump("name: ");
1708 data_[i].name.dump(sink);
1709 sink.dump("\n");
1710 sink.indent(indent_length);
1711 sink.dump("long_long array:");
1712 for (std::size_t j = 0; j != data_[i].item.La.length; ++j)
1713 {
1714 sink.dump(" ");
1715 sink.dump(data_[i].item.La.values[j]);
1716 }
1717 break;
1718 case double_float_array:
1719 sink.indent(indent_length);
1720 sink.dump("name: ");
1721 data_[i].name.dump(sink);
1722 sink.dump("\n");
1723 sink.indent(indent_length);
1724 sink.dump("double array:");
1725 for (std::size_t j = 0; j != data_[i].item.da.length; ++j)
1726 {
1727 sink.dump(" ");
1728 sink.dump(data_[i].item.da.values[j]);
1729 }
1730 break;
1731 case string_array:
1732 sink.indent(indent_length);
1733 sink.dump("name: ");
1734 data_[i].name.dump(sink);
1735 sink.dump("\n");
1736 sink.indent(indent_length);
1737 sink.dump("string array:");
1738 for (std::size_t j = 0; j != data_[i].item.sa.length; ++j)
1739 {
1740 sink.dump(" ");
1741 sink.dump(data_[i].item.sa.values[j].value,
1742 data_[i].item.sa.values[j].length);
1743 }
1744 break;
1745 case binary_array:
1746 sink.indent(indent_length);
1747 sink.dump("name: ");
1748 data_[i].name.dump(sink);
1749 sink.dump("\n");
1750 sink.indent(indent_length);
1751 sink.dump("binary array of length ");
1752 sink.dump(data_[i].item.bina.length);
1753 break;
1754 case nested_parameters:
1755 sink.indent(indent_length);
1756 sink.dump("name: ");
1757 data_[i].name.dump(sink);
1758 sink.dump("\n");
1759 sink.indent(indent_length);
1760 sink.dump("nested parameters:\n");
1761 data_[i].item.nested->dump(sink, indent_length + 2);
1762 add_newline = false;
1763 break;
1764 case nested_parameters_array:
1765 sink.indent(indent_length);
1766 sink.dump("name: ");
1767 data_[i].name.dump(sink);
1768 sink.dump("\n");
1769 sink.indent(indent_length);
1770 sink.dump("nested parameters array of length ");
1771 sink.dump(data_[i].item.nesteda.length);
1772 sink.dump(":\n");
1773 for (std::size_t j = 0; j != data_[i].item.nesteda.length; ++j)
1774 {
1775 sink.indent(indent_length);
1776 sink.dump(" nested at index ");
1777 sink.dump(j);
1778 sink.dump(":\n");
1779 data_[i].item.nesteda.values[j].dump(sink, indent_length + 4);
1780 }
1781 add_newline = false;
1782 break;
1783 default:
1784 details::fatal_failure(__FILE__, __LINE__);
1785 }
1786
1787 if (add_newline)
1788 {
1789 sink.dump("\n");
1790 }
1791 }
1792 }
1793
1794