Exemplo n.º 1
0
void XMLDocMerger::fill_defaults(
          YangNode* ynode,
          XMLNode*  new_node,
          XMLNode*  update_node,
          bool*     update_required
       )
{
  YangNode* yn = nullptr;
  XMLNode*  xchild = nullptr;

  for (YangNodeIter it = ynode->child_begin();
       it != ynode->child_end(); ++it) {
    yn = &(*it);
    const char* default_val = yn->get_default_value();
    if (!default_val && !yn->has_default()) {
      // Only default values or containers with default leaf descendents
      continue;
    }

    // Default values may be within a choice/case. Check if the choice has
    // another case. If the same case is present
    YangNode* ychoice = yn->get_choice();
    YangNode* ycase = yn->get_case();
    YangNode* other_choice = nullptr;
    YangNode* other_case   = nullptr;
    bool add_default = true;
    bool subtree_update = false;
    if (ychoice && ycase && (ychoice->get_default_case() != ycase)) {
      add_default = false;
    }

    for (XMLNodeIter xit = new_node->child_begin();
         xit != new_node->child_end(); ++xit) {
      xchild = &(*xit);
      if (xchild->get_local_name() == yn->get_name() &&
          xchild->get_name_space() == yn->get_ns()) {
        if (yn->get_stmt_type() == RW_YANG_STMT_TYPE_CONTAINER) {
          // The container has a default descendant node
          XMLNode* update_child = nullptr;
          bool created = false;
          if ((update_child = update_node->find(
                                yn->get_name(), yn->get_ns())) == nullptr) {
            update_child = update_node->add_child(yn);
            created = true;
          }
          fill_defaults(yn, xchild, update_child, &subtree_update);
          if (!subtree_update && created) {
            update_node->remove_child(update_child);
          }
          *update_required = (*update_required || subtree_update);
        }
        // Default node already present in the new-dom
        add_default = false;
        break;
      }
      
      if (!ychoice) {
        // Not part of a choice
        continue;
      }

      other_choice = xchild->get_yang_node()->get_choice();
      if (!other_choice || (other_choice != ychoice)) {
        // Other node is not a choice, or not the same choice, not conflicting
        continue;
      }

      other_case = xchild->get_yang_node()->get_case();
      if (other_case && (ycase != other_case)) {
        // There is a node with conflicting case. Hence no default
        add_default = false;
        break;
      }

      // Same case, in-case the case is not default, some-other node in the same
      // case is set. Then add this default, unless the same node is found in
      // the new-dom.
      add_default = true;
    }
    if (add_default) {
      XMLNode* xn = new_node->add_child(yn, default_val);
      RW_ASSERT(xn);
      XMLNode* un = update_node->add_child(yn, default_val);
      if (yn->get_stmt_type() == RW_YANG_STMT_TYPE_CONTAINER) {
        // The container has a default descendant node
        fill_defaults(yn, xn, un, &subtree_update);
        if (!subtree_update) {
          new_node->remove_child(xn);
          update_node->remove_child(un);
        }
        *update_required = (*update_required || subtree_update);
      } else {
        *update_required = true;
      }
    }
  }
}
Exemplo n.º 2
0
rw_status_t get_confd_case ( rw_yang::XMLNode *root,
                             confd_hkeypath_t *keypath,
                             confd_value_t *choice,
                             confd_value_t *case_val)
{
  RW_ASSERT (case_val);
  rw_yang::XMLNode *node = get_node_by_hkeypath (root, keypath, 0);

  if (nullptr == node) {
    return RW_STATUS_FAILURE;
  }

  XMLNodeList::uptr_t children(node->get_children());

  for (size_t i = 0; i < children->length(); i++) {
    XMLNode* child = children->at(i);
    YangNode *yn = child->get_descend_yang_node();

    if (nullptr == yn) {
      continue;
    }

    YangNode *yn_case = yn->get_case();
    if (nullptr == yn_case) {
      continue;
    }

    // The comparision starts with the choice..
    YangNode *yn_choice = yn_case->get_choice();
    RW_ASSERT (yn_choice);

    while (choice->type != C_NOEXISTS) {

      RW_ASSERT (choice->type == C_XMLTAG);

      const char * tag = confd_hash2str (choice->val.xmltag.tag);
      int n_s = choice->val.xmltag.ns;
      const char *ns = confd_hash2str (n_s);

      if (strcmp (tag, yn_choice->get_name()) ||
          strcmp (ns, yn_choice->get_ns())) {
        break;
      }

      // The case matches - check if choice exists
      choice++;

      if (C_NOEXISTS == choice->type) {
        case_val->type = C_XMLTAG;
        case_val->val.xmltag.ns = n_s;
        case_val->val.xmltag.tag = confd_str2hash (yn_case->get_name());
        return RW_STATUS_SUCCESS;
      }

      RW_ASSERT (choice->type == C_XMLTAG);

      yn_case = yn_choice->get_case();

      // Can this be null??
      RW_ASSERT (yn_case);

      tag = confd_hash2str (choice->val.xmltag.tag);
      ns = confd_hash2str (choice->val.xmltag.ns);

      if (strcmp (tag, yn_case->get_name()) ||
          strcmp (ns, yn_case->get_ns())) {
        break;
      }
    }
  }

  return RW_STATUS_FAILURE;
}