diff options
Diffstat (limited to 'lib/libconfigcpp.c++')
-rw-r--r-- | lib/libconfigcpp.c++ | 1487 |
1 files changed, 1487 insertions, 0 deletions
diff --git a/lib/libconfigcpp.c++ b/lib/libconfigcpp.c++ new file mode 100644 index 0000000..9cdee4d --- /dev/null +++ b/lib/libconfigcpp.c++ @@ -0,0 +1,1487 @@ +/* ---------------------------------------------------------------------------- + libconfig - A library for processing structured configuration files + Copyright (C) 2005-2018 Mark A Lindner + + This file is part of libconfig. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License + as published by the Free Software Foundation; either version 2.1 of + the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, see + <http://www.gnu.org/licenses/>. + ---------------------------------------------------------------------------- +*/ + +#include "libconfig.h++" + +#ifdef _MSC_VER +#pragma warning (disable: 4996) +#endif + +#include "wincompat.h" +#include "libconfig.h" + +#include <cstring> +#include <cstdlib> +#include <sstream> + +namespace libconfig { + +// --------------------------------------------------------------------------- + +static const char **__include_func(config_t *config, + const char *include_dir, + const char *path, + const char **error) +{ + Config *self = reinterpret_cast<Config *>(config_get_hook(config)); + return(self->evaluateIncludePath(path, error)); +} + +// --------------------------------------------------------------------------- + +ParseException::ParseException(const char *file, int line, const char *error) + : _file(file ? ::strdup(file) : NULL), _line(line), _error(error) +{ +} + +// --------------------------------------------------------------------------- + +ParseException::ParseException(const ParseException &other) + : ConfigException(other), + _file(other._file ? ::strdup(other._file) : NULL), + _line(other._line), + _error(other._error) +{ +} + +// --------------------------------------------------------------------------- + +ParseException::~ParseException() LIBCONFIGXX_NOEXCEPT +{ + ::free((void *)_file); +} + +// --------------------------------------------------------------------------- + +const char *ParseException::what() const LIBCONFIGXX_NOEXCEPT +{ + return("ParseException"); +} + +// --------------------------------------------------------------------------- + +static int __toTypeCode(Setting::Type type) +{ + int typecode; + + switch(type) + { + case Setting::TypeGroup: + typecode = CONFIG_TYPE_GROUP; + break; + + case Setting::TypeInt: + typecode = CONFIG_TYPE_INT; + break; + + case Setting::TypeInt64: + typecode = CONFIG_TYPE_INT64; + break; + + case Setting::TypeFloat: + typecode = CONFIG_TYPE_FLOAT; + break; + + case Setting::TypeString: + typecode = CONFIG_TYPE_STRING; + break; + + case Setting::TypeBoolean: + typecode = CONFIG_TYPE_BOOL; + break; + + case Setting::TypeArray: + typecode = CONFIG_TYPE_ARRAY; + break; + + case Setting::TypeList: + typecode = CONFIG_TYPE_LIST; + break; + + default: + typecode = CONFIG_TYPE_NONE; + } + + return(typecode); +} + +// --------------------------------------------------------------------------- + +static void __constructPath(const Setting &setting, + std::stringstream &path) +{ + // head recursion to print path from root to target + + if(! setting.isRoot()) + { + __constructPath(setting.getParent(), path); + if(path.tellp() > 0) + path << '.'; + + const char *name = setting.getName(); + if(name) + path << name; + else + path << '[' << setting.getIndex() << ']'; + } +} + +// --------------------------------------------------------------------------- + +SettingException::SettingException(const Setting &setting) +{ + std::stringstream sstr; + __constructPath(setting, sstr); + + _path = ::strdup(sstr.str().c_str()); +} + +// --------------------------------------------------------------------------- + +SettingException::SettingException(const Setting &setting, int idx) +{ + std::stringstream sstr; + __constructPath(setting, sstr); + sstr << ".[" << idx << "]"; + + _path = ::strdup(sstr.str().c_str()); +} + +// --------------------------------------------------------------------------- + +SettingException::SettingException(const Setting &setting, const char *name) +{ + std::stringstream sstr; + __constructPath(setting, sstr); + sstr << '.' << name; + + _path = ::strdup(sstr.str().c_str()); +} + +// --------------------------------------------------------------------------- + +SettingException::SettingException(const char *path) +{ + _path = ::strdup(path); +} + +// --------------------------------------------------------------------------- + +const char *SettingException::getPath() const +{ + return(_path); +} + +// --------------------------------------------------------------------------- + +SettingException::SettingException(const SettingException &other) + : ConfigException(other) +{ + _path = ::strdup(other._path); +} + +// --------------------------------------------------------------------------- + +SettingException &SettingException::operator=(const SettingException &other) +{ + ::free(_path); + _path = ::strdup(other._path); + + return(*this); +} + +// --------------------------------------------------------------------------- + +const char *SettingException::what() const LIBCONFIGXX_NOEXCEPT +{ + return("SettingException"); +} + +// --------------------------------------------------------------------------- + +SettingException::~SettingException() LIBCONFIGXX_NOEXCEPT +{ + ::free(_path); +} + +// --------------------------------------------------------------------------- + +SettingTypeException::SettingTypeException(const Setting &setting) + : SettingException(setting) +{ +} + +// --------------------------------------------------------------------------- + +SettingTypeException::SettingTypeException(const Setting &setting, int idx) + : SettingException(setting, idx) +{ +} + +// --------------------------------------------------------------------------- + +SettingTypeException::SettingTypeException(const Setting &setting, + const char *name) + : SettingException(setting, name) +{ +} + +// --------------------------------------------------------------------------- + +const char *SettingTypeException::what() const LIBCONFIGXX_NOEXCEPT +{ + return("SettingTypeException"); +} + +// --------------------------------------------------------------------------- + +SettingNotFoundException::SettingNotFoundException(const Setting &setting, + int idx) + : SettingException(setting, idx) +{ +} + +// --------------------------------------------------------------------------- + +SettingNotFoundException::SettingNotFoundException(const Setting &setting, + const char *name) + : SettingException(setting, name) +{ +} + +// --------------------------------------------------------------------------- + +SettingNotFoundException::SettingNotFoundException(const char *path) + : SettingException(path) +{ +} + +// --------------------------------------------------------------------------- + +const char *SettingNotFoundException::what() const LIBCONFIGXX_NOEXCEPT +{ + return("SettingNotFoundException"); +} + +// --------------------------------------------------------------------------- + +SettingNameException::SettingNameException(const Setting &setting, + const char *name) + : SettingException(setting, name) +{ +} + +// --------------------------------------------------------------------------- + +const char *SettingNameException::what() const LIBCONFIGXX_NOEXCEPT +{ + return("SettingNameException"); +} + +// --------------------------------------------------------------------------- + +const char *FileIOException::what() const LIBCONFIGXX_NOEXCEPT +{ + return("FileIOException"); +} + +// --------------------------------------------------------------------------- + +void Config::ConfigDestructor(void *arg) +{ + delete reinterpret_cast<Setting *>(arg); +} + +// --------------------------------------------------------------------------- + +Config::Config() + : _defaultFormat(Setting::FormatDefault) +{ + _config = new config_t; + config_init(_config); + config_set_hook(_config, reinterpret_cast<void *>(this)); + config_set_destructor(_config, ConfigDestructor); + config_set_include_func(_config, __include_func); +} + +// --------------------------------------------------------------------------- + +Config::~Config() +{ + config_destroy(_config); + delete _config; +} + +// --------------------------------------------------------------------------- + +void Config::clear() +{ + config_clear(_config); +} + +// --------------------------------------------------------------------------- + +void Config::setOptions(int options) +{ + config_set_options(_config, options); +} + +// --------------------------------------------------------------------------- + +int Config::getOptions() const +{ + return(config_get_options(_config)); +} + +// --------------------------------------------------------------------------- + +void Config::setOption(Config::Option option, bool flag) +{ + config_set_option(_config, (int)option, flag ? CONFIG_TRUE : CONFIG_FALSE); +} + +// --------------------------------------------------------------------------- + +bool Config::getOption(Config::Option option) const +{ + return(config_get_option(_config, (int)option) == CONFIG_TRUE); +} + +// --------------------------------------------------------------------------- + +void Config::setDefaultFormat(Setting::Format format) +{ + if(format == Setting::FormatHex) + _defaultFormat = Setting::FormatHex; + else + _defaultFormat = Setting::FormatDefault; + + config_set_default_format(_config, static_cast<short>(_defaultFormat)); +} + +// --------------------------------------------------------------------------- + +void Config::setTabWidth(unsigned short width) +{ + config_set_tab_width(_config, width); +} + +// --------------------------------------------------------------------------- + +unsigned short Config::getTabWidth() const +{ + return(config_get_tab_width(_config)); +} + +// --------------------------------------------------------------------------- + +void Config::setFloatPrecision(unsigned short digits) +{ + return (config_set_float_precision(_config,digits)); +} + +// --------------------------------------------------------------------------- + +unsigned short Config::getFloatPrecision() const +{ + return (config_get_float_precision(_config)); +} + +// --------------------------------------------------------------------------- + +void Config::setIncludeDir(const char *includeDir) +{ + config_set_include_dir(_config, includeDir); +} + +// --------------------------------------------------------------------------- + +const char *Config::getIncludeDir() const +{ + return(config_get_include_dir(_config)); +} + +// --------------------------------------------------------------------------- + +const char **Config::evaluateIncludePath(const char *path, const char **error) +{ + return(config_default_include_func(_config, getIncludeDir(), path, error)); +} + +// --------------------------------------------------------------------------- + +void Config::handleError() const +{ + switch(config_error_type(_config)) + { + case CONFIG_ERR_NONE: + break; + + case CONFIG_ERR_PARSE: + throw ParseException(config_error_file(_config), + config_error_line(_config), + config_error_text(_config)); + break; + + case CONFIG_ERR_FILE_IO: + default: + throw FileIOException(); + } +} + +// --------------------------------------------------------------------------- + +void Config::read(FILE *stream) +{ + if(! config_read(_config, stream)) + handleError(); +} + +// --------------------------------------------------------------------------- + +void Config::readString(const char *str) +{ + if(! config_read_string(_config, str)) + handleError(); +} + +// --------------------------------------------------------------------------- + +void Config::write(FILE *stream) const +{ + config_write(_config, stream); +} + +// --------------------------------------------------------------------------- + +void Config::readFile(const char *filename) +{ + if(! config_read_file(_config, filename)) + handleError(); +} + +// --------------------------------------------------------------------------- + +void Config::writeFile(const char *filename) +{ + if(! config_write_file(_config, filename)) + handleError(); +} + +// --------------------------------------------------------------------------- + +Setting & Config::lookup(const char *path) const +{ + config_setting_t *s = config_lookup(_config, path); + if(! s) + throw SettingNotFoundException(path); + + return(Setting::wrapSetting(s)); +} + +// --------------------------------------------------------------------------- + +bool Config::exists(const char *path) const +{ + config_setting_t *s = config_lookup(_config, path); + + return(s != NULL); +} + +// --------------------------------------------------------------------------- + +#define CONFIG_LOOKUP_NO_EXCEPTIONS(P, T, V) \ + try \ + { \ + Setting &s = lookup(P); \ + V = (T)s; \ + return(true); \ + } \ + catch(const ConfigException &) \ + { \ + return(false); \ + } + +// --------------------------------------------------------------------------- + +bool Config::lookupValue(const char *path, bool &value) const +{ + CONFIG_LOOKUP_NO_EXCEPTIONS(path, bool, value); +} + +// --------------------------------------------------------------------------- + +bool Config::lookupValue(const char *path, int &value) const +{ + CONFIG_LOOKUP_NO_EXCEPTIONS(path, int, value); +} + +// --------------------------------------------------------------------------- + +bool Config::lookupValue(const char *path, unsigned int &value) const +{ + CONFIG_LOOKUP_NO_EXCEPTIONS(path, unsigned int, value); +} + +// --------------------------------------------------------------------------- + +bool Config::lookupValue(const char *path, long long &value) const +{ + CONFIG_LOOKUP_NO_EXCEPTIONS(path, long long, value); +} + +// --------------------------------------------------------------------------- + +bool Config::lookupValue(const char *path, unsigned long long &value) const +{ + CONFIG_LOOKUP_NO_EXCEPTIONS(path, unsigned long long, value); +} + +// --------------------------------------------------------------------------- + +bool Config::lookupValue(const char *path, double &value) const +{ + CONFIG_LOOKUP_NO_EXCEPTIONS(path, double, value); +} + +// --------------------------------------------------------------------------- + +bool Config::lookupValue(const char *path, float &value) const +{ + CONFIG_LOOKUP_NO_EXCEPTIONS(path, float, value); +} + +// --------------------------------------------------------------------------- + +bool Config::lookupValue(const char *path, const char *&value) const +{ + CONFIG_LOOKUP_NO_EXCEPTIONS(path, const char *, value); +} + +// --------------------------------------------------------------------------- + +bool Config::lookupValue(const char *path, std::string &value) const +{ + CONFIG_LOOKUP_NO_EXCEPTIONS(path, const char *, value); +} + +// --------------------------------------------------------------------------- + +Setting & Config::getRoot() const +{ + return(Setting::wrapSetting(config_root_setting(_config))); +} + +// --------------------------------------------------------------------------- + +Setting::Setting(config_setting_t *setting) + : _setting(setting) +{ + switch(config_setting_type(setting)) + { + case CONFIG_TYPE_GROUP: + _type = TypeGroup; + break; + + case CONFIG_TYPE_INT: + _type = TypeInt; + break; + + case CONFIG_TYPE_INT64: + _type = TypeInt64; + break; + + case CONFIG_TYPE_FLOAT: + _type = TypeFloat; + break; + + case CONFIG_TYPE_STRING: + _type = TypeString; + break; + + case CONFIG_TYPE_BOOL: + _type = TypeBoolean; + break; + + case CONFIG_TYPE_ARRAY: + _type = TypeArray; + break; + + case CONFIG_TYPE_LIST: + _type = TypeList; + break; + + case CONFIG_TYPE_NONE: + default: + _type = TypeNone; + break; + } + + switch(config_setting_get_format(setting)) + { + case CONFIG_FORMAT_HEX: + _format = FormatHex; + break; + + case CONFIG_FORMAT_DEFAULT: + default: + _format = FormatDefault; + break; + } +} + +// --------------------------------------------------------------------------- + +Setting::~Setting() +{ + _setting = NULL; +} + +// --------------------------------------------------------------------------- + +void Setting::setFormat(Format format) +{ + if((_type == TypeInt) || (_type == TypeInt64)) + { + if(format == FormatHex) + _format = FormatHex; + else + _format = FormatDefault; + } + else + _format = FormatDefault; + + config_setting_set_format(_setting, static_cast<short>(_format)); +} + +// --------------------------------------------------------------------------- + +Setting::operator bool() const +{ + assertType(TypeBoolean); + + return(config_setting_get_bool(_setting) ? true : false); +} + +// --------------------------------------------------------------------------- + +Setting::operator int() const +{ + assertType(TypeInt); + + return(config_setting_get_int(_setting)); +} + +// --------------------------------------------------------------------------- + +Setting::operator unsigned int() const +{ + assertType(TypeInt); + + int v = config_setting_get_int(_setting); + + return(static_cast<unsigned int>(v)); +} + +// --------------------------------------------------------------------------- + +Setting::operator long() const +{ + if(sizeof(long) == sizeof(long long)) + return operator long long(); + else + return operator int(); +} + +// --------------------------------------------------------------------------- + +Setting::operator unsigned long() const +{ + if(sizeof(long) == sizeof(long long)) + return operator unsigned long long(); + else + return operator unsigned int(); +} + +// --------------------------------------------------------------------------- + +Setting::operator long long() const +{ + assertType(TypeInt64); + + return(config_setting_get_int64(_setting)); +} + +// --------------------------------------------------------------------------- + +Setting::operator unsigned long long() const +{ + assertType(TypeInt64); + + long long v = config_setting_get_int64(_setting); + + return(static_cast<unsigned long long>(v)); +} + +// --------------------------------------------------------------------------- + +Setting::operator double() const +{ + assertType(TypeFloat); + + return(config_setting_get_float(_setting)); +} + +// --------------------------------------------------------------------------- + +Setting::operator float() const +{ + assertType(TypeFloat); + + // may cause loss of precision: + return(static_cast<float>(config_setting_get_float(_setting))); +} + +// --------------------------------------------------------------------------- + +Setting::operator const char *() const +{ + assertType(TypeString); + + return(config_setting_get_string(_setting)); +} + +// --------------------------------------------------------------------------- + +Setting::operator std::string() const +{ + assertType(TypeString); + + const char *s = config_setting_get_string(_setting); + + std::string str; + if(s) + str = s; + + return(str); +} + +// --------------------------------------------------------------------------- + +Setting & Setting::operator=(bool value) +{ + assertType(TypeBoolean); + + config_setting_set_bool(_setting, value); + + return(*this); +} + +// --------------------------------------------------------------------------- + +Setting & Setting::operator=(int value) +{ + assertType(TypeInt); + + config_setting_set_int(_setting, value); + + return(*this); +} + +// --------------------------------------------------------------------------- + +Setting & Setting::operator=(long value) +{ + if(sizeof(long) == sizeof(long long)) + return(operator=(static_cast<long long>(value))); + else + return(operator=(static_cast<int>(value))); +} + +// --------------------------------------------------------------------------- + +Setting & Setting::operator=(const long long &value) +{ + assertType(TypeInt64); + + config_setting_set_int64(_setting, value); + + return(*this); +} + +// --------------------------------------------------------------------------- + +Setting & Setting::operator=(const double &value) +{ + assertType(TypeFloat); + + config_setting_set_float(_setting, value); + + return(*this); +} + +// --------------------------------------------------------------------------- + +Setting & Setting::operator=(float value) +{ + assertType(TypeFloat); + + double cvalue = static_cast<double>(value); + + config_setting_set_float(_setting, cvalue); + + return(*this); +} + +// --------------------------------------------------------------------------- + +Setting & Setting::operator=(const char *value) +{ + assertType(TypeString); + + config_setting_set_string(_setting, value); + + return(*this); +} + +// --------------------------------------------------------------------------- + +Setting & Setting::operator=(const std::string &value) +{ + assertType(TypeString); + + config_setting_set_string(_setting, value.c_str()); + + return(*this); +} + +// --------------------------------------------------------------------------- + +Setting & Setting::lookup(const char *path) const +{ + assertType(TypeGroup); + + config_setting_t *setting = config_setting_lookup(_setting, path); + + if(! setting) + throw SettingNotFoundException(*this, path); + + return(wrapSetting(setting)); +} + +// --------------------------------------------------------------------------- + +Setting & Setting::operator[](const char *name) const +{ + assertType(TypeGroup); + + config_setting_t *setting = config_setting_get_member(_setting, name); + + if(! setting) + throw SettingNotFoundException(*this, name); + + return(wrapSetting(setting)); +} + +// --------------------------------------------------------------------------- + +Setting & Setting::operator[](int i) const +{ + if((_type != TypeArray) && (_type != TypeGroup) && (_type != TypeList)) + throw SettingTypeException(*this, i); + + config_setting_t *setting = config_setting_get_elem(_setting, i); + + if(! setting) + throw SettingNotFoundException(*this, i); + + return(wrapSetting(setting)); +} + +// --------------------------------------------------------------------------- + +#define SETTING_LOOKUP_NO_EXCEPTIONS(K, T, V) \ + try \ + { \ + Setting &s = operator[](K); \ + V = (T)s; \ + return(true); \ + } \ + catch(const ConfigException &) \ + { \ + return(false); \ + } + +// --------------------------------------------------------------------------- + +bool Setting::lookupValue(const char *name, bool &value) const +{ + SETTING_LOOKUP_NO_EXCEPTIONS(name, bool, value); +} + +// --------------------------------------------------------------------------- + +bool Setting::lookupValue(const char *name, int &value) const +{ + SETTING_LOOKUP_NO_EXCEPTIONS(name, int, value); +} + +// --------------------------------------------------------------------------- + +bool Setting::lookupValue(const char *name, unsigned int &value) const +{ + SETTING_LOOKUP_NO_EXCEPTIONS(name, unsigned int, value); +} + +// --------------------------------------------------------------------------- + +bool Setting::lookupValue(const char *name, long long &value) const +{ + SETTING_LOOKUP_NO_EXCEPTIONS(name, long long, value); +} + +// --------------------------------------------------------------------------- + +bool Setting::lookupValue(const char *name, unsigned long long &value) const +{ + SETTING_LOOKUP_NO_EXCEPTIONS(name, unsigned long long, value); +} + +// --------------------------------------------------------------------------- + +bool Setting::lookupValue(const char *name, double &value) const +{ + SETTING_LOOKUP_NO_EXCEPTIONS(name, double, value); +} + +// --------------------------------------------------------------------------- + +bool Setting::lookupValue(const char *name, float &value) const +{ + SETTING_LOOKUP_NO_EXCEPTIONS(name, float, value); +} + +// --------------------------------------------------------------------------- + +bool Setting::lookupValue(const char *name, const char *&value) const +{ + SETTING_LOOKUP_NO_EXCEPTIONS(name, const char *, value); +} + +// --------------------------------------------------------------------------- + +bool Setting::lookupValue(const char *name, std::string &value) const +{ + SETTING_LOOKUP_NO_EXCEPTIONS(name, const char *, value); +} + +// --------------------------------------------------------------------------- + +bool Setting::exists(const char *name) const +{ + if(_type != TypeGroup) + return(false); + + config_setting_t *setting = config_setting_get_member(_setting, name); + + return(setting != NULL); +} + +// --------------------------------------------------------------------------- + +int Setting::getLength() const +{ + return(config_setting_length(_setting)); +} + +// --------------------------------------------------------------------------- + +const char * Setting::getName() const +{ + return(config_setting_name(_setting)); +} + +// --------------------------------------------------------------------------- + +std::string Setting::getPath() const +{ + std::stringstream path; + + __constructPath(*this, path); + + return(path.str()); +} + +// --------------------------------------------------------------------------- + +const Setting & Setting::getParent() const +{ + config_setting_t *setting = config_setting_parent(_setting); + + if(! setting) + throw SettingNotFoundException(NULL); + + return(wrapSetting(setting)); +} + +// --------------------------------------------------------------------------- + +Setting & Setting::getParent() +{ + config_setting_t *setting = config_setting_parent(_setting); + + if(! setting) + throw SettingNotFoundException(NULL); + + return(wrapSetting(setting)); +} + +// --------------------------------------------------------------------------- + +unsigned int Setting::getSourceLine() const +{ + return(config_setting_source_line(_setting)); +} + +// --------------------------------------------------------------------------- + +const char *Setting::getSourceFile() const +{ + return(config_setting_source_file(_setting)); +} + +// --------------------------------------------------------------------------- + +bool Setting::isRoot() const +{ + return(config_setting_is_root(_setting)); +} + +// --------------------------------------------------------------------------- + +int Setting::getIndex() const +{ + return(config_setting_index(_setting)); +} + +// --------------------------------------------------------------------------- + +void Setting::remove(const char *name) +{ + assertType(TypeGroup); + + if(! config_setting_remove(_setting, name)) + throw SettingNotFoundException(*this, name); +} + +// --------------------------------------------------------------------------- + +void Setting::remove(unsigned int idx) +{ + if((_type != TypeArray) && (_type != TypeGroup) && (_type != TypeList)) + throw SettingTypeException(*this, idx); + + if(! config_setting_remove_elem(_setting, idx)) + throw SettingNotFoundException(*this, idx); +} + +// --------------------------------------------------------------------------- + +Setting & Setting::add(const char *name, Setting::Type type) +{ + assertType(TypeGroup); + + int typecode = __toTypeCode(type); + + if(typecode == CONFIG_TYPE_NONE) + throw SettingTypeException(*this, name); + + config_setting_t *setting = config_setting_add(_setting, name, typecode); + + if(! setting) + throw SettingNameException(*this, name); + + return(wrapSetting(setting)); +} + +// --------------------------------------------------------------------------- + +Setting & Setting::add(Setting::Type type) +{ + if((_type != TypeArray) && (_type != TypeList)) + throw SettingTypeException(*this); + + if(_type == TypeArray) + { + int idx = getLength(); + + if(idx > 0) + { + Setting::Type atype = operator[](0).getType(); + if(type != atype) + throw SettingTypeException(*this, idx); + } + else + { + if((type != TypeInt) && (type != TypeInt64) && (type != TypeFloat) + && (type != TypeString) && (type != TypeBoolean)) + throw SettingTypeException(*this, idx); + } + } + + int typecode = __toTypeCode(type); + config_setting_t *s = config_setting_add(_setting, NULL, typecode); + + Setting &ns = wrapSetting(s); + + switch(type) + { + case TypeInt: + ns = 0; + break; + + case TypeInt64: + ns = INT64_CONST(0); + break; + + case TypeFloat: + ns = 0.0; + break; + + case TypeString: + ns = (char *)NULL; + break; + + case TypeBoolean: + ns = false; + break; + + default: + // won't happen + break; + } + + return(ns); +} + +// --------------------------------------------------------------------------- + +void Setting::assertType(Setting::Type type) const +{ + if(type != _type) + { + if(!(isNumber() && config_get_auto_convert(_setting->config) + && ((type == TypeInt) || (type == TypeInt64) || (type == TypeFloat)))) + throw SettingTypeException(*this); + } +} + +// --------------------------------------------------------------------------- + +Setting & Setting::wrapSetting(config_setting_t *s) +{ + Setting *setting = NULL; + + void *hook = config_setting_get_hook(s); + if(! hook) + { + setting = new Setting(s); + config_setting_set_hook(s, reinterpret_cast<void *>(setting)); + } + else + setting = reinterpret_cast<Setting *>(hook); + + return(*setting); +} + +// --------------------------------------------------------------------------- + +Setting::iterator Setting::begin() +{ return(iterator(*this)); } + +// --------------------------------------------------------------------------- + +Setting::iterator Setting::end() +{ return(iterator(*this, true)); } + +// --------------------------------------------------------------------------- + +Setting::const_iterator Setting::begin() const +{ return(const_iterator(*this)); } + +// --------------------------------------------------------------------------- + +Setting::const_iterator Setting::end() const +{ return(const_iterator(*this, true)); } + +// --------------------------------------------------------------------------- + +SettingIterator::SettingIterator(Setting& setting, bool endIterator) + : _setting(&setting), + _count(setting.getLength()), + _idx(endIterator ? _count : 0) +{ + if(!setting.isAggregate()) + throw SettingTypeException(setting); +} + +// --------------------------------------------------------------------------- + +SettingIterator::SettingIterator(const SettingIterator &other) + : _setting(other._setting), + _count(other._count), + _idx(other._idx) +{ +} + +// --------------------------------------------------------------------------- + +SettingIterator& SettingIterator::operator=(const SettingIterator &other) +{ + _setting = other._setting; + _count = other._count; + _idx = other._idx; + + return(*this); +} + +// --------------------------------------------------------------------------- + +SettingIterator& SettingIterator::operator++() +{ + ++_idx; + + return(*this); +} + +// --------------------------------------------------------------------------- + +SettingIterator SettingIterator::operator++(int) +{ + SettingIterator tmp(*this); + ++_idx; + + return(tmp); +} + +// --------------------------------------------------------------------------- + +SettingIterator& SettingIterator::operator--() +{ + --_idx; + + return(*this); +} + +// --------------------------------------------------------------------------- + +SettingIterator SettingIterator::operator--(int) +{ + SettingIterator tmp(*this); + --_idx; + + return(tmp); +} + +// --------------------------------------------------------------------------- + +SettingIterator SettingIterator::operator+(int offset) const +{ + SettingIterator copy(*this); + copy += offset; + + return(copy); +} + +// --------------------------------------------------------------------------- + +SettingIterator& SettingIterator::operator+=(int offset) +{ + _idx += offset; + + return(*this); +} + +// --------------------------------------------------------------------------- + +SettingIterator operator+(int offset, SettingIterator& si) +{ + SettingIterator copy(si); + copy += offset; + + return(copy); +} + +// --------------------------------------------------------------------------- + +SettingIterator SettingIterator::operator-(int offset) const +{ + SettingIterator copy(*this); + copy._idx -= offset; + + return(copy); +} + +// --------------------------------------------------------------------------- + +SettingIterator& SettingIterator::operator-=(int offset) +{ + _idx -= offset; + + return(*this); +} + +// --------------------------------------------------------------------------- + +int SettingIterator::operator-(SettingIterator const &other) const +{ + return(_idx - other._idx); +} + +// --------------------------------------------------------------------------- + +SettingConstIterator::SettingConstIterator(const Setting &setting, + bool endIterator) + : _setting(&setting), + _count(setting.getLength()), + _idx(endIterator ? _count : 0) +{ + if(!setting.isAggregate()) + throw SettingTypeException(setting); +} + +// --------------------------------------------------------------------------- + +SettingConstIterator::SettingConstIterator(const SettingConstIterator &other) + : _setting(other._setting), + _count(other._count), + _idx(other._idx) +{ +} + +// --------------------------------------------------------------------------- + +SettingConstIterator& SettingConstIterator::operator=( + const SettingConstIterator &other) +{ + _setting = other._setting; + _count = other._count; + _idx = other._idx; + return(*this); +} + +// --------------------------------------------------------------------------- + +SettingConstIterator& SettingConstIterator::operator++() +{ + ++_idx; + + return(*this); +} + +// --------------------------------------------------------------------------- + +SettingConstIterator SettingConstIterator::operator++(int) +{ + SettingConstIterator tmp(*this); + ++_idx; + + return(tmp); +} + +// --------------------------------------------------------------------------- + +SettingConstIterator& SettingConstIterator::operator--() +{ + --_idx; + + return(*this); +} + +// --------------------------------------------------------------------------- + +SettingConstIterator SettingConstIterator::operator--(int) +{ + SettingConstIterator tmp(*this); + --_idx; + + return(tmp); +} + +// --------------------------------------------------------------------------- + +SettingConstIterator SettingConstIterator::operator+(int offset) const +{ + SettingConstIterator copy(*this); + copy += offset; + + return(copy); +} + +// --------------------------------------------------------------------------- + +SettingConstIterator& SettingConstIterator::operator+=(int offset) +{ + _idx += offset; + + return(*this); +} + +// --------------------------------------------------------------------------- + +SettingConstIterator operator+(int offset, SettingConstIterator &si) +{ + SettingConstIterator copy(si); + copy += offset; + + return(copy); +} + +// --------------------------------------------------------------------------- + +SettingConstIterator SettingConstIterator::operator-(int offset) const +{ + SettingConstIterator copy(*this); + copy -= offset; + + return(copy); +} + +// --------------------------------------------------------------------------- + +SettingConstIterator& SettingConstIterator::operator-=(int offset) +{ + _idx -= offset; + + return(*this); +} + +// --------------------------------------------------------------------------- + +int SettingConstIterator::operator-(SettingConstIterator const &other) const +{ + return(_idx - other._idx); +} + + +} // namespace libconfig + |