LCOV - code coverage report
Current view: top level - ifmap - ifmap_encoder.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 59 72 81.9 %
Date: 2026-09-21 02:11:39 Functions: 10 11 90.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
       3             :  */
       4             : 
       5             : #include "ifmap/ifmap_encoder.h"
       6             : 
       7             : #include <sstream>
       8             : #include "ifmap/ifmap_link.h"
       9             : #include "ifmap/ifmap_object.h"
      10             : #include "ifmap/ifmap_update.h"
      11             : 
      12             : using namespace pugi;
      13             : using namespace std;
      14             : 
      15         585 : IFMapMessage::IFMapMessage() : op_type_(NONE), node_count_(0),
      16         195 :     objects_per_message_(kObjectsPerMessage) {
      17             :     // init empty document
      18         195 :     Open();
      19         195 : }
      20             : 
      21         311 : void IFMapMessage::Open() {
      22         311 :     xml_node iq = doc_.append_child("iq");
      23             :     // set iq (type, from, to) attributes
      24         311 :     iq.append_attribute("type") = "set";
      25         311 :     iq.append_attribute("from") = "network-control@contrailsystems.com";
      26         311 :     iq.append_attribute("to") = "";
      27         311 :     config_ = iq.append_child("config");
      28         311 : }
      29             : 
      30         118 : void IFMapMessage::Close() {
      31         118 :     ostringstream oss;
      32         118 :     doc_.save(oss);
      33         118 :     str_ = oss.str();
      34         118 : }
      35             : 
      36         118 : void IFMapMessage::SetReceiverInMsg(const std::string &cli_identifier) {
      37         118 :     xml_node iq = doc_.child("iq");
      38         118 :     assert(iq);
      39         118 :     xml_attribute iqattr = iq.attribute("to");
      40         118 :     assert(iqattr);
      41         118 :     std::string str(cli_identifier);
      42         118 :     str += "/config";
      43         118 :     iqattr.set_value(str.c_str());
      44         118 : }
      45             : 
      46           0 : void IFMapMessage::SetObjectsPerMessage(int num) {
      47           0 :     objects_per_message_ = num;
      48           0 : }
      49             : 
      50         892 : void IFMapMessage::EncodeUpdate(const IFMapUpdate *update) {
      51             :     // update is either of type UPDATE OR DELETE
      52         892 :     if (update->IsUpdate()) {
      53         892 :         if (op_type_ != UPDATE) {
      54         116 :             op_node_ = config_.append_child("update");
      55         116 :             op_type_ = UPDATE;
      56             :         }
      57         892 :         if (update->data().type == IFMapObjectPtr::NODE) {
      58         434 :             EncodeNode(update);
      59         458 :         } else if (update->data().type == IFMapObjectPtr::LINK) {
      60         458 :             EncodeLink(update);
      61             :         } else {
      62           0 :             assert(0);
      63             :         }
      64             :     } else {
      65           0 :         if (op_type_ != DEL) {
      66           0 :             op_node_ = config_.append_child("delete");
      67           0 :             op_type_ = DEL;
      68             :         }
      69           0 :         if (update->data().type == IFMapObjectPtr::NODE) {
      70           0 :             EncodeNode(update);
      71           0 :         } else if (update->data().type == IFMapObjectPtr::LINK) {
      72           0 :             EncodeLink(update);
      73             :         } else {
      74           0 :             assert(0);
      75             :         }
      76             :     }
      77         892 :     node_count_++;
      78         892 : }
      79             : 
      80         434 : void IFMapMessage::EncodeNode(const IFMapUpdate *update) {
      81         434 :     IFMapNode *node = update->data().u.node;
      82         434 :     if (update->IsUpdate()) {
      83         434 :         node->EncodeNodeDetail(&op_node_);
      84             :     } else {
      85           0 :         node->EncodeNode(&op_node_);
      86             :     }
      87         434 : }
      88             : 
      89         458 : void IFMapMessage::EncodeLink(const IFMapUpdate *update) {
      90         458 :     xml_node link_node = op_node_.append_child("link");
      91             : 
      92         458 :     const IFMapLink *link = update->data().u.link;
      93             : 
      94         458 :     IFMapNode::EncodeNode(link->left_id(), &link_node);
      95         458 :     IFMapNode::EncodeNode(link->right_id(), &link_node);
      96         458 :     link->EncodeLinkInfo(&link_node);
      97             : 
      98         458 :     node_count_++;
      99         458 : }
     100             : 
     101         892 : bool IFMapMessage::IsFull() {
     102         892 :     return ((node_count_ >= objects_per_message_) ? true : false);
     103             : }
     104             : 
     105         176 : bool IFMapMessage::IsEmpty() {
     106         176 :     return ((node_count_ == 0) ? true : false);
     107             : }
     108             : 
     109             : //
     110             : // Reset the IFMapMessage to initial state so that it can be used to build
     111             : // the next config message.
     112             : //
     113             : // Using remove_child to remove the only child of the document is a better
     114             : // way to clear the document than using reset. The pugixml library allocates
     115             : // memory for a document in increments of 32KB pages and then manages smaller
     116             : // allocations (nodes or attributes) using these pages. Calling reset method
     117             : // on a document frees all the pages. In contrast, removing the only child
     118             : // node of the document returns the smaller allocations to the free pool of
     119             : // memory for the document, but doesn't free the pages themselves. This lets
     120             : // the library reuse the same memory when building the tree for each message.
     121             : //
     122         116 : void IFMapMessage::Reset() {
     123         116 :     doc_.remove_child("iq");
     124         116 :     node_count_ = 0;
     125         116 :     op_type_ = NONE;
     126         116 :     Open();
     127         116 : }

Generated by: LCOV version 1.14