From: Vitaliy Cherepanov/AI Tools Lab/Engineer/삼성전자 Date: Mon, 28 May 2018 12:11:35 +0000 (+0300) Subject: nnc: implement PluginData class (#247) X-Git-Tag: nncc_backup~2659 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=84e33117998cb5b91dd6f67148313fe75fc0f34c;p=platform%2Fcore%2Fml%2Fnnfw.git nnc: implement PluginData class (#247) 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 --- diff --git a/contrib/nnc/CMakeLists.txt b/contrib/nnc/CMakeLists.txt index cd2c828..167726e 100644 --- a/contrib/nnc/CMakeLists.txt +++ b/contrib/nnc/CMakeLists.txt @@ -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 index 0000000..f640e78 --- /dev/null +++ b/contrib/nnc/include/module/plugin/PluginData.h @@ -0,0 +1,84 @@ +#ifndef __PLUGIN_DATA_H__ +#define __PLUGIN_DATA_H__ + +#include +#include +#include +#include +#include +#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 parse(int argc, char *argv[]) noexcept(false); + static std::shared_ptr + intersection(const DataList &common, + const std::map &supported) noexcept(false); + static std::shared_ptr + intersection(const DataList &common, + const std::vector &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 &getElements() const noexcept(false); + + const Data &operator[](const std::string &key) const noexcept(false); + +private: + std::string _name; + std::map _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 index 0000000..f553638 --- /dev/null +++ b/contrib/nnc/src/module/plugin/PluginData.cpp @@ -0,0 +1,172 @@ +#include +#include +#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::parse(int argc, char *argv[]) noexcept(false) { + std::shared_ptr 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::intersection(const DataList &common, + const std::vector &supported) noexcept(false) { + std::shared_ptr 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::intersection(const DataList &common, + const std::map &supported) noexcept(false) { + std::vector 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 &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