blob: 15b1b06005a53d576142d4958bb5ee9db66b4372 [file] [log] [blame]
Jan Kundrátbd3169c2020-02-03 19:31:34 +01001#include <cmath>
Václav Kubernát3c8fe022020-06-04 01:35:03 +02002#include "datastore_access.hpp"
3#include "libyang_utils.hpp"
4#include "utils.hpp"
Václav Kubernát02a71152020-01-21 14:52:51 +01005
6leaf_data_ leafValueFromValue(const libyang::S_Value& value, LY_DATA_TYPE type)
7{
8 using namespace std::string_literals;
9 switch (type) {
10 case LY_TYPE_INT8:
11 return value->int8();
12 case LY_TYPE_INT16:
13 return value->int16();
14 case LY_TYPE_INT32:
15 return value->int32();
16 case LY_TYPE_INT64:
17 return value->int64();
18 case LY_TYPE_UINT8:
19 return value->uint8();
20 case LY_TYPE_UINT16:
21 return value->uint16();
22 case LY_TYPE_UINT32:
Jan Kundrátcc2538f2020-02-03 11:33:42 +010023 return value->uint32();
Václav Kubernát02a71152020-01-21 14:52:51 +010024 case LY_TYPE_UINT64:
25 return value->uint64();
26 case LY_TYPE_BOOL:
27 return bool(value->bln());
28 case LY_TYPE_STRING:
29 return std::string(value->string());
30 case LY_TYPE_ENUM:
31 return enum_{std::string(value->enm()->name())};
Jan Kundrát0d8abd12020-05-07 02:00:14 +020032 case LY_TYPE_IDENT:
33 return identityRef_{value->ident()->module()->name(), value->ident()->name()};
Jan Kundrát4225b3f2020-01-24 12:58:38 +010034 case LY_TYPE_BINARY:
Jan Kundrát68985442020-05-07 02:15:34 +020035 return binary_{value->binary()};
Jan Kundrát379bb572020-05-07 03:23:13 +020036 case LY_TYPE_EMPTY:
37 return empty_{};
Jan Kundrátbd3169c2020-02-03 19:31:34 +010038 case LY_TYPE_DEC64:
39 {
40 auto v = value->dec64();
41 return v.value * std::pow(10, -v.digits);
42 }
Václav Kubernát02a71152020-01-21 14:52:51 +010043 default: // TODO: implement all types
44 return "(can't print)"s;
45 }
46}
Václav Kubernát3c8fe022020-06-04 01:35:03 +020047
48// This is very similar to the fillMap lambda in SysrepoAccess, however,
49// Sysrepo returns a weird array-like structure, while libnetconf
50// returns libyang::Data_Node
51void lyNodesToTree(DatastoreAccess::Tree& res, const std::vector<std::shared_ptr<libyang::Data_Node>> items, std::optional<std::string> ignoredXPathPrefix)
52{
53 auto stripXPathPrefix = [&ignoredXPathPrefix] (auto path) {
54 return ignoredXPathPrefix ? path.substr(ignoredXPathPrefix->size()) : path;
55 };
56
57 for (const auto& it : items) {
58 if (!it)
59 continue;
60 if (it->schema()->nodetype() == LYS_CONTAINER) {
61 if (libyang::Schema_Node_Container{it->schema()}.presence()) {
62 // The fact that the container is included in the data tree
63 // means that it is present and I don't need to check any
64 // value.
65 res.emplace_back(stripXPathPrefix(it->path()), special_{SpecialValue::PresenceContainer});
66 }
67 }
68 if (it->schema()->nodetype() == LYS_LIST) {
69 res.push_back({stripXPathPrefix(it->path()), special_{SpecialValue::List}});
70 }
71 if (it->schema()->nodetype() == LYS_LEAF || it->schema()->nodetype() == LYS_LEAFLIST) {
72 libyang::Data_Node_Leaf_List leaf(it);
73 auto value = leafValueFromValue(leaf.value(), leaf.leaf_type()->base());
74 res.emplace_back(stripXPathPrefix(it->path()), value);
75 }
76 }
77}