-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathlibyang_utils.cpp
More file actions
134 lines (117 loc) · 4.62 KB
/
libyang_utils.cpp
File metadata and controls
134 lines (117 loc) · 4.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#include <boost/algorithm/string/predicate.hpp>
#include <cmath>
#include <libyang-cpp/Context.hpp>
#include "datastore_access.hpp"
#include "libyang_utils.hpp"
#include "utils.hpp"
struct impl_leafValueFromNode {
leaf_data_ operator()(const libyang::Empty) const
{
return empty_{};
}
leaf_data_ operator()(const libyang::Binary& bin) const
{
return binary_{bin.base64};
}
leaf_data_ operator()(const std::vector<libyang::Bit>& bits) const
{
bits_ res;
std::transform(bits.begin(), bits.end(), std::back_inserter(res.m_bits), [] (const libyang::Bit& bit) {
return bit.name;
});
return res;
}
leaf_data_ operator()(const libyang::Enum& enumVal) const
{
return enum_{enumVal.name};
}
leaf_data_ operator()(const libyang::IdentityRef& identRef) const
{
return identityRef_{identRef.module, identRef.name};
}
leaf_data_ operator()(const libyang::Decimal64& dec) const
{
return dec.number * std::pow(10, -dec.digits);
}
leaf_data_ operator()(const libyang::InstanceIdentifier& node) const
{
return instanceIdentifier_{node.path};
}
template <typename Type>
leaf_data_ operator()(const Type& val) const
{
return val;
}
};
leaf_data_ leafValueFromNode(libyang::DataNodeTerm node)
{
return std::visit(impl_leafValueFromNode{},node.value());
}
namespace {
template <typename CollectionType>
void impl_lyNodesToTree(DatastoreAccess::Tree& res, CollectionType items, std::optional<std::string> ignoredXPathPrefix)
{
auto stripXPathPrefix = [&ignoredXPathPrefix](auto path) {
return ignoredXPathPrefix && path.find(*ignoredXPathPrefix) != std::string::npos ? path.substr(ignoredXPathPrefix->size()) : path;
};
for (const auto& it : items) {
if (it.schema().nodeType() == libyang::NodeType::Container) {
if (it.schema().asContainer().isPresence()) {
// 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() == libyang::NodeType::List) {
res.emplace_back(stripXPathPrefix(it.path()), special_{SpecialValue::List});
}
if (it.schema().nodeType() == libyang::NodeType::Leaf || it.schema().nodeType() == libyang::NodeType::Leaflist) {
auto term = it.asTerm();
auto value = leafValueFromNode(term);
res.emplace_back(stripXPathPrefix(it.path()), value);
}
}
}
}
template <typename CollectionType>
void lyNodesToTree(DatastoreAccess::Tree& res, CollectionType items, std::optional<std::string> ignoredXPathPrefix)
{
for (auto it = items.begin(); it != items.end(); /* nothing */) {
if ((*it).schema().nodeType() == libyang::NodeType::Leaflist) {
auto leafListPath = stripLeafListValueFromPath(it->path());
res.emplace_back(leafListPath, special_{SpecialValue::LeafList});
while (it != items.end() && boost::starts_with(it->path(), leafListPath)) {
impl_lyNodesToTree(res, it->childrenDfs(), ignoredXPathPrefix);
it++;
}
} else {
impl_lyNodesToTree(res, it->childrenDfs(), ignoredXPathPrefix);
it++;
}
}
}
using SiblingColl = libyang::Collection<libyang::DataNode, libyang::IterationType::Sibling>;
using DfsColl = libyang::Collection<libyang::DataNode, libyang::IterationType::Dfs>;
template
void lyNodesToTree<SiblingColl>(DatastoreAccess::Tree& res, SiblingColl items, std::optional<std::string> ignoredXPathPrefix);
template
void lyNodesToTree<DfsColl>(DatastoreAccess::Tree& res, DfsColl items, std::optional<std::string> ignoredXPathPrefix);
template
void lyNodesToTree<libyang::Set<libyang::DataNode>>(DatastoreAccess::Tree& res, libyang::Set<libyang::DataNode> items, std::optional<std::string> ignoredXPathPrefix);
DatastoreAccess::Tree rpcOutputToTree(const std::optional<libyang::DataNode>& output)
{
DatastoreAccess::Tree res;
if (output) {
lyNodesToTree(res, output->siblings(), joinPaths(output->path(), "/"));
}
return res;
}
libyang::DataNode treeToRpcInput(libyang::Context ctx, const std::string& path, DatastoreAccess::Tree in)
{
auto root = ctx.newPath(path, std::nullopt, libyang::CreationOptions::Update);
for (const auto& [k, v] : in) {
root.newPath(k, leafDataToString(v), libyang::CreationOptions::Update);
}
return root;
}