root/library/bdm/base/libconfig/libconfigcpp.c++ @ 652

Revision 248, 27.3 kB (checked in by smidl, 15 years ago)

doc

Line 
1/* ----------------------------------------------------------------------------
2   libconfig - A library for processing structured configuration files
3   Copyright (C) 2005-2008  Mark A Lindner
4 
5   This file is part of libconfig.
6   
7   This library is free software; you can redistribute it and/or
8   modify it under the terms of the GNU Lesser General Public License
9   as published by the Free Software Foundation; either version 2.1 of
10   the License, or (at your option) any later version.
11   
12   This library is distributed in the hope that it will be useful, but
13   WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15   Lesser General Public License for more details.
16   
17   You should have received a copy of the GNU Library General Public
18   License along with this library; if not, see
19   <http://www.gnu.org/licenses/>.
20   ----------------------------------------------------------------------------
21*/
22
23#include "libconfig.h++"
24
25#ifdef _MSC_VER
26#pragma warning (disable: 4996)
27#endif
28
29#include "wincompat.h"
30
31using namespace libconfig;
32
33#include <cstring>
34#include <cstdlib>
35#include <sstream>
36
37// ---------------------------------------------------------------------------
38
39ParseException::ParseException(int line, const char *error)
40  : _line(line), _error(error)
41{
42}
43
44// ---------------------------------------------------------------------------
45
46ParseException::~ParseException() throw()
47{
48}
49
50// ---------------------------------------------------------------------------
51
52const char *ParseException::what() const throw()
53{
54  return("ParseException");
55}
56
57// ---------------------------------------------------------------------------
58
59static int __toTypeCode(Setting::Type type)
60{
61  int typecode;
62
63  switch(type)
64  {
65    case Setting::TypeGroup:
66      typecode = CONFIG_TYPE_GROUP;
67      break;
68     
69    case Setting::TypeInt:
70      typecode = CONFIG_TYPE_INT;
71      break;
72
73    case Setting::TypeInt64:
74      typecode = CONFIG_TYPE_INT64;
75      break;
76
77    case Setting::TypeFloat:
78      typecode = CONFIG_TYPE_FLOAT;
79      break;
80
81    case Setting::TypeString:
82      typecode = CONFIG_TYPE_STRING;
83      break;
84
85    case Setting::TypeBoolean:
86      typecode = CONFIG_TYPE_BOOL;
87      break;
88
89    case Setting::TypeArray:
90      typecode = CONFIG_TYPE_ARRAY;
91      break;
92
93    case Setting::TypeList:
94      typecode = CONFIG_TYPE_LIST;
95      break;
96     
97    default:
98      typecode = CONFIG_TYPE_NONE;
99  }
100
101  return(typecode);
102}
103
104// ---------------------------------------------------------------------------
105
106static void __constructPath(const Setting &setting,
107                            std::stringstream &path)
108{
109  // head recursion to print path from root to target
110 
111  if(! setting.isRoot())
112  {
113    __constructPath(setting.getParent(), path);
114    if(path.tellp() > 0)
115      path << '.';
116
117    const char *name = setting.getName();
118    if(name)
119      path << name;
120    else
121      path << '[' << setting.getIndex() << ']';
122  }
123}
124
125// ---------------------------------------------------------------------------
126
127SettingException::SettingException(const Setting &setting)
128{
129  std::stringstream sstr;
130  __constructPath(setting, sstr);
131
132  _path = ::strdup(sstr.str().c_str());
133}
134
135// ---------------------------------------------------------------------------
136
137SettingException::SettingException(const Setting &setting, int idx)
138{
139  std::stringstream sstr;
140  __constructPath(setting, sstr);
141  sstr << ".[" << idx << "]";
142
143  _path = ::strdup(sstr.str().c_str());
144}
145
146// ---------------------------------------------------------------------------
147
148SettingException::SettingException(const Setting &setting, const char *name)
149{
150  std::stringstream sstr;
151  __constructPath(setting, sstr);
152  sstr << '.' << name;
153
154  _path = ::strdup(sstr.str().c_str());
155}
156
157// ---------------------------------------------------------------------------
158
159SettingException::SettingException(const char *path)
160{
161  _path = ::strdup(path);
162}
163
164// ---------------------------------------------------------------------------
165
166const char *SettingException::getPath() const
167{
168  return(_path);
169}
170
171// ---------------------------------------------------------------------------
172
173SettingException::SettingException(const SettingException &other)
174{
175  _path = ::strdup(other._path);
176}
177
178// ---------------------------------------------------------------------------
179
180SettingException &SettingException::operator=(const SettingException &other)
181{
182  ::free(_path);
183  _path = ::strdup(other._path);
184
185  return(*this);
186}
187
188// ---------------------------------------------------------------------------
189
190const char *SettingException::what() const throw()
191{
192  return("SettingException");
193}
194
195// ---------------------------------------------------------------------------
196
197SettingException::~SettingException() throw()
198{
199  ::free(_path);
200}
201
202// ---------------------------------------------------------------------------
203
204SettingTypeException::SettingTypeException(const Setting &setting)
205  : SettingException(setting)
206{
207}
208
209// ---------------------------------------------------------------------------
210
211SettingTypeException::SettingTypeException(const Setting &setting, int idx)
212  : SettingException(setting, idx)
213{
214}
215
216// ---------------------------------------------------------------------------
217
218SettingTypeException::SettingTypeException(const Setting &setting,
219                                           const char *name)
220  : SettingException(setting, name)
221{
222}
223
224// ---------------------------------------------------------------------------
225
226const char *SettingTypeException::what() const throw()
227{
228  return("SettingTypeException");
229}
230
231// ---------------------------------------------------------------------------
232
233SettingNotFoundException::SettingNotFoundException(const Setting &setting,
234                                                   int idx)
235  : SettingException(setting, idx)
236{
237}
238
239// ---------------------------------------------------------------------------
240
241SettingNotFoundException::SettingNotFoundException(const Setting &setting,
242                                                   const char *name)
243  : SettingException(setting, name)
244{
245}
246
247// ---------------------------------------------------------------------------
248
249SettingNotFoundException::SettingNotFoundException(const char *path)
250  : SettingException(path)
251{
252}
253
254// ---------------------------------------------------------------------------
255
256const char *SettingNotFoundException::what() const throw()
257{
258  return("SettingNotFoundException");
259}
260
261// ---------------------------------------------------------------------------
262
263SettingNameException::SettingNameException(const Setting &setting,
264                                           const char *name)
265  : SettingException(setting, name)
266{
267}
268
269// ---------------------------------------------------------------------------
270
271const char *SettingNameException::what() const throw()
272{
273  return("SettingNameException");
274}
275
276// ---------------------------------------------------------------------------
277
278const char *FileIOException::what() const throw()
279{
280  return("FileIOException");
281}
282
283// ---------------------------------------------------------------------------
284
285void Config::ConfigDestructor(void *arg)
286{
287  delete reinterpret_cast<Setting *>(arg);
288}
289
290// ---------------------------------------------------------------------------
291
292Config::Config()
293{
294  config_init(& _config);
295  config_set_destructor(& _config, ConfigDestructor);
296}
297
298// ---------------------------------------------------------------------------
299
300Config::~Config()
301{
302  config_destroy(& _config);
303}
304
305// ---------------------------------------------------------------------------
306
307void Config::setAutoConvert(bool flag)
308{
309  config_set_auto_convert(& _config, (flag ? CONFIG_TRUE : CONFIG_FALSE));
310}
311
312// ---------------------------------------------------------------------------
313
314bool Config::getAutoConvert() const
315{
316  return(config_get_auto_convert(& _config) != CONFIG_FALSE);
317}
318
319// ---------------------------------------------------------------------------
320
321void Config::read(FILE *stream) throw(ParseException)
322{
323  if(! config_read(& _config, stream))
324    throw ParseException(config_error_line(& _config),
325                         config_error_text(& _config));
326}
327
328// ---------------------------------------------------------------------------
329
330void Config::write(FILE *stream) const
331{
332  config_write(& _config, stream);
333}
334
335// ---------------------------------------------------------------------------
336
337void Config::readFile(const char *filename) throw(FileIOException,
338                                                  ParseException)
339{
340  FILE *f = fopen(filename, "rt");
341  if(f == NULL)
342    throw FileIOException();
343  try
344  {
345    read(f);
346    fclose(f);
347  }
348  catch(ParseException& p)
349  {
350    fclose(f);
351    throw p;
352  }
353}
354
355// ---------------------------------------------------------------------------
356
357void Config::writeFile(const char *filename) throw(FileIOException)
358{
359  if(! config_write_file(& _config, filename))
360    throw FileIOException();
361}
362
363// ---------------------------------------------------------------------------
364
365Setting & Config::lookup(const char *path) const
366  throw(SettingNotFoundException)
367{
368  config_setting_t *s = config_lookup(& _config, path);
369  if(! s)
370    throw SettingNotFoundException(path);
371
372  return(Setting::wrapSetting(s));
373}
374
375// ---------------------------------------------------------------------------
376
377bool Config::exists(const char *path) const throw()
378{
379  config_setting_t *s = config_lookup(& _config, path);
380
381  return(s != NULL);
382}
383
384// ---------------------------------------------------------------------------
385
386#define CONFIG_LOOKUP_NO_EXCEPTIONS(P, T, V)    \
387  try                                           \
388  {                                             \
389    Setting &s = lookup(P);                     \
390    V = (T)s;                                   \
391    return(true);                               \
392  }                                             \
393  catch(ConfigException)                        \
394  {                                             \
395    return(false);                              \
396  }
397
398// ---------------------------------------------------------------------------
399
400bool Config::lookupValue(const char *path, bool &value) const throw()
401{
402  CONFIG_LOOKUP_NO_EXCEPTIONS(path, bool, value);
403}
404
405// ---------------------------------------------------------------------------
406
407bool Config::lookupValue(const char *path, long &value) const throw()
408{
409  CONFIG_LOOKUP_NO_EXCEPTIONS(path, long, value);
410}
411
412// ---------------------------------------------------------------------------
413
414bool Config::lookupValue(const char *path, unsigned long &value) const throw()
415{
416  CONFIG_LOOKUP_NO_EXCEPTIONS(path, unsigned long, value);
417}
418
419// ---------------------------------------------------------------------------
420
421bool Config::lookupValue(const char *path, int &value) const throw()
422{
423  CONFIG_LOOKUP_NO_EXCEPTIONS(path, int, value);
424}
425
426// ---------------------------------------------------------------------------
427
428bool Config::lookupValue(const char *path, unsigned int &value) const throw()
429{
430  CONFIG_LOOKUP_NO_EXCEPTIONS(path, unsigned int, value);
431}
432
433// ---------------------------------------------------------------------------
434
435bool Config::lookupValue(const char *path, long long &value) const throw()
436{
437  CONFIG_LOOKUP_NO_EXCEPTIONS(path, long long, value);
438}
439
440// ---------------------------------------------------------------------------
441
442bool Config::lookupValue(const char *path, unsigned long long &value)
443  const throw()
444{
445  CONFIG_LOOKUP_NO_EXCEPTIONS(path, unsigned long long, value);
446}
447
448// ---------------------------------------------------------------------------
449
450bool Config::lookupValue(const char *path, double &value) const throw()
451{
452  CONFIG_LOOKUP_NO_EXCEPTIONS(path, double, value);
453}
454
455// ---------------------------------------------------------------------------
456
457bool Config::lookupValue(const char *path, float &value) const throw()
458{
459  CONFIG_LOOKUP_NO_EXCEPTIONS(path, float, value);
460}
461
462// ---------------------------------------------------------------------------
463
464bool Config::lookupValue(const char *path, const char *&value) const throw()
465{
466  CONFIG_LOOKUP_NO_EXCEPTIONS(path, const char *, value);
467}
468
469// ---------------------------------------------------------------------------
470
471bool Config::lookupValue(const char *path, std::string &value) const throw()
472{
473  CONFIG_LOOKUP_NO_EXCEPTIONS(path, const char *, value);
474}
475
476// ---------------------------------------------------------------------------
477
478Setting & Config::getRoot() const
479{
480  return(Setting::wrapSetting(config_root_setting(& _config)));
481}
482
483// ---------------------------------------------------------------------------
484
485Setting::Setting(config_setting_t *setting)
486  : _setting(setting)
487{
488  switch(config_setting_type(setting))
489  {
490    case CONFIG_TYPE_GROUP:
491      _type = TypeGroup;
492      break;
493
494    case CONFIG_TYPE_INT:
495      _type = TypeInt;
496      break;
497
498    case CONFIG_TYPE_INT64:
499      _type = TypeInt64;
500      break;
501
502    case CONFIG_TYPE_FLOAT:
503      _type = TypeFloat;
504      break;
505
506    case CONFIG_TYPE_STRING:
507      _type = TypeString;
508      break;
509
510    case CONFIG_TYPE_BOOL:
511      _type = TypeBoolean;
512      break;
513
514    case CONFIG_TYPE_ARRAY:
515      _type = TypeArray;
516      break;
517
518    case CONFIG_TYPE_LIST:
519      _type = TypeList;
520      break;
521
522    case CONFIG_TYPE_NONE:
523    default:
524      _type = TypeNone;
525      break;
526  }
527
528  switch(config_setting_get_format(setting))
529  {
530    case CONFIG_FORMAT_HEX:
531      _format = FormatHex;
532      break;
533
534    case CONFIG_FORMAT_DEFAULT:
535    default:
536      _format = FormatDefault;
537      break;
538  }
539}
540
541// ---------------------------------------------------------------------------
542
543Setting::~Setting() throw()
544{
545  _setting = NULL;
546}
547
548// ---------------------------------------------------------------------------
549
550void Setting::setFormat(Format format) throw()
551{
552  if((_type == TypeInt) || (_type == TypeInt64))
553  {
554    if(format == FormatHex)
555      _format = FormatHex;
556    else
557      _format = FormatDefault;
558  }
559  else
560    _format = FormatDefault;
561}
562
563// ---------------------------------------------------------------------------
564
565Setting::operator bool() const throw(SettingTypeException)
566{
567  assertType(TypeBoolean);
568
569  return(config_setting_get_bool(_setting) ? true : false);
570}
571
572// ---------------------------------------------------------------------------
573
574Setting::operator long() const throw(SettingTypeException)
575{
576  assertType(TypeInt);
577
578  return(config_setting_get_int(_setting));
579}
580
581// ---------------------------------------------------------------------------
582
583Setting::operator unsigned long() const throw(SettingTypeException)
584{
585  assertType(TypeInt);
586
587  long v = config_setting_get_int(_setting);
588
589  if(v < 0)
590    v = 0;
591 
592  return(static_cast<unsigned long>(v));
593}
594
595// ---------------------------------------------------------------------------
596
597Setting::operator int() const throw(SettingTypeException)
598{
599  assertType(TypeInt);
600
601  // may cause loss of precision:
602  return(static_cast<int>(config_setting_get_int(_setting)));
603}
604
605// ---------------------------------------------------------------------------
606
607Setting::operator unsigned int() const throw(SettingTypeException)
608{
609  assertType(TypeInt);
610
611  long v = config_setting_get_int(_setting);
612
613  if(v < 0)
614    v = 0;
615
616  return(static_cast<unsigned int>(v));
617}
618
619// ---------------------------------------------------------------------------
620
621Setting::operator long long() const throw(SettingTypeException)
622{
623  assertType(TypeInt64);
624
625  return(config_setting_get_int64(_setting));
626}
627
628// ---------------------------------------------------------------------------
629
630Setting::operator unsigned long long() const throw(SettingTypeException)
631{
632  assertType(TypeInt64);
633
634  long long v = config_setting_get_int64(_setting);
635
636  if(v < INT64_CONST(0))
637    v = INT64_CONST(0);
638
639  return(static_cast<unsigned long long>(v));
640}
641
642// ---------------------------------------------------------------------------
643
644Setting::operator double() const throw(SettingTypeException)
645{
646  assertType(TypeFloat);
647
648  return(config_setting_get_float(_setting));
649}
650
651// ---------------------------------------------------------------------------
652
653Setting::operator float() const throw(SettingTypeException)
654{
655  assertType(TypeFloat);
656
657  // may cause loss of precision:
658  return(static_cast<float>(config_setting_get_float(_setting)));
659}
660
661// ---------------------------------------------------------------------------
662
663Setting::operator const char *() const throw(SettingTypeException)
664{
665  assertType(TypeString);
666
667  return(config_setting_get_string(_setting));
668}
669
670// ---------------------------------------------------------------------------
671
672Setting::operator std::string() const throw(SettingTypeException)
673{
674  assertType(TypeString);
675
676  const char *s = config_setting_get_string(_setting);
677
678  std::string str;
679  if(s)
680    str = s;
681
682  return(str);
683}
684
685// ---------------------------------------------------------------------------
686
687Setting & Setting::operator=(bool value) throw(SettingTypeException)
688{
689  assertType(TypeBoolean);
690
691  config_setting_set_bool(_setting, value);
692
693  return(*this);
694}
695
696// ---------------------------------------------------------------------------
697
698Setting & Setting::operator=(long value) throw(SettingTypeException)
699{
700  assertType(TypeInt);
701
702  config_setting_set_int(_setting, value);
703
704  return(*this);
705}
706
707// ---------------------------------------------------------------------------
708
709Setting & Setting::operator=(int value) throw(SettingTypeException)
710{
711  assertType(TypeInt);
712
713  long cvalue = static_cast<long>(value);
714 
715  config_setting_set_int(_setting, cvalue);
716
717  return(*this);
718}
719
720// ---------------------------------------------------------------------------
721
722Setting & Setting::operator=(const long long &value)
723  throw(SettingTypeException)
724{
725  assertType(TypeInt64);
726
727  config_setting_set_int64(_setting, value);
728
729  return(*this);
730}
731
732// ---------------------------------------------------------------------------
733
734Setting & Setting::operator=(const double &value) throw(SettingTypeException)
735{
736  assertType(TypeFloat);
737
738  config_setting_set_float(_setting, value);
739
740  return(*this);
741}
742
743// ---------------------------------------------------------------------------
744
745Setting & Setting::operator=(float value) throw(SettingTypeException)
746{
747  assertType(TypeFloat);
748
749  double cvalue = static_cast<double>(value);
750
751  config_setting_set_float(_setting, cvalue);
752
753  return(*this);
754}
755
756// ---------------------------------------------------------------------------
757
758Setting & Setting::operator=(const char *value) throw(SettingTypeException)
759{
760  assertType(TypeString);
761
762  config_setting_set_string(_setting, value);
763
764  return(*this);
765}
766
767// ---------------------------------------------------------------------------
768
769Setting & Setting::operator=(const std::string &value)
770  throw(SettingTypeException)
771{
772  assertType(TypeString);
773
774  config_setting_set_string(_setting, value.c_str());
775
776  return(*this);
777}
778
779// ---------------------------------------------------------------------------
780
781Setting & Setting::operator[](int i) const
782  throw(SettingTypeException, SettingNotFoundException)
783{
784  if((_type != TypeArray) && (_type != TypeGroup) && (_type != TypeList))
785    throw SettingTypeException(*this, i);
786 
787  config_setting_t *setting = config_setting_get_elem(_setting, i);
788
789  if(! setting)
790    throw SettingNotFoundException(*this, i);
791
792  return(wrapSetting(setting));
793}
794
795// ---------------------------------------------------------------------------
796
797Setting & Setting::operator[](const char *key) const
798  throw(SettingTypeException, SettingNotFoundException)
799{
800  assertType(TypeGroup);
801
802  config_setting_t *setting = config_setting_get_member(_setting, key);
803
804  if(! setting)
805    throw SettingNotFoundException(*this, key);
806
807  return(wrapSetting(setting));
808}
809
810// ---------------------------------------------------------------------------
811
812#define SETTING_LOOKUP_NO_EXCEPTIONS(K, T, V)   \
813  try                                           \
814  {                                             \
815    Setting &s = operator[](K);                 \
816    V = (T)s;                                   \
817    return(true);                               \
818  }                                             \
819  catch(ConfigException)                        \
820  {                                             \
821    return(false);                              \
822  }
823
824// ---------------------------------------------------------------------------
825
826bool Setting::lookupValue(const char *name, bool &value) const throw()
827{
828  SETTING_LOOKUP_NO_EXCEPTIONS(name, bool, value);
829}
830
831// ---------------------------------------------------------------------------
832
833bool Setting::lookupValue(const char *name, long &value) const throw()
834{
835  SETTING_LOOKUP_NO_EXCEPTIONS(name, long, value);
836}
837
838// ---------------------------------------------------------------------------
839
840bool Setting::lookupValue(const char *name, unsigned long &value)
841  const throw()
842{
843  SETTING_LOOKUP_NO_EXCEPTIONS(name, unsigned long, value);
844}
845
846// ---------------------------------------------------------------------------
847
848bool Setting::lookupValue(const char *name, int &value) const throw()
849{
850  SETTING_LOOKUP_NO_EXCEPTIONS(name, int, value);
851}
852
853// ---------------------------------------------------------------------------
854
855bool Setting::lookupValue(const char *name, unsigned int &value) const throw()
856{
857  SETTING_LOOKUP_NO_EXCEPTIONS(name, unsigned int, value);
858}
859
860// ---------------------------------------------------------------------------
861
862bool Setting::lookupValue(const char *name, long long &value) const throw()
863{
864  SETTING_LOOKUP_NO_EXCEPTIONS(name, long long, value);
865}
866
867// ---------------------------------------------------------------------------
868
869bool Setting::lookupValue(const char *name, unsigned long long &value)
870  const throw()
871{
872  SETTING_LOOKUP_NO_EXCEPTIONS(name, unsigned long long, value);
873}
874
875// ---------------------------------------------------------------------------
876
877bool Setting::lookupValue(const char *name, double &value) const throw()
878{
879  SETTING_LOOKUP_NO_EXCEPTIONS(name, double, value);
880}
881
882// ---------------------------------------------------------------------------
883
884bool Setting::lookupValue(const char *name, float &value) const throw()
885{
886  SETTING_LOOKUP_NO_EXCEPTIONS(name, float, value);
887}
888
889// ---------------------------------------------------------------------------
890
891bool Setting::lookupValue(const char *name, const char *&value) const throw()
892{
893  SETTING_LOOKUP_NO_EXCEPTIONS(name, const char *, value);
894}
895
896// ---------------------------------------------------------------------------
897
898bool Setting::lookupValue(const char *name, std::string &value) const throw()
899{
900  SETTING_LOOKUP_NO_EXCEPTIONS(name, const char *, value);
901}
902
903// ---------------------------------------------------------------------------
904
905bool Setting::exists(const char *name) const throw()
906{
907  if(_type != TypeGroup)
908    return(false);
909
910  config_setting_t *setting = config_setting_get_member(_setting, name);
911
912  return(setting != NULL);
913}
914
915// ---------------------------------------------------------------------------
916
917int Setting::getLength() const throw()
918{
919  return(config_setting_length(_setting));
920}
921
922// ---------------------------------------------------------------------------
923
924const char * Setting::getName() const throw()
925{
926  return(config_setting_name(_setting));
927}
928
929// ---------------------------------------------------------------------------
930
931std::string Setting::getPath() const
932{
933  std::stringstream path;
934
935  __constructPath(*this, path);
936
937  return(path.str());
938}
939
940// ---------------------------------------------------------------------------
941
942const Setting & Setting::getParent() const throw(SettingNotFoundException)
943{
944  config_setting_t *setting = config_setting_parent(_setting);
945
946  if(! setting)
947    throw SettingNotFoundException(NULL);
948
949  return(wrapSetting(setting));
950}
951
952// ---------------------------------------------------------------------------
953
954Setting & Setting::getParent() throw(SettingNotFoundException)
955{
956  config_setting_t *setting = config_setting_parent(_setting);
957
958  if(! setting)
959    throw SettingNotFoundException(NULL);
960
961  return(wrapSetting(setting));
962}
963
964// ---------------------------------------------------------------------------
965
966bool Setting::isRoot() const throw()
967{
968  return(config_setting_is_root(_setting));
969}
970
971// ---------------------------------------------------------------------------
972
973int Setting::getIndex() const throw()
974{
975  return(config_setting_index(_setting));
976}
977
978// ---------------------------------------------------------------------------
979
980void Setting::remove(const char *name)
981  throw(SettingTypeException, SettingNotFoundException)
982{
983  assertType(TypeGroup);
984 
985  if(! config_setting_remove(_setting, name))
986    throw SettingNotFoundException(*this, name);
987}
988
989// ---------------------------------------------------------------------------
990
991void Setting::remove(unsigned int idx)
992  throw(SettingTypeException, SettingNotFoundException)
993{
994  if((_type != TypeArray) && (_type != TypeGroup) && (_type != TypeList))
995    throw SettingTypeException(*this, idx);
996 
997  if(! config_setting_remove_elem(_setting, idx))
998    throw SettingNotFoundException(*this, idx);
999}
1000
1001// ---------------------------------------------------------------------------
1002
1003Setting & Setting::add(const char *name, Setting::Type type)
1004  throw(SettingNameException, SettingTypeException)
1005{
1006  assertType(TypeGroup);
1007 
1008  int typecode = __toTypeCode(type);
1009
1010  if(typecode == CONFIG_TYPE_NONE)
1011    throw SettingTypeException(*this, name);
1012
1013  config_setting_t *setting = config_setting_add(_setting, name, typecode);
1014
1015  if(! setting)
1016    throw SettingNameException(*this, name);
1017
1018  return(wrapSetting(setting));
1019}
1020
1021// ---------------------------------------------------------------------------
1022
1023Setting & Setting::add(Setting::Type type) throw(SettingTypeException)
1024{
1025  if((_type != TypeArray) && (_type != TypeList))
1026    throw SettingTypeException(*this);
1027
1028  if(_type == TypeArray)
1029  {
1030    int idx = getLength();
1031   
1032    if(idx > 0)
1033    {
1034      Setting::Type atype = operator[](0).getType();
1035      if(type != atype)
1036        throw SettingTypeException(*this, idx);
1037    }
1038    else
1039    {
1040      if((type != TypeInt) && (type != TypeFloat) && (type != TypeString)
1041         && (type != TypeBoolean))
1042        throw SettingTypeException(*this, idx);
1043    }
1044  }
1045
1046  int typecode = __toTypeCode(type);
1047  config_setting_t *s = config_setting_add(_setting, NULL, typecode);
1048
1049  Setting &ns = wrapSetting(s);
1050
1051  switch(type)
1052  {
1053    case TypeInt:
1054      ns = 0;
1055      break;
1056
1057    case TypeInt64:
1058      ns = INT64_CONST(0);
1059      break;
1060
1061    case TypeFloat:
1062      ns = 0.0;
1063      break;
1064
1065    case TypeString:
1066      ns = (char *)NULL;
1067      break;
1068
1069    case TypeBoolean:
1070      ns = false;
1071      break;
1072
1073    default:
1074      // won't happen
1075      break;
1076  }
1077
1078  return(ns);
1079}
1080
1081// ---------------------------------------------------------------------------
1082
1083void Setting::assertType(Setting::Type type) const throw(SettingTypeException)
1084{
1085  if(type != _type)
1086  {
1087    if(!(isNumber() && config_get_auto_convert(_setting->config)
1088         && ((type == TypeInt) || (type == TypeFloat))))
1089      throw SettingTypeException(*this);
1090  }
1091}
1092
1093// ---------------------------------------------------------------------------
1094
1095Setting & Setting::wrapSetting(config_setting_t *s)
1096{
1097  Setting *setting = NULL;
1098 
1099  void *hook = config_setting_get_hook(s);
1100  if(! hook)
1101  {
1102    setting = new Setting(s);
1103    config_setting_set_hook(s, reinterpret_cast<void *>(setting));
1104  }
1105  else
1106    setting = reinterpret_cast<Setting *>(hook);
1107
1108  return(*setting);
1109}
1110
1111// ---------------------------------------------------------------------------
1112// eof
Note: See TracBrowser for help on using the browser.