nnc: implement PluginData class (#247)
authorVitaliy Cherepanov/AI Tools Lab/Engineer/삼성전자 <v.cherepanov@samsung.com>
Mon, 28 May 2018 12:11:35 +0000 (15:11 +0300)
committerSergey Vostokov/AI Tools Lab/Staff Engineer/삼성전자 <s.vostokov@samsung.com>
Mon, 28 May 2018 12:11:35 +0000 (15:11 +0300)
nnc: implement PluginData class

This class will be used for command line arguments parsing and
and interact it with plugin params

Signed-off-by: Vitaliy Cherepanov <v.cherepanov@samsung.com>
contrib/nnc/CMakeLists.txt
contrib/nnc/include/module/plugin/PluginData.h [new file with mode: 0644]
contrib/nnc/src/module/plugin/PluginData.cpp [new file with mode: 0644]

index cd2c828..167726e 100644 (file)
@@ -5,6 +5,7 @@ file(GLOB_RECURSE CL_SRC src/*.cpp include/*.h)
 add_executable(nnc ${CL_SRC})
 target_link_libraries(nnc PRIVATE nncc_core)
 target_link_libraries(nnc PRIVATE nncc_foundation)
+target_link_libraries(nnc PRIVATE nnc_plugin_core)
 target_link_libraries(nnc PRIVATE dl)
 target_include_directories(nnc PUBLIC include)
 
diff --git a/contrib/nnc/include/module/plugin/PluginData.h b/contrib/nnc/include/module/plugin/PluginData.h
new file mode 100644 (file)
index 0000000..f640e78
--- /dev/null
@@ -0,0 +1,84 @@
+#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__ */
diff --git a/contrib/nnc/src/module/plugin/PluginData.cpp b/contrib/nnc/src/module/plugin/PluginData.cpp
new file mode 100644 (file)
index 0000000..f553638
--- /dev/null
@@ -0,0 +1,172 @@
+#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 &param : 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