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-06-04 02:06:09 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         573 : IFMapMessage::IFMapMessage() : op_type_(NONE), node_count_(0),
      16         191 :     objects_per_message_(kObjectsPerMessage) {
      17             :     // init empty document
      18         191 :     Open();
      19         191 : }
      20             : 
      21         304 : void IFMapMessage::Open() {
      22         304 :     xml_node iq = doc_.append_child("iq");
      23             :     // set iq (type, from, to) attributes
      24         304 :     iq.append_attribute("type") = "set";
      25         304 :     iq.append_attribute("from") = "network-control@contrailsystems.com";
      26         304 :     iq.append_attribute("to") = "";
      27         304 :     config_ = iq.append_child("config");
      28         304 : }
      29             : 
      30         115 : void IFMapMessage::Close() {
      31         115 :     ostringstream oss;
      32         115 :     doc_.save(oss);
      33         115 :     str_ = oss.str();
      34         115 : }
      35             : 
      36         115 : void IFMapMessage::SetReceiverInMsg(const std::string &cli_identifier) {
      37         115 :     xml_node iq = doc_.child("iq");
      38         115 :     assert(iq);
      39         115 :     xml_attribute iqattr = iq.attribute("to");
      40         115 :     assert(iqattr);
      41         115 :     std::string str(cli_identifier);
      42         115 :     str += "/config";
      43         115 :     iqattr.set_value(str.c_str());
      44         115 : }
      45             : 
      46           0 : void IFMapMessage::SetObjectsPerMessage(int num) {
      47           0 :     objects_per_message_ = num;
      48           0 : }
      49             : 
      50         901 : void IFMapMessage::EncodeUpdate(const IFMapUpdate *update) {
      51             :     // update is either of type UPDATE OR DELETE
      52         901 :     if (update->IsUpdate()) {
      53         901 :         if (op_type_ != UPDATE) {
      54         113 :             op_node_ = config_.append_child("update");
      55         113 :             op_type_ = UPDATE;
      56             :         }
      57         901 :         if (update->data().type == IFMapObjectPtr::NODE) {
      58         433 :             EncodeNode(update);
      59         468 :         } else if (update->data().type == IFMapObjectPtr::LINK) {
      60         468 :             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         901 :     node_count_++;
      78         901 : }
      79             : 
      80         433 : void IFMapMessage::EncodeNode(const IFMapUpdate *update) {
      81         433 :     IFMapNode *node = update->data().u.node;
      82         433 :     if (update->IsUpdate()) {
      83         433 :         node->EncodeNodeDetail(&op_node_);
      84             :     } else {
      85           0 :         node->EncodeNode(&op_node_);
      86             :     }
      87         433 : }
      88             : 
      89         468 : void IFMapMessage::EncodeLink(const IFMapUpdate *update) {
      90         468 :     xml_node link_node = op_node_.append_child("link");
      91             : 
      92         468 :     const IFMapLink *link = update->data().u.link;
      93             : 
      94         468 :     IFMapNode::EncodeNode(link->left_id(), &link_node);
      95         468 :     IFMapNode::EncodeNode(link->right_id(), &link_node);
      96         468 :     link->EncodeLinkInfo(&link_node);
      97             : 
      98         468 :     node_count_++;
      99         468 : }
     100             : 
     101         901 : bool IFMapMessage::IsFull() {
     102         901 :     return ((node_count_ >= objects_per_message_) ? true : false);
     103             : }
     104             : 
     105         168 : bool IFMapMessage::IsEmpty() {
     106         168 :     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         113 : void IFMapMessage::Reset() {
     123         113 :     doc_.remove_child("iq");
     124         113 :     node_count_ = 0;
     125         113 :     op_type_ = NONE;
     126         113 :     Open();
     127         113 : }

Generated by: LCOV version 1.14