--- /dev/null
+#ifndef __PLUGIN_DATA_H__
+#define __PLUGIN_DATA_H__
+
+#include <string>
+#include <map>
+#include <vector>
+#include <memory>
+#include <exception>
+#include "PluginParam.h"
+#include "nncc/foundation/Exception.h"
+
+namespace nncc
+{
+namespace contrib
+{
+namespace config
+{
+
+class DataException : public foundation::Exception
+{
+public:
+ explicit DataException(const std::string &info) : Exception(info) {}
+ explicit DataException(Exception &e, const std::string &info) : Exception(e, info) {}
+};
+
+class Data
+{
+public:
+ Data() = delete;
+ explicit Data(const std::string &name);
+ Data(const std::string &name, const std::string &value);
+
+ const std::string &getValue() const;
+ const std::string &getName() const;
+ bool hasValue() const;
+
+ void setValue(const std::string &value);
+
+private:
+ bool _hasValue;
+ std::string _name;
+ std::string _value;
+};
+
+bool operator==(const Data &elm, const char *cmp_value);
+
+std::ostream &operator<<(std::ostream &os, const Data &op);
+
+class DataList
+{
+public:
+ DataList() = delete;
+ explicit DataList(const std::string &name);
+
+ // factory method
+ static std::shared_ptr<DataList> parse(int argc, char *argv[]) noexcept(false);
+ static std::shared_ptr<DataList>
+ intersection(const DataList &common,
+ const std::map<std::string, PluginParam> &supported) noexcept(false);
+ static std::shared_ptr<DataList>
+ intersection(const DataList &common,
+ const std::vector<PluginParam> &supported) noexcept(false);
+
+ Data &createElement(const std::string &name);
+ Data &createElement(const std::string &name, const std::string &value);
+
+ const std::string &getName() const;
+ const Data &getElement(const std::string &name) const noexcept(false);
+ const std::map<std::string, Data> &getElements() const noexcept(false);
+
+ const Data &operator[](const std::string &key) const noexcept(false);
+
+private:
+ std::string _name;
+ std::map<std::string, Data> _items;
+};
+
+std::ostream &operator<<(std::ostream &os, const DataList &list);
+
+} // namespace config
+} // namespace contrib
+} // namespace nncc
+
+#endif /* __PLUGIN_DATA_H__ */
--- /dev/null
+#include <cstring>
+#include <ostream>
+#include "module/plugin/PluginData.h"
+
+namespace nncc
+{
+namespace contrib
+{
+namespace config
+{
+
+// Data class
+
+Data::Data(const std::string &name) : _hasValue(false), _name(name) {}
+
+Data::Data(const std::string &name, const std::string &value) : Data(name) { setValue(value); }
+
+const std::string &Data::getValue() const {
+ if (!_hasValue)
+ throw DataException("Option <" + _name + "> has no value");
+ return _value;
+}
+
+const std::string &Data::getName() const { return _name; }
+
+bool operator==(const Data &elm, const char *cmp_value) { return elm.getValue() == cmp_value; };
+
+void Data::setValue(const std::string &value) {
+ _hasValue = true;
+ _value = value;
+}
+
+bool Data::hasValue() const { return _hasValue; }
+
+std::ostream &operator<<(std::ostream &os, const Data &op) {
+ if (op.hasValue()) {
+ os << "<" << op.getName() << "> = " << op.getValue();
+ } else {
+ os << "<" << op.getName() << ">";
+ }
+
+ return os;
+}
+
+// DataList class
+
+static int is_long_option(const char *argv) {
+ int res = 0;
+ size_t len;
+
+ len = strnlen(argv, 3);
+
+ if (len <= 1) {
+ res = 0;
+ } else if (len == 2) {
+ res = (argv[0] == '-' && argv[1] != '-');
+ } else {
+ res = (argv[0] == '-' && argv[1] == '-' && argv[2] != '-');
+ }
+
+ return res;
+}
+
+static int is_single(int cur, int argc, char *argv[]) {
+ int res = 0;
+
+ if (cur >= argc) {
+ res = 0;
+ } else if (cur + 1 == argc) {
+ res = is_long_option(argv[cur]);
+ } else {
+ res = is_long_option(argv[cur]) && is_long_option(argv[cur + 1]);
+ }
+
+ return res;
+}
+
+DataList::DataList(const std::string &name) : _name(name) {}
+
+std::shared_ptr<DataList> DataList::parse(int argc, char *argv[]) noexcept(false) {
+ std::shared_ptr<DataList> params(new DataList("params"));
+
+ for (int i = 1; i < argc; i++) {
+ if (is_single(i, argc, argv)) {
+ params->createElement(argv[i] + 2);
+ } else if (is_long_option(argv[i])) {
+ params->createElement(argv[i] + 2, argv[i + 1]);
+ i++;
+ }
+ }
+
+ return params;
+}
+
+// This function is used to intersect command line params
+// with params requested by plugins and modules
+std::shared_ptr<DataList>
+DataList::intersection(const DataList &common,
+ const std::vector<PluginParam> &supported) noexcept(false) {
+ std::shared_ptr<DataList> params(new DataList("params"));
+ for (auto s : supported) {
+ try {
+ const Data &op = common.getElement(s.getName());
+ if (op.hasValue())
+ params->createElement(op.getName(), op.getValue());
+ else
+ params->createElement(op.getName());
+ }
+ catch (DataException &eOp) {
+ if (!s.isOptional()) {
+ std::string info = "option <" + s.getName() + "> should be set. " + s.getDesc();
+ throw DataException(eOp, info);
+ }
+ }
+ }
+
+ return params;
+}
+
+// This function is used to intersect command line params
+// with params requested by plugins and modules
+std::shared_ptr<DataList>
+DataList::intersection(const DataList &common,
+ const std::map<std::string, PluginParam> &supported) noexcept(false) {
+ std::vector<PluginParam> supported_list;
+ for (auto ¶m : supported) {
+ supported_list.push_back(param.second);
+ }
+
+ return intersection(common, supported_list);
+}
+
+Data &DataList::createElement(const std::string &name) {
+ // TODO check emplace
+ auto res = _items.emplace(name, Data(name));
+ return res.first->second;
+}
+
+Data &DataList::createElement(const std::string &name, const std::string &value) {
+ // TODO check emplace
+ auto res = DataList::_items.emplace(name, Data(name, value));
+ return res.first->second;
+}
+
+const std::string &DataList::getName() const { return _name;}
+
+const Data &DataList::getElement(const std::string &name) const noexcept(false) {
+ auto it = _items.find(name);
+ if (it == _items.end()) {
+ throw DataException(std::string("option <") + name + "> not found");
+ }
+ return it->second;
+}
+
+const std::map<std::string, Data> &DataList::getElements() const noexcept(false) { return _items; }
+
+const Data &DataList::operator[](const std::string &key) const noexcept(false) { return getElement(key); }
+
+std::ostream &operator<<(std::ostream &os, const DataList &list) {
+ os << "<" << list.getName() << "> = {" << std::endl;
+
+ for (auto &f : list.getElements())
+ os << f.second << std::endl;
+
+ os << "}" << std::endl;
+
+ return os;
+}
+
+} // namespace config
+} // namespace contrib
+} // namespace nncc