| #include <cmath> |
| #include "datastore_access.hpp" |
| #include "libyang_utils.hpp" |
| #include "utils.hpp" |
| |
| leaf_data_ leafValueFromValue(const libyang::S_Value& value, LY_DATA_TYPE type) |
| { |
| using namespace std::string_literals; |
| switch (type) { |
| case LY_TYPE_INT8: |
| return value->int8(); |
| case LY_TYPE_INT16: |
| return value->int16(); |
| case LY_TYPE_INT32: |
| return value->int32(); |
| case LY_TYPE_INT64: |
| return value->int64(); |
| case LY_TYPE_UINT8: |
| return value->uint8(); |
| case LY_TYPE_UINT16: |
| return value->uint16(); |
| case LY_TYPE_UINT32: |
| return value->uint32(); |
| case LY_TYPE_UINT64: |
| return value->uint64(); |
| case LY_TYPE_BOOL: |
| return bool(value->bln()); |
| case LY_TYPE_STRING: |
| return std::string(value->string()); |
| case LY_TYPE_ENUM: |
| return enum_{std::string(value->enm()->name())}; |
| case LY_TYPE_IDENT: |
| return identityRef_{value->ident()->module()->name(), value->ident()->name()}; |
| case LY_TYPE_BINARY: |
| return binary_{value->binary()}; |
| case LY_TYPE_EMPTY: |
| return empty_{}; |
| case LY_TYPE_DEC64: |
| { |
| auto v = value->dec64(); |
| return v.value * std::pow(10, -v.digits); |
| } |
| default: // TODO: implement all types |
| return "(can't print)"s; |
| } |
| } |
| |
| // This is very similar to the fillMap lambda in SysrepoAccess, however, |
| // Sysrepo returns a weird array-like structure, while libnetconf |
| // returns libyang::Data_Node |
| void lyNodesToTree(DatastoreAccess::Tree& res, const std::vector<std::shared_ptr<libyang::Data_Node>> items, std::optional<std::string> ignoredXPathPrefix) |
| { |
| auto stripXPathPrefix = [&ignoredXPathPrefix] (auto path) { |
| return ignoredXPathPrefix ? path.substr(ignoredXPathPrefix->size()) : path; |
| }; |
| |
| for (const auto& it : items) { |
| if (!it) |
| continue; |
| if (it->schema()->nodetype() == LYS_CONTAINER) { |
| if (libyang::Schema_Node_Container{it->schema()}.presence()) { |
| // The fact that the container is included in the data tree |
| // means that it is present and I don't need to check any |
| // value. |
| res.emplace_back(stripXPathPrefix(it->path()), special_{SpecialValue::PresenceContainer}); |
| } |
| } |
| if (it->schema()->nodetype() == LYS_LIST) { |
| res.push_back({stripXPathPrefix(it->path()), special_{SpecialValue::List}}); |
| } |
| if (it->schema()->nodetype() == LYS_LEAF || it->schema()->nodetype() == LYS_LEAFLIST) { |
| libyang::Data_Node_Leaf_List leaf(it); |
| auto value = leafValueFromValue(leaf.value(), leaf.leaf_type()->base()); |
| res.emplace_back(stripXPathPrefix(it->path()), value); |
| } |
| } |
| } |