+/** Types of data in the core config
+ */
+enum ConfigDataType
+{
+ DT_NOTHING = 0, /* No data */
+ DT_INTEGER = 1, /* Integer */
+ DT_CHARPTR = 2, /* Char pointer */
+ DT_BOOLEAN = 3, /* Boolean */
+ DT_HOSTNAME = 4, /* Hostname syntax */
+ DT_NOSPACES = 5, /* No spaces */
+ DT_IPADDRESS = 6, /* IP address (v4, v6) */
+ DT_CHANNEL = 7, /* Channel name */
+ DT_LIMIT = 8, /* size_t */
+ DT_ALLOW_WILD = 64, /* Allow wildcards/CIDR in DT_IPADDRESS */
+ DT_ALLOW_NEWLINE = 128 /* New line characters allowed in DT_CHARPTR */
+};
+
+/** The maximum number of values in a core configuration tag. Can be increased if needed.
+ */
+#define MAX_VALUES_PER_TAG 18
+
+/** Holds a config value, either string, integer or boolean.
+ * Callback functions receive one or more of these, either on
+ * their own as a reference, or in a reference to a deque of them.
+ * The callback function can then alter the values of the ValueItem
+ * classes to validate the settings.
+ */
+class ValueItem
+{
+ /** Actual data */
+ std::string v;
+ public:
+ /** Initialize with an int */
+ ValueItem(int value);
+ /** Initialize with a bool */
+ ValueItem(bool value);
+ /** Initialize with a string */
+ ValueItem(const char* value) : v(value) { }
+ /** Change value to a string */
+ void Set(const std::string &val);
+ /** Change value to an int */
+ void Set(int value);
+ /** Get value as an int */
+ int GetInteger();
+ /** Get value as a string */
+ const char* GetString() const;
+ /** Get value as a string */
+ inline const std::string& GetValue() const { return v; }
+ /** Get value as a bool */
+ bool GetBool();
+};
+
+/** The base class of the container 'ValueContainer'
+ * used internally by the core to hold core values.
+ */
+class ValueContainerBase
+{
+ public:
+ /** Constructor */
+ ValueContainerBase() { }
+ /** Destructor */
+ virtual ~ValueContainerBase() { }
+};
+
+/** ValueContainer is used to contain pointers to different
+ * core values such as the server name, maximum number of
+ * clients etc.
+ * It is specialized to hold a data type, then pointed at
+ * a value in the ServerConfig class. When the value has been
+ * read and validated, the Set method is called to write the
+ * value safely in a type-safe manner.
+ */
+template<typename T> class ValueContainer : public ValueContainerBase
+{
+ T ServerConfig::* const vptr;
+ public:
+ /** Initialize with a value of type T */
+ ValueContainer(T ServerConfig::* const offset) : vptr(offset)
+ {
+ }
+
+ /** Change value to type T of size s */
+ void Set(ServerConfig* conf, const T& value)
+ {
+ conf->*vptr = value;
+ }
+
+ void Set(ServerConfig* conf, const ValueItem& item);
+};
+
+class ValueContainerLimit : public ValueContainerBase
+{
+ size_t ServerLimits::* const vptr;
+ public:
+ /** Initialize with a value of type T */
+ ValueContainerLimit(size_t ServerLimits::* const offset) : vptr(offset)
+ {
+ }
+
+ /** Change value to type T of size s */
+ void Set(ServerConfig* conf, const size_t& value)
+ {
+ conf->Limits.*vptr = value;
+ }
+};
+
+/** A specialization of ValueContainer to hold a pointer to a bool
+ */
+typedef ValueContainer<bool> ValueContainerBool;
+
+/** A specialization of ValueContainer to hold a pointer to
+ * an unsigned int
+ */
+typedef ValueContainer<unsigned int> ValueContainerUInt;
+
+/** A specialization of ValueContainer to hold a pointer to
+ * a char array.
+ */
+typedef ValueContainer<std::string> ValueContainerString;
+
+/** A specialization of ValueContainer to hold a pointer to
+ * an int
+ */
+typedef ValueContainer<int> ValueContainerInt;
+
+/** A set of ValueItems used by multi-value validator functions
+ */
+typedef std::deque<ValueItem> ValueList;
+
+/** A callback for validating a single value
+ */
+typedef bool (*Validator)(ServerConfig* conf, const char*, const char*, ValueItem&);
+/** A callback for validating multiple value entries
+ */
+typedef bool (*MultiValidator)(ServerConfig* conf, const char*, const char**, ValueList&, int*);
+/** A callback indicating the end of a group of entries
+ */
+typedef bool (*MultiNotify)(ServerConfig* conf, const char*);
+
+/** Holds a core configuration item and its callbacks
+ */
+struct InitialConfig
+{
+ /** Tag name */
+ const char* tag;
+ /** Value name */
+ const char* value;
+ /** Default, if not defined */
+ const char* default_value;
+ /** Value containers */
+ ValueContainerBase* val;
+ /** Data types */
+ int datatype;
+ /** Validation function */
+ Validator validation_function;
+};
+
+/** Represents a deprecated configuration tag.
+ */
+struct Deprecated
+{
+ /** Tag name
+ */
+ const char* tag;
+ /** Tag value
+ */
+ const char* value;
+ /** Reason for deprecation
+ */
+ const char* reason;
+};
+
+/** Holds a core configuration item and its callbacks
+ * where there may be more than one item
+ */
+struct MultiConfig
+{
+ /** Tag name */
+ const char* tag;
+ /** One or more items within tag */
+ const char* items[MAX_VALUES_PER_TAG];
+ /** One or more defaults for items within tags */
+ const char* items_default[MAX_VALUES_PER_TAG];
+ /** One or more data types */
+ int datatype[MAX_VALUES_PER_TAG];
+ /** Validation function */
+ MultiValidator validation_function;
+};