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

Generated by: LCOV version 1.14