# Config

The config library supports Apps to store configuration options in a config database table. To access the config options from within a JavaScript App, the C++ config library communicates with the JavaScript config library using JSON messages. See the JS config library documentation for more informations.

The usage of the config library is straight forward and only needs a couple of steps:

- Create instance of ConfigContext.
- Register the config library to the JSON API framework by passing the created instance to RegisterJsonApi(configContextInstance).
- Create the database table used by the config lib by calling CreateInitTask(databaseObject) and exetuting the returned task (don't forget to free it, after the task is finished).
- Add ConfigItem members to your class and initialize them passing the ConfigContext instance (see the description of the ConfigItems classes below).

Now the appliction service and the JavaScript app only need to access the items or changed and save them (especially from the JavaScript side). ConfigContext and the JavaScript config library are handling all of the communication, so there is no need for an app to worry about that.

## File information

File | common/interface/config.h
Classes | ConfigContext ConfigItem ConfigChoice ConfigBool ConfigInt ConfigDword ConfigLong64 ConfigUlong64 ConfigString
JSON messages | Base message GetConfigItems GetConfigItemsResult ReadConfig ReadConfigResult ConfigUpdate WriteConfig WriteConfigResult
Examples | ConfigContext Using config First steps

# Classes

## ConfigContext

    class ConfigContext : public UTask, public UJsonApiContext, public UConfigContextApi {
    protected:
        virtual void ConfigChanged() {}
        virtual void ConfigChangedUnmanaged() {}
        virtual bool CanReadConfig(IJsonApiConnection * const connection) { return true; }
        virtual bool CanWriteConfig(IJsonApiConnection * const connection) { return true; }
        class ITask * UpdateUnmanagedItems();
        class ITask * UpdateManagedItems();

    public:
        ConfigContext(class IDatabase * database, class IInstanceLog * log);
        virtual ~ConfigContext();

        bool SwitchToFileMode(class IIoMux * iomux, const char * absoluteFileName, bool initFromDatabase = false);
        void SwitchToDatabaseMode();

        class ITask * CreateInitTask(class IDatabase * database = nullptr, bool readOnly = false);
        void ResetChangedFlag();
        class ITask * WriteItemValue(ConfigItem * item, const char * value, bool notify);
    };

### Overview

The ConfigContext is the base class of the config library. It handles the communication with the database as well as with the JSON API framework. An application only needs to create an instance of ConfigContext and initialize it. To initialize, the instance must be passed to to RegisterJsonApi() of an existing JsonApiContext instance and the database must be initialized by executing the task returned by CreateInitTask(). Even if not necessary it is recommended to create a subclass of ConfigContext to store the config items into that subclass, too. This makes handling and initializing the config items easier as well as get informed after changes made for the config items.
The ConfigContext stores the configuration inside the database accassable through the given database connection. When initializing running the task to do so, a table called config will be created with three rows:

- name The name of the config item with a maximum length of 255 chars.
- value The vlaue of the config item. Each item is stored as string with an (in theory) unlimited length. But be aware that each item will stay resident in RAM, so take care to not hold values to big.
- unmanaged A boolean value to describe if the item is unmanaged or not.

Note that only items will be written to the database, that have a different value than given as the default value. Even if an item had ben changed and set back to the default value, it is no longer written to the database.
Each config item will be registered to a ConfigContext instance and managed by that instance. That also means that each config item must have a unique name. See the description of ConfigItem classes below for more details.

### Protected functions

ConfigChanged
  Will be called after the value of a config item had been changed. Create a class derived from ConfigContext to catch that callback.
ConfigChangedUnmanaged
  Will be called after the value of an unmanaged config item had been changed. An unmanaged config item can only be accessed by the C++ side of the library, but not by the JSON API. So on the JSON API side, that item is read-only. Create a class derived from ConfigContext to catch that callback.
CanReadConfig
  Will be called to check, if a given IJsonApiConnection instance has the right to read the config. Create a class derived from ConfigContext and overwrite the function to add rights management for reading the config.

  #### Parameters

  class IJsonApiConnection * const connection | The IJsonApiConnection instance to be checked for the right to read the config.

  #### Return value

  True, if the given connection has the right to read the config. So if true is returned, ConfigContext will send config informations to the connection that asks for them. False, to deny the access to the config. The default implementation of ConfigContext::CanReadConfig() always returns true.
CanWriteConfig
  Will be called to check, if a given IJsonApiConnection instance has the right to write the config. Create a class derived from ConfigContext and overwrite the function to add rights management for writing the config.

  #### Parameters

  class IJsonApiConnection * const connection | The IJsonApiConnection instance to be checked for the right to write the config.

  #### Return value

  True, if the given connection has the right to write the config. So if true is returned, ConfigContext will accept changed config values send via JSON API messages and write them to the database. False, to deny the access to the config. The default implementation of ConfigContext::CanWriteConfig() always returns true.

### Public functions

ConfigContext (Constructor)
  The constructor of the class.

  #### Parameters

  class IDatabase * database | The IDatabase instance to be used by the config context.
  class IInstanceLog * const log | The IInstanceLog instance used for loging purposes.

SwitchToFileMode
  In standard mode the config library writes values to the database config table. After calling this function, changes are written to a file instead.
  The task created with CreateInitTask will also read from this config file and not from the database anymore.

  #### Parameters

  class IIoMux * iomux | The IIoMux instance to be used.
  const char * absoluteFileName | The absolute path and filename in which the config will be stored.
  bool initFromDatabase | (Default: false) Set true if the config file shall be created at once and initialized with the current database values.

  #### Return value

  True if the file can be created and written. Otherwise false.
SwitchToDatabaseMode
  Switches back to database mode. If you want the current values to be written into the database, you must use UpdateManagedItems and/or UpdateUnmanagedItems.

  #### Parameters

  #### Return value

CreateInitTask
  Creates an instance of the task to initialize the database table used by the config context.

  #### Parameters

  class IDatabase * database | (Default: nullptr) The IDatabase instance to be used. If nullptr, the instance passed to the constructor will be used.
  bool readOnly | (Default: false) Set true if the config table is read only (in standby scenarios).

  #### Return value

  The task that must be executed to initialize the config table. Simply call Start(class UTask * user) of that task, passing a user of your choice to that function. Make sure to provide a user parameter. The function Start() without any parameter should not be used.

  #### Remarks

  Note that the created ITask instance returned by CreateInitTask() must be freed after the task has finished or failed. If not, the application will create memory leaks.
ResetChangedFlag
  This will reset the changed flag of all items. After calling that, Changed() of each ConfigItem registered to ConfigContext will return false. It will be a good Idea to call that function in ConfigChanged() and / or ConfigChangedUnmanaged() after handling all changes.
WriteItemValue
  Call this function to write a config item to the database. Generally this will be done when items had been changed through the JSON API. But in case of unmanaged items, this function is the only way to save them.

  #### Parameters

  ConfigItem * item | The config item to write to the database.
  const char * value | The value to write.
  bool notify | If true, a changed notification will be send to all open JsonApoContext instances.

## ConfigItem

    class ConfigItem : public istd::listElement {
    private:
        char * name;

    protected:
        friend class TaskWriteConfig;
        friend class TaskWriteConfigUnmanaged;
        friend class TaskInitConfig;
        friend class ConfigContext;

        class IInstanceLog * const log;
        bool changed;
        bool unmanaged;

        virtual void ReadValueFromDataset(class IDataSet * dataset) = 0;
        virtual void ReadValueFromJSON(class json_io * json, dword base, class IJsonApiConnection * connection) = 0;
        virtual void WriteValueToJSON(class json_io * json, dword base, char * & convBuf, class IJsonApiConnection * connection) = 0;
        virtual int WriteValueToString(char * dest) = 0;
        virtual void SetWriteValue(const char * value) = 0;
        virtual void WriteItemTypeToJSON(class json_io * json, dword base, char * & convBuf) = 0;

    public:
        ConfigItem(ConfigContext * context, const char * name, bool unmanaged);
        virtual ~ConfigItem();

        const char * GetName() const { return this->name; }
        bool Changed() const { return this->changed; }
        virtual bool HasDefaultValue() = 0;
        virtual void Reset() = 0;
    };

### Overview

This is the base class for each config item. Generally there is no need to create an own config item, because the config library provides config items for the most use cases. But if there is need, an own config item must be derived from ConfigItem. Also, because of the internals, ConfigContext must be a friend class for the new config item as well (the other classes don't need to, that's only used internally for the ConfigItem base class).
If an app whants to create an own config item class, it needs to provide one of the default data types to ConfigContext anyway. If not, the result of handling that item on the JSON API side is undefined. Types supported by the ConfigContext are:

- 32bit integers (singed and unsigned)
- 64bit integers (singed and unsigned - but take care with 64bit integers because of the not-that-good support of them on JavaScript).
- bool.
- string (with unlimited length).
- password (which is a string with a flag given on initialization to define it as password. Passwords can only be received from the JSON API and only in an encrypted way. ConfigContext will not send passwords. Instead an empty string for that items will be send).
- choice (which is a combination of an integer as index and a array with available choices).

### Remarks

Don't use ConfigItem direktly (however, because of the pure virutal functions the compiler don't let you do so). Use one of the pre defined ConfigItem subclasses (as described below) or implement your own to map the data type of your choice the one of the base data types using a subclass of ConfigItem.
When creating a subclass, each functions (except GetName() and Changed()) must be implemented by the subclass!

### Protected variables

bool changed
  Must be set from within the ReadValue* functions to show whether the value of the item had been changed or not.
bool unmanaged
  Defines whether the item is unmanaged or not. An unmanaged item cannot be accessed through the JSON API. It is recommended to not touch this value in an subclass and only set it using the constructor of ConfigItem.

### Protected functions

ReadValueFromDataset
  Will be called during loading the data from the database. An derived class should get the value from the "value" field of the dataset (by calling the datasets functions to get a value by field name, see IDataSet for details) and stores that to an internal variable in whatever datatype needed. Don't make a copy of the dataset pointer, because it will be released after all data had ben read from the database. There is no need to control the items name inside the dataset, because ConfigContext will determine the config item the current row in dataset is for by the config item name of that row.

  #### Parameters

  class IDataSet * dataset | The dataset instance holding the row responsible for the item.

  #### Remarks

  Never ever delete the given dataset, store the pointer for later use or call Next() or FetchNextRow() of the dataset instance, or everything will be screwed up!
ReadValueFromJSON
  Will be called during parsing a JSON received from the JSON API. The function need to get the value (depending on the type, see the JSON message description below) and store it into an internal variable. If the value differes from the previous value, the function must set the changed flag to true.
  A subclass of ConfigItem read the value of the datatype needed from the given json_io instance. It must check, if there is data for that item not not get undefined behaviour. The name for the field is the same as the one for the config value. Only choice type config items are a little bit different. See the JSON describtion below.

  #### Parameters

  class json_io * json | The json_io instance to read the config item value from.
  dword base | The base id inside the json to start reading the config item data.
  class IJsonApiConnection * const connection | The IJsonApiConnection instance that sent the data to write.

WriteValueToJSON
  When an JasonApiContext requests the configuration of an application through the JSON API, ConfigContext will call WriteValueToJSON for each config item. The function need to write their value to the given json_io instance by calling the propriate function for the value to write. The value should be written using the name of the config item as name for the JSON item to write which get be done using the GetName() function of ConfigItem (e. g. json->add_usnigned(base, this->GetName(), this->value, convBuf)). Config item that are type of choice item need also to store the choices to them. See the JSON message description below.

  #### Parameters

  class json_io * json | The json_io instance to write the config item value to.
  dword base | The base id inside the json to start writing the config item data.
  char * & convBuf | A pointer to a buffer used by json_io to convert numbers to strings. You only need it if number values need to be written to the json_io instance.
  class IJsonApiConnection * const connection | The IJsonApiConnection instance that requested the config.

WriteValueToString
  When writing the value to the database, ConfigContext needs it as string (because the values from the config items are stored as strings only to the database). So for each config item this function will be called so that the function can convert the value to write it into the given buffer (or copy it, if the value of the item is already in string format).

  #### Parameters

  char * dest | The destination buffer to write the value to as string. Dest can also be nullptr. In that case, the function only should return the length of the string that will be written to the buffer if given in dest.

  #### Return value

  The function must return the length of the string put to dest, also if dest nullptr.
WriteItemTypeToJSON
  The JavaScript config library requests all config items registeres to ConfigContext and needs to now what type there are. For this, ConfigContext calls WriteItemTypeToJSON. A ConfigItem subclass needs the following fields to the given json_io instance:
  - name The name of the config item. You can use ConfigItem::GetName() for this.
  - type The type of the config item wich must be one of the items listed below.
  - password This field must only be added (and then be added with the value true), if the item holds a string password value.
  - minVal (For integer types only) The minumum value the item can have.
  - maxVal (For integer types only) The maximum value the item can have.
  Type need to be one of the followin value (the names of defines for that type is given in brackets):
  - BOOL The item is a BOOl type (CFG_TYPE_BOOL)
  - INT The item is a signed 32bit integer type (CFG_TYPE_INT)
  - DWORD The item is an unsigned 32bit integer type (CFG_TYPE_DWORD)
  - LONG64 The item is a signed 64bit integer type (CFG_TYPE_LONG64)
  - ULONG64 The item is an unsigned 64bit integer type (CFG_TYPE_ULONG64)
  - STRING The item is a string type (CFG_TYPE_STRING)
  - CHOICE The item is a choice type (CFG_TYPE_CHOICE)

  #### Parameters

  class json_io * json | The json_io instance to write the config item type information.
  dword base | The base id inside the json to start writing the config item type information.
  char * & convBuf | A pointer to a buffer used by json_io to convert numbers to strings. You only need it if number values need to be written to the json_io instance.

### Public functions

ConfigItem (Constructor)
  The constructor of the class.

  #### Parameters

  ConfigContext * context | The ConfigContext instance the item itself will reigster to it.
  char * name | The name of the config item. Must be unique withing the given ConfigContext.
  bool unmanaged | If set to true, the item is unmanaged and with this not accassable through the JSON API.

GetName

  #### Return value

  Returns the name of the config item as passed to the constructor.
Changed

  #### Return value

  Returns ture, if the item had been changed the last time the config items had been saved using the JSON API. The only good place to call that function will be within ConfigContext::ConfigChanged() and ConfigContext::ConfigChangedUnmanaged() to figure out, wich item actually had been changed and maybe nead to lead to additional updates inside the application.
HasDefaultValue

  #### Return value

  Returns true, if the current value of the item equals the default value given on creation, else false.

  #### Remarks

  ConfigItem itself doesn't have handlig of default value, so it need to be implemented from a subclass.
Reset
  Resets the config item and set the value to the default value. Must be implemented by a subclass.

## ConfigChoice

    class ConfigChoice : public ConfigItem {
    public:
        ConfigChoice(ConfigContext * context, const char * name, size_t defVal, const char ** options, bool unmanaged = false);
        virtual ~ConfigChoice();

        int ValueIdx() const { return this->valueIdx; }
        const char * Value() const { return (this->valueIdx < this->optionsCount ? this->choiceValues[this->valueIdx] : nullptr); }
        void SetValue(const char * option);
        void SetValueIdx(size_t valudIdx);
        bool HasDefaultValue() override;
        void Reset() override;
    };

### Overview

This config item is for providing a couple of available options and selecting one of them (that can be used e. g. for setting the language for an UI). The choice options will be passes as an array of string (terminated by a nullptr entry), while the choice itself represents the index inside that array. However, ConfigChoice will write the choice itself to the database instead of the index. So if there need to localize the options, the application needs to provide some kind of mapping. Using the options in a way to show them directly inside a UI is not the best idea.

### Public functions

ConfigChoice (Constructor)
  The constructor of the class.

  #### Parameters

  ConfigContext * context | The ConfigContext instance the item itself will reigster to it.
  char * name | The name of the config item. Must be unique withing the given ConfigContext.
  size_t defVal | The index of the default value inside the given options array.
  const char ** options | The options proivided by an array of char pointers terminated by a nullptr entry. ConfigOptions won't copy that array, so it should be guaranteed that this array exists over the lifetime of the COnfigOptions instance.
  bool unmanaged | (Default false) If set to true, the item is unmanaged and with this not accassable through the JSON API.

ValueIdx

  #### Return value

  Returns the index of the currently selected option.
Value

  #### Return value

  Returns the value of the current selected options. This will be the same as options[ConfigItem::ValuedIdx()].

  #### Remarks

  If the current value index is out of range of the options array, nullptr will be returned.
SetValue
  Set the current value of ConfigItem by passing a string that also is inside the options array. Calling this function will internally set the value index to the correct value. If the given option cannot be found, the internal value index will be set to 0.

  #### Parameters

  const char * option | The option to set. Must be inside the options array passed to the constructor of ConfigChoice.

  #### Remarks

  SetValue() can only be called for items with unmanaged flag set to true. Everything else will lead to an assertion.
  Note that this won't affect the internal changed flag.
  You also should take care the case of the given string, because SetValue() will make a case sensitive compare to each string inside the options array.
SetValueIdx
  Will set the internal index to the given value. If the given value is out of range, the internal index will set to 0.

  #### Parameters

  size_t valueIdx | The new index to set.

  #### Remarks

  SetValueIdx() can only be called for items with unmanaged flag set to true. Everything else will lead to an assertion.
  Note that this won't affect the internal changed flag.
HasDefaultValue

  #### Return value

  Returns true, if the current value of the item equals the default value given on creation, else false.
Reset
  Resets the config item and set the value to the default value.

## ConfigBool

    class ConfigBool : public ConfigItem {
    public:
        ConfigBool(ConfigContext * context, const char * name, bool defVal, bool unmanaged = false);
        virtual ~ConfigBool();

        bool Value() const { return this->value; }
        void SetValue(bool value);
        bool HasDefaultValue() override;
        void Reset() override;
    };

### Overview

This config item will store a simple boolean value.

### Public functions

ConfigBool (Constructor)
  The constructor of the class.

  #### Parameters

  ConfigContext * context | The ConfigContext instance the item itself will reigster to it.
  char * name | The name of the config item. Must be unique withing the given ConfigContext.
  bool defVal | The default value for the item.
  bool unmanaged | (Default false) If set to true, the item is unmanaged and with this not accassable through the JSON API.

Value

  #### Return value

  Returns the current value of the config item.
SetValue
  Set the value of the config item to the given one.

  #### Parameters

  bool value | The new value to set.

  #### Remarks

  SetValue() can only be called for items with unmanaged flag set to true. Everything else will lead to an assertion.
  Note that this won't affect the internal changed flag.
HasDefaultValue

  #### Return value

  Returns true, if the current value of the item equals the default value given on creation, else false.
Reset
  Resets the config item and set the value to the default value.

## ConfigInt

    class ConfigInt: public ConfigItem {
    public:
        ConfigInt(ConfigContext * context, const char * name, int defVal, bool unmanaged = false, int minVal = INT32_MIN, int maxVal = INT32_MAX);
        virtual ~ConfigInt();

        int Value() const { return this->value; }
        void SetValue(int value);
        bool HasDefaultValue() override;
        void Reset() override;
    };

### Overview

This config item will store a 32bit singed integer.

### Public functions

ConfigInt (Constructor)
  The constructor of the class.

  #### Parameters

  ConfigContext * context | The ConfigContext instance the item itself will reigster to it.
  char * name | The name of the config item. Must be unique withing the given ConfigContext.
  int defVal | The default value for the item.
  bool unmanaged | (Default false) If set to true, the item is unmanaged and with this not accassable through the JSON API.
  int minVal | (Default: INT32_MIN) The minimum value that can be set to that item.
  int maxVal | (Default: INT32_MAX) The maximum value that can be set to that item.

Value

  #### Return value

  Returns the current value of the config item.
SetValue
  Set the value of the config item to the given one.

  #### Parameters

  int value | The new value to set.

  #### Remarks

  SetValue() can only be called for items with unmanaged flag set to true. Everything else will lead to an assertion.
  Note that this won't affect the internal changed flag.
  If the value passed to SetValue() is less than minVal (given to the constructor), the internal value will be set to minVal. If it is greater than maxVal, the internal value will be set to maxVal.
HasDefaultValue

  #### Return value

  Returns true, if the current value of the item equals the default value given on creation, else false.
Reset
  Resets the config item and set the value to the default value.

## ConfigDword

    class ConfigDword : public ConfigItem {
    public:
        ConfigDword(ConfigContext * context, const char * name, dword defVal, bool unmanaged = false, dword minVal = 0, dword maxVal = UINT32_MAX);
        virtual ~ConfigDword();

        dword Value() const { return this->value; }
        void SetValue(dword value);
        bool HasDefaultValue() override;
        void Reset() override;
    };

### Overview

This config item will store a 32bit unsinged integer.

### Public functions

ConfigDword (Constructor)
  The constructor of the class.

  #### Parameters

  ConfigContext * context | The ConfigContext instance the item itself will reigster to it.
  char * name | The name of the config item. Must be unique withing the given ConfigContext.
  dword defVal | The default value for the item.
  bool unmanaged | (Default false) If set to true, the item is unmanaged and with this not accassable through the JSON API.
  dword minVal | (Default: 0) The minimum value that can be set to that item.
  dword maxVal | (Default: UINT32_MAX) The maximum value that can be set to that item.

Value

  #### Return value

  Returns the current value of the config item.
SetValue
  Set the value of the config item to the given one.

  #### Parameters

  dword value | The new value to set.

  #### Remarks

  SetValue() can only be called for items with unmanaged flag set to true. Everything else will lead to an assertion.
  Note that this won't affect the internal changed flag.
  If the value passed to SetValue() is less than minVal (given to the constructor), the internal value will be set to minVal. If it is greater than maxVal, the internal value will be set to maxVal.
HasDefaultValue

  #### Return value

  Returns true, if the current value of the item equals the default value given on creation, else false.
Reset
  Resets the config item and set the value to the default value.

## ConfigLong64

    class ConfigLong64 : public ConfigItem {
    public:
        ConfigLong64(ConfigContext * context, const char * name, long64 defVal, bool unmanaged = false, long64 minVal = INT64_MIN, long64 maxVal = INT64_MAX);
        virtual ~ConfigLong64();

        long64 Value() const { return this->value; }
        void SetValue(long64 value);
        bool HasDefaultValue() override;
        void Reset() override;
    };

### Overview

This config item will store a 64bit singed integer.

### Public functions

ConfigLong64 (Constructor)
  The constructor of the class.

  #### Parameters

  ConfigContext * context | The ConfigContext instance the item itself will reigster to it.
  char * name | The name of the config item. Must be unique withing the given ConfigContext.
  long64 defVal | The default value for the item.
  bool unmanaged | (Default false) If set to true, the item is unmanaged and with this not accassable through the JSON API.
  long64 minVal | (Default: INT64_MIN) The minimum value that can be set to that item.
  long64 maxVal | (Default: INT64_MAX) The maximum value that can be set to that item.

Value

  #### Return value

  Returns the current value of the config item.
SetValue
  Set the value of the config item to the given one.

  #### Parameters

  long64 value | The new value to set.

  #### Remarks

  SetValue() can only be called for items with unmanaged flag set to true. Everything else will lead to an assertion.
  Note that this won't affect the internal changed flag.
  If the value passed to SetValue() is less than minVal (given to the constructor), the internal value will be set to minVal. If it is greater than maxVal, the internal value will be set to maxVal.
HasDefaultValue

  #### Return value

  Returns true, if the current value of the item equals the default value given on creation, else false.
Reset
  Resets the config item and set the value to the default value.

## ConfigUlong64

    class ConfigUlong64 : public ConfigItem {
    public:
        ConfigUlong64(ConfigContext * context, const char * name, ulong64 defVal, bool unmanaged = false, ulong64 minVal = 0, ulong64 maxVal = UINT64_MAX);
        virtual ~ConfigUlong64();

        ulong64 Value() const { return this->value; }
        void SetValue(ulong64 value);
        bool HasDefaultValue() override;
        void Reset() override;
    };

### Overview

This config item will store a 64bit singed integer.

### Public functions

ConfigUlong64 (Constructor)
  The constructor of the class.

  #### Parameters

  ConfigContext * context | The ConfigContext instance the item itself will reigster to it.
  char * name | The name of the config item. Must be unique withing the given ConfigContext.
  ulong64 defVal | The default value for the item.
  bool unmanaged | (Default false) If set to true, the item is unmanaged and with this not accassable through the JSON API.
  ulong64 minVal | (Default: 0) The minimum value that can be set to that item.
  ulong64 maxVal | (Default: UINT64_MAX) The maximum value that can be set to that item.

Value

  #### Return value

  Returns the current value of the config item.
SetValue
  Set the value of the config item to the given one.

  #### Parameters

  ulong64 value | The new value to set.

  #### Remarks

  SetValue() can only be called for items with unmanaged flag set to true. Everything else will lead to an assertion.
  Note that this won't affect the internal changed flag.
  If the value passed to SetValue() is less than minVal (given to the constructor), the internal value will be set to minVal. If it is greater than maxVal, the internal value will be set to maxVal.
HasDefaultValue

  #### Return value

  Returns true, if the current value of the item equals the default value given on creation, else false.
Reset
  Resets the config item and set the value to the default value.

## ConfigString

    class ConfigString : public ConfigItem {
    public:
        ConfigString(ConfigContext * context, const char * name, const char * defVal, bool unmanaged = false, bool isPassword = false);
        virtual ~ConfigString();

        const char * Value() const { return this->value; }
        void SetValue(const char * value);
        bool HasDefaultValue() override;
        void Reset() override;
        static void Encrypt(const char * seed, const char * password, char * out, size_t len);
        static void Decrypt(const char * seed, const char * password, char * out, size_t len);
    };

### Overview

This config item will store string value. That also can be a password (of isPassword of the constructor is set to true). In that case, an empty string instead of the password itself will be send to a JsonApiContext. When setting a new value for that item using the JSON API, the password must be encrypted. See the JSON messages description below for more details. Gladly, the encryption and decryption part is handled inside the JavaScript config library as well as inside the C++ library.

### Remarks

Note that even passwords must be send by a JsonApiContext in an encrypted format, the password itself will be saved unencrypted to the database. This is not a big problem, because the database of an application can only be accassed after passing the login-procedure on the JavaScript side. On the linux (C++) side, the access to the database is also protected by username and password. However, an app is free to encrypt the password itself before sending it to ConfigContext (or setting it using SetValue() for unmanaged items), which will end up in an encrpyted password inside the databse. In that case, the app also must decrypt the password when needed.

### Public functions

ConfigString (Constructor)
  The constructor of the class.

  #### Parameters

  ConfigContext * context | The ConfigContext instance the item itself will reigster to it.
  char * name | The name of the config item. Must be unique withing the given ConfigContext.
  char * defVal | The default value for the item.
  bool unmanaged | (Default false) If set to true, the item is unmanaged and with this not accassable through the JSON API.
  bool isPassword | (Default false) If set to true, the item is handled as password string and will not be send to a JsonApiContext.

  #### Remarks

  Note that ConfigString won't make a copy of the default value given in devVal. It will only store the pointer. So an application must guarantee, that the string passed to the constructor will exist and also not be changed over the lifetime of a ConfigString object.
Value

  #### Return value

  Returns the current value of the config item.

  #### Remarks

  If the item is defined as password, Value() will return that password in plain text.
SetValue
  Set the value of the config item to the given one.

  #### Parameters

  ulong64 value | The new value to set.

  #### Remarks

  SetValue() can only be called for items with unmanaged flag set to true. Everything else will lead to an assertion.
  Note that this won't affect the internal changed flag.
  If the item is defined as password, the password must be set unencrypted here (or Value() will return it encrypted, too).
HasDefaultValue

  #### Return value

  Returns true, if the current value of the item equals the default value given on creation, else false.
Reset
  Resets the config item and set the value to the default value.
Encrypt
  Encrypts a password with a seed and writes the result to an output buffer. The encrypted password can be decrypted with the same seed again.

  #### Parameters

  const char * seed | A seed to use.
  const char * password | The clear text password.
  char * out | Output buffer. The buffer should have a size of strlen(password) * 2 + 1.
  size_t len | The length of the output buffer.

Decrypt
  Decrypts a password with a seed and writes the result to an output buffer.

  #### Parameters

  const char * seed | A seed to use.
  const char * password | The encrypted password.
  char * out | Output buffer. The buffer should have a size of strlen(password) / 2 + 1.
  size_t len | The length of the output buffer.

# JSON Messages

## Overview

Below is the description of the JSON messages the ConfigContext shares with the JavaScript config library. Note that some of the fields are optional end depend on the value of other fields. You are free to implement your only config javascript library, but note that this messages only will be accepted after sucessfully logging into an appservice using the AppWebsocket javascript library. See JavaScript config library for details.

The Config protocol supports the AppWebsocket "src" mechanism.

## Base message

    {
        "api": "Config",
        "src": string,
        "mt": "ConfigMessage"
    }

All messages send from and to ConfigContext always have the same header. The property api defines the message as part of the configuration API of the SDK, mt defines the message itself and will be one of the following values:

Send to ConfigContext

- GetConfigItems
- ReadConfig
- WriteConfig

Send from ConfigContext

- GetConfigItemsResult
- ReadConfigResult
- WriteConfigResult
- ConfigUpdate

## GetConfigItems

    {
        "api": "Config",
        "mt": "GetConfigItems"
    }

### Overview

Before reading the current config, the list of available config items should be requested first. This will be done by the GetConfigItems message, which will lead to a GetConfigItemsResult with the list of config items and details to them.

## GetConfigItemsResult

    {
        "api": "Config",
        "mt": "GetConfigItems",
        "result": "AccessDenied",
        "ConfigItems": [ConfigItemObject]
    }

### Overview

This will be the answer for a GetConfigItems message. Beside the message base, there will be another property which is either result or ConfigItems.

### Fields

result
  If the JsonApiContext that sent the GetConfigItems message doens't have the right to read the config, the result property will be set (always with the value "AccessDenied"). In that case, result is the only additional one. If access is allowed, no result property will be sent within that message.
ConfigItems
  If the JsonApiContext that has sent the GetConfigItems message has the right to read the config, an array named ConfigItems will be send. This array can be empty (if there are no config items), or filled with objects descriped in ConfigItemObject providing the informations for an config item.

### ConfigItemObject

    {
        "name": "ConfigItemName",
        "type": "TypeOfItem",
        "minVal" : Number,
        "maxVal" : Number,
        "password" : true,
        "choices" : [ListOfChoices]
    }

name
  The name of the config item as defined on the C++ side.
type
  The type of the config item. Will be one of the following:
  - BOOL A boolean field.
  - INT A 32bit singed integer field.
  - DWORD A 32bit unsigned integer field.
  - LONG64 A 64bit singed integer field.
  - ULONG64 A 64bit unsigned integer field.
  - STRING A string field.
  - CHOICE A choice field.
minVal (optional)
  (Only for config item types INT, DWORD, LONG64 and ULONG64) If set, the property defines minimum value accepted by that config item.
maxVal (optional)
  (Only for config item types INT, DWORD, LONG64 and ULONG64) If set, the property defines maximum value accepted by that config item.
password (optional)
  (Only for config item type STRING) If exists (and in that case always set to true), the string config item is defined as password string. That means, that ReadConfig and ConfigUpdate never will send the real value for that item (an empty string will be send instead). And when writing a value to that item, it must be encrypted. That encryption is handled by the JavaScript config library.
choices
  (Only for config item type CHOICE) An array with the available choices to choose. Each choice is represented by a string value.

### Example message

    {
        "api": "Config",
        "mt": "GetConfigItemsResult",
        "ConfigItems": [{
            "name" : "maxPlayers",
            "type" : "DWORD",
            "minVal" : 1,
            "maxVal" : 10
        },
        {
            "name" : "teams",
            "type" : "CHOICE",
            "choices" : ["RedTeam", "BlueTeam", "InnoTeam"]
        },
        {
            "name" : "playerName",
            "type" : "STRING"
        }]
    }

## ReadConfig

    {
        "api": "Config",
        "mt": "ReadConfig"
    }

### Overview

This will request the current configuration which will lead to a ReadConfigResult message.

## ReadConfigResult / ConfigUpdate

    {
        "api": "Config",
        "mt": "ReadConfigResult" / "ConfigUpdate"
        "ConfigItems" : {
            "ItemName" : number,
            "ItemName" : true / false,
            "ItemName" : "stringValue"
        }
    }

### Overview

This message will be used to send the current configuration after requested (ReadConfigResult) or after the config had been changed on the C++ side (ConfigUpdate). The messages for ReadConfigResult and ConfigUpdate are the same except the value of the mt property, of course.
ConfigItems
  This array holds all config items and their values. Each item will be send by a property with the name of the item and the value. The value type depends of the type of the config item itself:
  - INT, DWORD, LONG64, ULONG64: The value as number with the bitwith according the config item type.
  - CHOICE: The zero based index inside the array of choices received with the GetConfigItemsResult message.
  - BOOL: Simply true or false.
  - STRING: The string value of the item.

### Example message

    {
        "api": "Config",
        "mt": "ReadConfigResult",
        "ConfigItems": {
            "maxPlayers" : 5,
            "teams" : 2,
            "playerName" : "Goldfish"
        }
    }

## WriteConfig

    {
        "api": "Config",
        "mt": "WriteConfig",
        "ConfigItems": {
            "ItemName": number,
            "ItemName": true / false,
            "ItemName": "StringValue",
            "ItemNamePassword": {
                "value": "EncodedValue",
                "key": "KeyToDecode"
            }
        }
    }

### Overview

With this message, ConfigContext will update the internal config items with the values sent by the message. Each property value that differ from the appropriate config items dfefault value or current value, will be updated in memory and written to the database.
ConfigItems
  This array holds all config items and their values. Each item will be send by a property with the name of the item and the value. The value type depends of the type of the config item itself:
  - INT, DWORD, LONG64, ULONG64: The value as number with the bitwith according the config item type.
  - CHOICE: The zero based index inside the array of choices received with the GetConfigItemsResult message.
  - BOOL: Simply true or false.
  - STRING: The string value of the item.
  There is one special field for string config items that are defined as password strings. For this items, "Password" must be added to the items name and set as the property that holds an array. Inside this array, the encrypted string value will be set to the value property, while the key property holds the key needed to decode the string inside value. The encryption must be done by creating a value for the key and call the decrypt function of appWebsocket with that created key and the string to encode. Both informations (the encrypted string and the key) are used by ConfigContext do decrypt the password again.

## WriteConfigResult

    {
        "api":"Config",
        "mt":"WriteConfigResult",
        "result":"ok"
    }

### Overview

This message will be send as answer to WriteConfig.
result
  The result of the WriteConfig message which can be one of the following value:
  - ok The config had been sucessfully witten to the database.
  - failed Writing the config failed. See the log of the application service for details (logging of config must be enabled).
  - AccessDenied The connection does't have the right to write the config.

# Code examples

## ConfigContext

    // A simple class derived from ConfigContext

    static const char * team_names[] = { "ReadTeam", "BlueTeam", "InnoTeam", nullptr };

    class MyConfig : public ConfigContext() {
    private:
        class MyApp * myApp;
        ConfigInt maxPlayers;
        ConfigString playerName;
        ConfigChoice teams;

    protected:
        virtual void ConfigChanged()
        {
            this->myApp->OnConfigChanged();
        }

    public:
        // Let's assume, that MyApp is derived from JsonApiContext.
        MyConfig(class MyApp * userApp, class IDatabase * database, class IInstanceLog * log)
            : ConfigContext(database, log),
              maxPlayers(this, "maxPlayers", 5, false, 1, 10),
              playerName(this, "playerName", "Goldfish"),
              teams(this, "teams", 2, team_names)
        {
            this->myApp = userApp;
            this->myApp->RegisterJsonApi(this);
        }

        ConfigInt & MaxPlayers() { return this->maxPlayers; }
        ConfigString & PlayerName() { return this->playerName; }
        ConfigChoice & Teams() { return this->teams; }
    };

## Using config

    // Let's assume, that MyApp is derived from JsonApiContext and UTask, already
    // created and also has pointers to an already created and initialized IDatabase
    // instance as well as valid IInstanceLog instance.

    void MyApp::Init()
    {
        this->config = new MyConfig(this, this->database, this->log);
        ITask * initConfigTask = this->config->CreateInitTask();
        initConfigTask->Start(this);
    }

    void MyApp::TaskComplete(ITask * task)
    {
        delete task;
        debug->printf("Config database initialized");
    }

    void MyApp::OnConfigChanged()
    {
        debug->printf("Config changed - new values:");
        debug->printf("    Max-Players   : %u", this->config->MaxPlayers().Value());
        debug->printf("    Player-Name   : %s", this->config->PlayerName().Value());
        debug->printf("    Selected Team : %s", this->config->Teams().Value());
    }

## First Steps

To use config some preparations in your code needs to be done. The following steps appply when you use ConfigContext as base class to your instance class and do not use a separate class for the config. This is a good option in most cases.

Includes
  Use config.h as include

      #include "common/lib/config.h"

Definitions in the instance class
  Use JsonApiContext and ConfigContext as base class

      ..., public JsonApiContext, public ConfigContext

  Define a private function, as initialization complete handler

      void ConfigInitComplete(class ITask * task);

  Define a UTaskTemplate class so that this handler will be called

      class UTaskTemplate<YourApp, class ITask> taskConfigInit;

  Define public members for the config parameters, e.g

      class ConfigString configParameter;

Instance Code
  Initializations in the constructor of the instance class

      ConfigContext(0, this),
      taskConfigInit(this, &yourApp::ConfigInitComplete),
      configParameter(this, "parameter", "")

  Call RegisterJsonApi in the instance constructor, so that the Config lib is known as Api provider

      RegisterJsonApi(this);

  Start config initialization after database is connected. E.g. in the DatabaseConnectComplete function

          class ITask * task = CreateInitTask(database);
          task->Start(&taskConfigInit);

  Continue initialization when config init is complete

      void YourApp::ConfigInitComplete(class ITask * task)
      {
          ... more init ...
      }

  Make sure the you instance class is passed as jsonApiContext in the AppWebsocket constructor

      AppWebsocket(webserverPlugin, yourApp, yourApp)