LCOV - code coverage report
Current view: top level - root/contrail/src/contrail-common/base - proto.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 133 144 92.4 %
Date: 2026-08-24 02:06:43 Functions: 28 29 96.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
       3             :  */
       4             : 
       5             : #include "base/proto.h"
       6             : 
       7             : #include <boost/bind/bind.hpp>
       8             : 
       9             : using namespace std;
      10             : using namespace boost::placeholders;
      11             : 
      12             : namespace detail {
      13             :     bool debug_ = false;
      14             : }
      15             : 
      16             : struct ParseContext::StackFrame {
      17     2646358 :     StackFrame() : offset(0), lensize(0), size(-1), total_size(-1) {
      18     2646292 :     }
      19             :     int offset; // offset of the data pointer at present
      20             :     int lensize; //size of the length of the current element being parsed
      21             :     size_t size;
      22             :     size_t total_size;
      23             :     std::unique_ptr<ParseObject> data;
      24             : };
      25             : 
      26      197014 : ParseContext::ParseContext()
      27      197014 :     : offset_(0) {
      28      197012 : }
      29             : 
      30             : struct deleter {
      31             :     template <typename T>
      32      197391 :     void operator()(T *ptr) {
      33      197391 :         delete ptr;
      34      197393 :     }
      35             : };
      36             : 
      37      196999 : ParseContext::~ParseContext() {
      38      196999 :     for_each(stack_.begin(), stack_.end(), deleter());
      39      197001 :     stack_.clear();
      40      197002 : }
      41             : 
      42      189462 : ParseObject *ParseContext::release() {
      43      189462 :     if (stack_.empty()) {
      44           0 :         return NULL;
      45             :     }
      46      189464 :     StackFrame *current = stack_.back();
      47      189463 :     return current->data.release();
      48             : }
      49             : 
      50     2646313 : void ParseContext::Push(ParseObject *data) {
      51     2646313 :     StackFrame *frame = new StackFrame();
      52     2646288 :     frame->data.reset(data);
      53     2646172 :     stack_.push_back(frame);
      54     2646240 : }
      55             : 
      56     2638365 : ParseObject *ParseContext::Pop() {
      57     2638365 :     if (stack_.size() <= 1) {
      58      189456 :         return NULL;
      59             :     }
      60     2448900 :     StackFrame *frame = stack_.back();
      61     2448894 :     ParseObject *obj = frame->data.release();
      62     2448874 :     stack_.pop_back();
      63     2448878 :     delete frame;
      64     2448908 :     return obj;
      65             : }
      66             : 
      67      659336 : void ParseContext::ReleaseData() {
      68      659336 :     if (!stack_.empty()) {
      69      659329 :         StackFrame *frame = stack_.back();
      70      659320 :         frame->data.release();
      71             :     }
      72      659306 : }
      73     1285254 : void ParseContext::SwapData(ParseObject *obj) {
      74     1285254 :     if (!stack_.empty() && obj) {
      75     1285231 :         StackFrame *frame = stack_.back();
      76     1285210 :         frame->data.reset(obj);
      77             :     } else {
      78           0 :         delete obj;
      79             :     }
      80     1285217 : }
      81             : 
      82           0 : ParseObject *ParseContext::data() {
      83           0 :     if (stack_.empty()) {
      84           0 :         return NULL;
      85             :     }
      86           0 :     StackFrame *current = stack_.back();
      87           0 :     return current->data.get();
      88             : }
      89             : 
      90     9215132 : void ParseContext::advance(int delta) {
      91     9215132 :     if (!stack_.empty()) {
      92     8632525 :         stack_.back()->offset += delta;
      93             :     }
      94     9214266 :     offset_ += delta;
      95     9214266 : }
      96             : 
      97     2151249 : void ParseContext::set_lensize(int length) {
      98     2151249 :     if (!stack_.empty()) {
      99     2151219 :         StackFrame *current = stack_.back();
     100     2151210 :         current->lensize = length;
     101             :     }
     102     2151209 : }
     103             : 
     104     3267450 : int ParseContext::lensize() const {
     105     3267450 :     if (stack_.empty()) {
     106           0 :         return -1;
     107             :     }
     108     3267438 :     StackFrame *current = stack_.back();
     109     3267412 :     return current->lensize;
     110             : }
     111             : 
     112     7237036 : void ParseContext::set_size(size_t length) {
     113     7237036 :     if (!stack_.empty()) {
     114     6847948 :         StackFrame *current = stack_.back();
     115     6847871 :         current->size = length;
     116             :     }
     117     7236743 : }
     118             : 
     119    23484639 : size_t ParseContext::size() const {
     120    23484639 :     if (stack_.empty()) {
     121      975227 :         return -1;
     122             :     }
     123    22506702 :     StackFrame *current = stack_.back();
     124    22506062 :     return current->size;
     125             : }
     126             : 
     127     2780065 : void ParseContext::set_total_size() {
     128     2780065 :     if (!stack_.empty()) {
     129     2780044 :         StackFrame *current = stack_.back();
     130     2780032 :         current->total_size = current->size;
     131             :     }
     132     2780031 : }
     133             : 
     134       86613 : size_t ParseContext::total_size() const {
     135       86613 :     if (stack_.empty()) {
     136           0 :         return -1;
     137             :     }
     138       86612 :     StackFrame *current = stack_.back();
     139       86612 :     return current->total_size >= 0 ? current->total_size : current->size;
     140             : }
     141             : 
     142        7840 : void ParseContext::SetError(int error, int subcode, std::string type,
     143             :                             const uint8_t *data, int data_size) {
     144        7840 :     if (error_context_.error_code) {
     145             :         // Error already set. Ignore this one.
     146         300 :         return;
     147             :     }
     148        7540 :     error_context_.error_code = error;
     149        7540 :     error_context_.error_subcode = subcode;
     150        7540 :     error_context_.type_name = type;
     151        7540 :     error_context_.data = data;
     152        7540 :     error_context_.data_size = data_size;
     153             : }
     154             : 
     155             : struct EncodeContext::StackFrame {
     156             :     typedef boost::function<void(EncodeContext *)> CallbackFn;
     157             :     typedef std::vector<CallbackFn>::iterator CallbackIterator;
     158     5075627 :     StackFrame() : offset(0) {
     159     5075213 :     }
     160             :     int offset;
     161             :     std::vector<CallbackFn> callbacks;
     162             : };
     163             : 
     164      275339 : EncodeContext::EncodeContext() {
     165      275323 : }
     166             : 
     167      275361 : EncodeContext::~EncodeContext() {
     168      275361 : }
     169             : 
     170     5075052 : void EncodeContext::Push() {
     171     5075052 :     StackFrame *frame = new StackFrame();
     172     5075173 :     stack_.push_back(frame);
     173     5073563 : }
     174             : 
     175     5074648 : void EncodeContext::Pop(bool callback) {
     176     5074648 :     StackFrame *frame = &stack_.back();
     177     5073762 :     if (callback) {
     178     5073692 :         for (StackFrame::CallbackIterator iter =
     179    12583483 :              frame->callbacks.begin(); iter != frame->callbacks.end(); ++iter) {
     180     2436106 :             StackFrame::CallbackFn cb = *iter;
     181     2436168 :             (cb)(this);
     182     2435910 :         }
     183             :     }
     184             : 
     185     5074093 :     int p_offset = frame->offset;
     186     5074093 :     stack_.pop_back();                  // deletes frame
     187     5073931 :     if (!stack_.empty()) {
     188     4798554 :         StackFrame *top = &(stack_.back());
     189     4797770 :         top->offset += p_offset;
     190             :     }
     191     5072659 : }
     192             : 
     193     8593590 : void EncodeContext::advance(int delta) {
     194     8593590 :     if (stack_.empty()) {
     195           0 :         return;
     196             :     }
     197     8591626 :     StackFrame *frame = &stack_.back();
     198     8589023 :     frame->offset += delta;
     199             : }
     200             : 
     201     2199476 : int EncodeContext::length() const {
     202     2199476 :     const StackFrame *frame = &stack_.back();
     203     2199287 :     return frame->offset;
     204             : };
     205             : 
     206     2436595 : void EncodeContext::AddCallback(CallbackType cb, uint8_t *data,
     207             :                                 int element_size) {
     208     2436595 :     StackFrame *top = &(stack_.back());
     209     2436380 :     top->callbacks.push_back(
     210     4872212 :         boost::bind(cb, _1, data, top->offset, element_size));
     211     2435748 : }
     212             : 
     213      574693 : void EncodeOffsets::SaveOffset(std::string key, int offset) {
     214             :     std::pair<std::map<std::string, int>::iterator, bool > result =
     215      574693 :             offsets_.insert(make_pair(key, offset));
     216      574788 :     if (!result.second) {
     217           4 :         PROTO_DEBUG("Offset for " << key << " already set");
     218             :     }
     219      574788 : }
     220             : 
     221      574622 : void EncodeContext::SaveOffset(std::string key) {
     222      574622 :     int length = 0;
     223      574622 :     for (boost::ptr_vector<StackFrame>::iterator it = stack_.begin();
     224     2215938 :          it != stack_.end(); ++it) {
     225     1641326 :         length += it->offset;
     226             :     }
     227      574542 :     PROTO_DEBUG("Saving Offset for " << key << " at " << length);
     228      574542 :     offsets_.SaveOffset(key, length);
     229      574794 : }
     230             : 
     231      184907 : int EncodeOffsets::FindOffset(const char *key) {
     232      184907 :     std::map<std::string, int>::iterator it = offsets_.find(std::string(key));
     233      184903 :     if (it == offsets_.end())
     234           0 :         return -1;
     235      184902 :     return it->second;
     236             : }

Generated by: LCOV version 1.14