mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-30 21:45:37 +00:00
[#2601] update YANG developer guide
This commit is contained in:
committed by
Razvan Becheriu
parent
e4e9d0e362
commit
13142fea93
@@ -60,9 +60,9 @@ Translator::checkAndGetAndJsonifyLeaf(ElementPtr& storage,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Translator::checkAndJsonifyAndSetLeaf(ConstElementPtr const& from,
|
Translator::checkAndStringifyAndSetLeaf(ConstElementPtr const& from,
|
||||||
string const& xpath,
|
string const& xpath,
|
||||||
string const& name) {
|
string const& name) {
|
||||||
ConstElementPtr const& x(from->get(name));
|
ConstElementPtr const& x(from->get(name));
|
||||||
if (x) {
|
if (x) {
|
||||||
ElementPtr const& json(Element::create(x->str()));
|
ElementPtr const& json(Element::create(x->str()));
|
||||||
@@ -112,16 +112,6 @@ void Translator::checkAndSetUserContext(ConstElementPtr const& from,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string
|
|
||||||
Translator::decode64(string const& input) {
|
|
||||||
vector<uint8_t> binary;
|
|
||||||
decodeBase64(input, binary);
|
|
||||||
string result;
|
|
||||||
result.resize(binary.size());
|
|
||||||
memmove(&result[0], &binary[0], result.size());
|
|
||||||
return (result);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Translator::deleteItem(string const& xpath) {
|
Translator::deleteItem(string const& xpath) {
|
||||||
|
|
||||||
@@ -135,15 +125,6 @@ Translator::deleteItem(string const& xpath) {
|
|||||||
session_.applyChanges();
|
session_.applyChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
string
|
|
||||||
Translator::encode64(string const& input) {
|
|
||||||
vector<uint8_t> binary;
|
|
||||||
binary.resize(input.size());
|
|
||||||
memmove(&binary[0], input.c_str(), binary.size());
|
|
||||||
return (encodeBase64(binary));
|
|
||||||
}
|
|
||||||
|
|
||||||
DataNode
|
DataNode
|
||||||
Translator::findXPath(string const& xpath) const {
|
Translator::findXPath(string const& xpath) const {
|
||||||
optional<DataNode> const& data_node(getData(xpath));
|
optional<DataNode> const& data_node(getData(xpath));
|
||||||
@@ -233,60 +214,6 @@ Translator::getMandatoryDivergingLeaf(ElementPtr& storage,
|
|||||||
storage->set(name, x);
|
storage->set(name, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
Translator::Deserializer
|
|
||||||
Translator::initializeDeserializer() {
|
|
||||||
Deserializer result;
|
|
||||||
|
|
||||||
result.emplace(LeafBaseType::Binary, [](string const& value) -> ElementPtr const {
|
|
||||||
return Element::create(decode64(value));
|
|
||||||
});
|
|
||||||
|
|
||||||
for (LeafBaseType const& i :
|
|
||||||
{LeafBaseType::Bool, LeafBaseType::Dec64, LeafBaseType::Int8, LeafBaseType::Int16,
|
|
||||||
LeafBaseType::Int32, LeafBaseType::Int64, LeafBaseType::Uint8, LeafBaseType::Uint16,
|
|
||||||
LeafBaseType::Uint32, LeafBaseType::Uint64}) {
|
|
||||||
result.emplace(i, [](string const& value) -> ElementPtr const {
|
|
||||||
return Element::fromJSON(value);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// The rest of YANG values can be expressed as strings.
|
|
||||||
for (LeafBaseType const& i :
|
|
||||||
{LeafBaseType::Bits, LeafBaseType::Empty, LeafBaseType::Enum, LeafBaseType::IdentityRef,
|
|
||||||
LeafBaseType::InstanceIdentifier, LeafBaseType::Leafref, LeafBaseType::String,
|
|
||||||
LeafBaseType::Union, LeafBaseType::Unknown}) {
|
|
||||||
result.emplace(i, [](string const& value) -> ElementPtr const {
|
|
||||||
return Element::create(value);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
Translator::Serializer
|
|
||||||
Translator::initializeSerializer() {
|
|
||||||
Serializer result;
|
|
||||||
|
|
||||||
result.emplace(LeafBaseType::Binary, [](string const& value) -> string const {
|
|
||||||
return encode64(value);
|
|
||||||
});
|
|
||||||
|
|
||||||
// The rest of YANG values can be expressed directly.
|
|
||||||
for (LeafBaseType const& i :
|
|
||||||
{LeafBaseType::Bits, LeafBaseType::Bool, LeafBaseType::Dec64, LeafBaseType::Empty,
|
|
||||||
LeafBaseType::Enum, LeafBaseType::IdentityRef, LeafBaseType::InstanceIdentifier,
|
|
||||||
LeafBaseType::Int8, LeafBaseType::Int16, LeafBaseType::Int32, LeafBaseType::Int64,
|
|
||||||
LeafBaseType::Leafref, LeafBaseType::String, LeafBaseType::Uint8, LeafBaseType::Uint16,
|
|
||||||
LeafBaseType::Uint32, LeafBaseType::Uint64, LeafBaseType::Union, LeafBaseType::Unknown}) {
|
|
||||||
result.emplace(i, [](string const& value) -> string const {
|
|
||||||
return value;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Translator::schemaNodeExists(string const& xpath) const {
|
bool Translator::schemaNodeExists(string const& xpath) const {
|
||||||
Context const& context(session_.getContext());
|
Context const& context(session_.getContext());
|
||||||
try {
|
try {
|
||||||
@@ -377,5 +304,76 @@ Translator::translateToYang(ConstElementPtr const& element,
|
|||||||
return serializer.at(type)(string_representation);
|
return serializer.at(type)(string_representation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string
|
||||||
|
Translator::decode64(string const& input) {
|
||||||
|
vector<uint8_t> binary;
|
||||||
|
decodeBase64(input, binary);
|
||||||
|
string result;
|
||||||
|
result.resize(binary.size());
|
||||||
|
memmove(&result[0], &binary[0], result.size());
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
|
||||||
|
string
|
||||||
|
Translator::encode64(string const& input) {
|
||||||
|
vector<uint8_t> binary;
|
||||||
|
binary.resize(input.size());
|
||||||
|
memmove(&binary[0], input.c_str(), binary.size());
|
||||||
|
return (encodeBase64(binary));
|
||||||
|
}
|
||||||
|
|
||||||
|
Translator::Deserializer
|
||||||
|
Translator::initializeDeserializer() {
|
||||||
|
Deserializer result;
|
||||||
|
|
||||||
|
result.emplace(LeafBaseType::Binary, [](string const& value) -> ElementPtr const {
|
||||||
|
return Element::create(decode64(value));
|
||||||
|
});
|
||||||
|
|
||||||
|
for (LeafBaseType const& i :
|
||||||
|
{LeafBaseType::Bool, LeafBaseType::Dec64, LeafBaseType::Int8, LeafBaseType::Int16,
|
||||||
|
LeafBaseType::Int32, LeafBaseType::Int64, LeafBaseType::Uint8, LeafBaseType::Uint16,
|
||||||
|
LeafBaseType::Uint32, LeafBaseType::Uint64}) {
|
||||||
|
result.emplace(i, [](string const& value) -> ElementPtr const {
|
||||||
|
return Element::fromJSON(value);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// The rest of YANG values can be expressed as strings.
|
||||||
|
for (LeafBaseType const& i :
|
||||||
|
{LeafBaseType::Bits, LeafBaseType::Empty, LeafBaseType::Enum, LeafBaseType::IdentityRef,
|
||||||
|
LeafBaseType::InstanceIdentifier, LeafBaseType::Leafref, LeafBaseType::String,
|
||||||
|
LeafBaseType::Union, LeafBaseType::Unknown}) {
|
||||||
|
result.emplace(i, [](string const& value) -> ElementPtr const {
|
||||||
|
return Element::create(value);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Translator::Serializer
|
||||||
|
Translator::initializeSerializer() {
|
||||||
|
Serializer result;
|
||||||
|
|
||||||
|
result.emplace(LeafBaseType::Binary, [](string const& value) -> string const {
|
||||||
|
return encode64(value);
|
||||||
|
});
|
||||||
|
|
||||||
|
// The rest of YANG values can be expressed directly.
|
||||||
|
for (LeafBaseType const& i :
|
||||||
|
{LeafBaseType::Bits, LeafBaseType::Bool, LeafBaseType::Dec64, LeafBaseType::Empty,
|
||||||
|
LeafBaseType::Enum, LeafBaseType::IdentityRef, LeafBaseType::InstanceIdentifier,
|
||||||
|
LeafBaseType::Int8, LeafBaseType::Int16, LeafBaseType::Int32, LeafBaseType::Int64,
|
||||||
|
LeafBaseType::Leafref, LeafBaseType::String, LeafBaseType::Uint8, LeafBaseType::Uint16,
|
||||||
|
LeafBaseType::Uint32, LeafBaseType::Uint64, LeafBaseType::Union, LeafBaseType::Unknown}) {
|
||||||
|
result.emplace(i, [](string const& value) -> string const {
|
||||||
|
return value;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace yang
|
} // namespace yang
|
||||||
} // namespace isc
|
} // namespace isc
|
||||||
|
@@ -121,9 +121,9 @@ public:
|
|||||||
/// @param xpath the xpath to the YANG node without the last node
|
/// @param xpath the xpath to the YANG node without the last node
|
||||||
/// @param name the name of the YANG node which should also match the map
|
/// @param name the name of the YANG node which should also match the map
|
||||||
/// key in the JSON configuration
|
/// key in the JSON configuration
|
||||||
void checkAndJsonifyAndSetLeaf(isc::data::ConstElementPtr const& from,
|
void checkAndStringifyAndSetLeaf(isc::data::ConstElementPtr const& from,
|
||||||
std::string const& xpath,
|
std::string const& xpath,
|
||||||
std::string const& name);
|
std::string const& name);
|
||||||
|
|
||||||
/// @brief Get an element from given ElementPtr node and set it in sysrepo
|
/// @brief Get an element from given ElementPtr node and set it in sysrepo
|
||||||
/// at given xpath.
|
/// at given xpath.
|
||||||
@@ -132,7 +132,7 @@ public:
|
|||||||
/// @param xpath the xpath to the YANG node without the last node
|
/// @param xpath the xpath to the YANG node without the last node
|
||||||
/// @param name the name of the YANG node which should also match the map
|
/// @param name the name of the YANG node which should also match the map
|
||||||
/// key in the JSON configuration
|
/// key in the JSON configuration
|
||||||
/// @param type the sysrepo node type
|
/// @param type the YANG node type
|
||||||
void checkAndSetLeaf(isc::data::ConstElementPtr const& from,
|
void checkAndSetLeaf(isc::data::ConstElementPtr const& from,
|
||||||
std::string const& xpath,
|
std::string const& xpath,
|
||||||
std::string const& name,
|
std::string const& name,
|
||||||
@@ -148,7 +148,7 @@ public:
|
|||||||
/// @param xpath the xpath to the YANG node without the last node
|
/// @param xpath the xpath to the YANG node without the last node
|
||||||
/// @param name the name of the parameter to be set in storage
|
/// @param name the name of the parameter to be set in storage
|
||||||
/// @param yang_name the name by which to find the parameter in the YANG data node
|
/// @param yang_name the name by which to find the parameter in the YANG data node
|
||||||
/// @param type the sysrepo node type
|
/// @param type the YANG node type
|
||||||
void checkAndSetDivergingLeaf(isc::data::ConstElementPtr const& from,
|
void checkAndSetDivergingLeaf(isc::data::ConstElementPtr const& from,
|
||||||
std::string const& xpath,
|
std::string const& xpath,
|
||||||
std::string const& name,
|
std::string const& name,
|
||||||
@@ -158,10 +158,10 @@ public:
|
|||||||
/// @brief Get an element from given ElementPtr node and set it in sysrepo
|
/// @brief Get an element from given ElementPtr node and set it in sysrepo
|
||||||
/// at given xpath as a leaf-list.
|
/// at given xpath as a leaf-list.
|
||||||
///
|
///
|
||||||
/// @param from the parent configuration node from which to take the value
|
/// @param from the parent configuration node from which to take the values
|
||||||
/// @param xpath the xpath to the YANG node without the last node
|
/// @param xpath the xpath to the YANG node without the last node
|
||||||
/// @param name the name of the parameter to be set in storage
|
/// @param name the name of the parameter to be set in storage
|
||||||
/// @param type the sysrepo node type
|
/// @param type the YANG node type of the underlying leaf-list nodes
|
||||||
void checkAndSetLeafList(isc::data::ConstElementPtr const& from,
|
void checkAndSetLeafList(isc::data::ConstElementPtr const& from,
|
||||||
std::string const& xpath,
|
std::string const& xpath,
|
||||||
std::string const& name,
|
std::string const& name,
|
||||||
@@ -218,13 +218,6 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Checks whether a YANG node exists in the schema.
|
|
||||||
///
|
|
||||||
/// @param xpath the xpath to be checked
|
|
||||||
///
|
|
||||||
/// @return true if the YANG node exists in the schema, false otherwise
|
|
||||||
bool schemaNodeExists(std::string const& xpath) const;
|
|
||||||
|
|
||||||
/// @brief Get a YANG data node found at the given absolute xpath.
|
/// @brief Get a YANG data node found at the given absolute xpath.
|
||||||
///
|
///
|
||||||
/// @note This is a computationally expensive operation that makes a lookup in the sysrepo
|
/// @note This is a computationally expensive operation that makes a lookup in the sysrepo
|
||||||
@@ -325,6 +318,13 @@ public:
|
|||||||
std::string const& name,
|
std::string const& name,
|
||||||
std::string const& yang_name) const;
|
std::string const& yang_name) const;
|
||||||
|
|
||||||
|
/// @brief Checks whether a YANG node exists in the schema.
|
||||||
|
///
|
||||||
|
/// @param xpath the xpath to be checked
|
||||||
|
///
|
||||||
|
/// @return true if the YANG node exists in the schema, false otherwise
|
||||||
|
bool schemaNodeExists(std::string const& xpath) const;
|
||||||
|
|
||||||
/// @brief Translate and set basic value from JSON to YANG.
|
/// @brief Translate and set basic value from JSON to YANG.
|
||||||
///
|
///
|
||||||
/// @param xpath The xpath of the basic value.
|
/// @param xpath The xpath of the basic value.
|
||||||
@@ -341,7 +341,7 @@ public:
|
|||||||
/// @param xpath the xpath to the YANG node without the last node
|
/// @param xpath the xpath to the YANG node without the last node
|
||||||
/// @param name the name of the YANG node which should also match the map
|
/// @param name the name of the YANG node which should also match the map
|
||||||
/// key in the JSON configuration
|
/// key in the JSON configuration
|
||||||
/// @param type the sysrepo node type
|
/// @param type the YANG node type
|
||||||
void setMandatoryLeaf(isc::data::ConstElementPtr const& from,
|
void setMandatoryLeaf(isc::data::ConstElementPtr const& from,
|
||||||
std::string const& xpath,
|
std::string const& xpath,
|
||||||
std::string const& name,
|
std::string const& name,
|
||||||
@@ -355,7 +355,7 @@ public:
|
|||||||
/// @param name the name of the YANG node which should also match the map
|
/// @param name the name of the YANG node which should also match the map
|
||||||
/// key in the JSON configuration
|
/// key in the JSON configuration
|
||||||
/// @param yang_name the name by which to find the parameter in the YANG data node
|
/// @param yang_name the name by which to find the parameter in the YANG data node
|
||||||
/// @param type the sysrepo node type
|
/// @param type the YANG node type
|
||||||
void setMandatoryDivergingLeaf(isc::data::ConstElementPtr const& from,
|
void setMandatoryDivergingLeaf(isc::data::ConstElementPtr const& from,
|
||||||
std::string const& xpath,
|
std::string const& xpath,
|
||||||
std::string const& name,
|
std::string const& name,
|
||||||
|
@@ -523,7 +523,7 @@ TranslatorConfig::setServerKeaDhcpCommon(string const& xpath,
|
|||||||
|
|
||||||
checkAndSetLeafList(elem, xpath, "host-reservation-identifiers", LeafBaseType::Enum);
|
checkAndSetLeafList(elem, xpath, "host-reservation-identifiers", LeafBaseType::Enum);
|
||||||
|
|
||||||
checkAndJsonifyAndSetLeaf(elem, xpath, "dhcp-queue-control");
|
checkAndStringifyAndSetLeaf(elem, xpath, "dhcp-queue-control");
|
||||||
|
|
||||||
checkAndSetUserContext(elem, xpath);
|
checkAndSetUserContext(elem, xpath);
|
||||||
|
|
||||||
@@ -596,7 +596,7 @@ TranslatorConfig::setServerKeaDhcpCommon(string const& xpath,
|
|||||||
<< name->stringValue() << "']";
|
<< name->stringValue() << "']";
|
||||||
string const hook_xpath(hook_lib.str());
|
string const hook_xpath(hook_lib.str());
|
||||||
setItem(hook_xpath, ElementPtr(), LeafBaseType::Unknown);
|
setItem(hook_xpath, ElementPtr(), LeafBaseType::Unknown);
|
||||||
checkAndJsonifyAndSetLeaf(lib, hook_xpath, "parameters");
|
checkAndStringifyAndSetLeaf(lib, hook_xpath, "parameters");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -43,25 +43,75 @@ All translators take a Session pointer (a structure provided by Sysrepo that
|
|||||||
is responsible for maintaining a connection) in constructors and derive from
|
is responsible for maintaining a connection) in constructors and derive from
|
||||||
the basic / base class and recursively from translators for embedded parts.
|
the basic / base class and recursively from translators for embedded parts.
|
||||||
|
|
||||||
@c isc::yang::Translator provides some methods:
|
@c isc::yang::Translator provides several public methods:
|
||||||
|
|
||||||
|
- @c isc::yang::Translator::checkAndGet() is able to retrieve a YANG node that
|
||||||
|
can be retrieved through complex logic which is abstracted through a lambda.
|
||||||
|
|
||||||
- @c isc::yang::Translator::checkAndGetLeaf() is a convenience wrapper
|
- @c isc::yang::Translator::checkAndGetLeaf() is a convenience wrapper
|
||||||
over @c isc::yang::Translator::getItem().
|
over @c isc::yang::Translator::getItem().
|
||||||
|
|
||||||
|
- @c isc::yang::Translator::checkAndGetAndJsonifyLeaf() retrieves elements
|
||||||
|
that are strings in the YANG schema, but that require passing through
|
||||||
|
@c isc::data::Element::fromJSON() when translating to ElementPtr.
|
||||||
|
|
||||||
|
- @c isc::yang::Translator::checkAndStringifyAndSetLeaf() does the opposite of
|
||||||
|
@c isc::yang::Translator::checkAndGetAndJsonifyLeaf(). It takes an arbitrary
|
||||||
|
Element and sets it as a YANG string in sysrepo.
|
||||||
|
|
||||||
- @c isc::yang::Translator::checkAndSetLeaf() is a convenience wrapper
|
- @c isc::yang::Translator::checkAndSetLeaf() is a convenience wrapper
|
||||||
over @c isc::yang::Translator::setItem().
|
over @c isc::yang::Translator::setItem().
|
||||||
|
|
||||||
|
- @c isc::yang::Translator::checkAndSetLeafList() is able to push multiple
|
||||||
|
leaf list nodes to the same xpath to form a leaf list.
|
||||||
|
|
||||||
|
- @c isc::yang::Translator::checkAndSetUserContext() is specifically tailored
|
||||||
|
for setting user context in sysrepo. It's use is frequent enough to have
|
||||||
|
earned its own function.
|
||||||
|
|
||||||
- @c isc::yang::Translator::deleteItem() deletes the data node found at
|
- @c isc::yang::Translator::deleteItem() deletes the data node found at
|
||||||
given xpth.
|
given xpath.
|
||||||
|
|
||||||
|
- @c isc::yang::Translator::findXPath() retrieves any data node found at any
|
||||||
|
xpath. It is computationally intensive. Use sparingly.
|
||||||
|
|
||||||
- @c isc::yang::Translator::forAll() iterates over the node found at
|
- @c isc::yang::Translator::forAll() iterates over the node found at
|
||||||
given xpath and all its descendants and calls the given function.
|
given xpath and all its descendants and calls the given function.
|
||||||
|
|
||||||
|
- @c isc::yang::Translator::getData() retrieves any data node found at any
|
||||||
|
xpath. The difference from @c isc::yang::Translator::findXPath() is that it
|
||||||
|
does not throw if the data node is not found and instead returns nullopt.
|
||||||
|
|
||||||
- @c isc::yang::Translator::getItem() retrieves and translates a leaf
|
- @c isc::yang::Translator::getItem() retrieves and translates a leaf
|
||||||
from YANG to JSON.
|
from YANG to Element.
|
||||||
|
|
||||||
- @c isc::yang::Translator::getList() retrieves a list from Sysrepo and
|
- @c isc::yang::Translator::getList() retrieves a list from Sysrepo and
|
||||||
translates it form YANG to JSON.
|
translates it form YANG to Element.
|
||||||
- @c isc::yang::Translator::setItem() translates a leaf from JSON to
|
|
||||||
|
- @c isc::yang::Translator::getMandatoryLeaf() fetches a leaf that is expected
|
||||||
|
to be present in the YANG data node, most of the time a YANG key.
|
||||||
|
|
||||||
|
- @c isc::yang::Translator::schemaNodeExists() checks if an xpath is valid
|
||||||
|
from the YANG schema point of view. Not used anywhere, but it's here to
|
||||||
|
substitute logic that had been previously removed.
|
||||||
|
|
||||||
|
- @c isc::yang::Translator::setItem() translates a leaf from Element to
|
||||||
YANG and sets it in Sysrepo.
|
YANG and sets it in Sysrepo.
|
||||||
- @c isc::yang::Translator::translateFromYang(optional<DataNode>, string) translates a YANG
|
|
||||||
leaf to a JSON node.
|
- @c isc::yang::Translator::setMandatoryLeaf() sets a leaf that is expected
|
||||||
|
to be present in the Element node, most of the time a YANG key.
|
||||||
|
|
||||||
|
- @c isc::yang::Translator::translateFromYang(optional<DataNode>, string)
|
||||||
|
translates a YANG leaf to an Element node based on YANG type.
|
||||||
|
All YANG types are explicitly handled.
|
||||||
|
|
||||||
- @c isc::yang::Translator::translateToYang(ConstElementPtr, LeafBaseType)
|
- @c isc::yang::Translator::translateToYang(ConstElementPtr, LeafBaseType)
|
||||||
translates a JSON leaf to a string.
|
translates an Element leaf to a string based on the YANG type.
|
||||||
|
All YANG types are explicitly handled.
|
||||||
|
|
||||||
|
Some of these methods have a counterpart that have "Diverging" in their name.
|
||||||
|
They are exceptionally used in the case where YANG xpath and Element map key are
|
||||||
|
different. This facilitates identifying these diverging nodes.
|
||||||
|
|
||||||
@section yangTranslatorPool Pool translator
|
@section yangTranslatorPool Pool translator
|
||||||
|
|
||||||
@@ -85,8 +135,8 @@ some of them depend on other structures, for instance
|
|||||||
depends on the corresponding list item translator
|
depends on the corresponding list item translator
|
||||||
@c isc::yang::TranslatorOptionData. This multiple inheritance forms
|
@c isc::yang::TranslatorOptionData. This multiple inheritance forms
|
||||||
a graph with the basic and the configuration translators at the two ends.
|
a graph with the basic and the configuration translators at the two ends.
|
||||||
Multiple inheritance and its "diamond" issue are handled by C++ with
|
Multiple inheritance and its diamond issue are handled by C++ with
|
||||||
the "virtual" inheritance: depending classes must be virtually inherited
|
the virtual inheritance: depending classes must be virtually inherited
|
||||||
and explicitly constructed.
|
and explicitly constructed.
|
||||||
|
|
||||||
@section yangTranslatorSubnet Subnet translator
|
@section yangTranslatorSubnet Subnet translator
|
||||||
|
Reference in New Issue
Block a user