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-11-09 02:10:49 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             :  * Copyright Contributors to the OpenSDN project
       4             :  */
       5             : 
       6             : #include "base/proto.h"
       7             : 
       8             : #include <boost/bind/bind.hpp>
       9             : 
      10             : using namespace std;
      11             : using namespace boost::placeholders;
      12             : 
      13             : namespace detail {
      14             :     bool debug_ = false;
      15             : }
      16             : 
      17             : struct ParseContext::StackFrame {
      18     2643977 :     StackFrame() : offset(0), lensize(0), size(-1), total_size(-1) {
      19     2643935 :     }
      20             :     int offset; // offset of the data pointer at present
      21             :     int lensize; //size of the length of the current element being parsed
      22             :     size_t size;
      23             :     size_t total_size;
      24             :     std::unique_ptr<ParseObject> data;
      25             : };
      26             : 
      27      196469 : ParseContext::ParseContext()
      28      196469 :     : offset_(0) {
      29      196466 : }
      30             : 
      31             : struct deleter {
      32             :     template <typename T>
      33      196843 :     void operator()(T *ptr) {
      34      196843 :         delete ptr;
      35      196850 :     }
      36             : };
      37             : 
      38      196454 : ParseContext::~ParseContext() {
      39      196454 :     for_each(stack_.begin(), stack_.end(), deleter());
      40      196454 :     stack_.clear();
      41      196453 : }
      42             : 
      43      188915 : ParseObject *ParseContext::release() {
      44      188915 :     if (stack_.empty()) {
      45           0 :         return NULL;
      46             :     }
      47      188914 :     StackFrame *current = stack_.back();
      48      188914 :     return current->data.release();
      49             : }
      50             : 
      51     2643919 : void ParseContext::Push(ParseObject *data) {
      52     2643919 :     StackFrame *frame = new StackFrame();
      53     2643934 :     frame->data.reset(data);
      54     2643842 :     stack_.push_back(frame);
      55     2643900 : }
      56             : 
      57     2635946 : ParseObject *ParseContext::Pop() {
      58     2635946 :     if (stack_.size() <= 1) {
      59      188909 :         return NULL;
      60             :     }
      61     2447038 :     StackFrame *frame = stack_.back();
      62     2447033 :     ParseObject *obj = frame->data.release();
      63     2447007 :     stack_.pop_back();
      64     2447012 :     delete frame;
      65     2447072 :     return obj;
      66             : }
      67             : 
      68      658463 : void ParseContext::ReleaseData() {
      69      658463 :     if (!stack_.empty()) {
      70      658464 :         StackFrame *frame = stack_.back();
      71      658460 :         frame->data.release();
      72             :     }
      73      658443 : }
      74     1283902 : void ParseContext::SwapData(ParseObject *obj) {
      75     1283902 :     if (!stack_.empty() && obj) {
      76     1283871 :         StackFrame *frame = stack_.back();
      77     1283855 :         frame->data.reset(obj);
      78             :     } else {
      79           0 :         delete obj;
      80             :     }
      81     1283849 : }
      82             : 
      83           0 : ParseObject *ParseContext::data() {
      84           0 :     if (stack_.empty()) {
      85           0 :         return NULL;
      86             :     }
      87           0 :     StackFrame *current = stack_.back();
      88           0 :     return current->data.get();
      89             : }
      90             : 
      91     9206166 : void ParseContext::advance(int delta) {
      92     9206166 :     if (!stack_.empty()) {
      93     8625139 :         stack_.back()->offset += delta;
      94             :     }
      95     9205172 :     offset_ += delta;
      96     9205172 : }
      97             : 
      98     2150052 : void ParseContext::set_lensize(int length) {
      99     2150052 :     if (!stack_.empty()) {
     100     2150028 :         StackFrame *current = stack_.back();
     101     2150006 :         current->lensize = length;
     102             :     }
     103     2150006 : }
     104             : 
     105     3264508 : int ParseContext::lensize() const {
     106     3264508 :     if (stack_.empty()) {
     107           0 :         return -1;
     108             :     }
     109     3264487 :     StackFrame *current = stack_.back();
     110     3264477 :     return current->lensize;
     111             : }
     112             : 
     113     7229732 : void ParseContext::set_size(size_t length) {
     114     7229732 :     if (!stack_.empty()) {
     115     6841678 :         StackFrame *current = stack_.back();
     116     6841567 :         current->size = length;
     117             :     }
     118     7229319 : }
     119             : 
     120    23462733 : size_t ParseContext::size() const {
     121    23462733 :     if (stack_.empty()) {
     122      972530 :         return -1;
     123             :     }
     124    22487232 :     StackFrame *current = stack_.back();
     125    22486102 :     return current->size;
     126             : }
     127             : 
     128     2778296 : void ParseContext::set_total_size() {
     129     2778296 :     if (!stack_.empty()) {
     130     2778259 :         StackFrame *current = stack_.back();
     131     2778244 :         current->total_size = current->size;
     132             :     }
     133     2778244 : }
     134             : 
     135       86536 : size_t ParseContext::total_size() const {
     136       86536 :     if (stack_.empty()) {
     137           0 :         return -1;
     138             :     }
     139       86538 :     StackFrame *current = stack_.back();
     140       86536 :     return current->total_size >= 0 ? current->total_size : current->size;
     141             : }
     142             : 
     143        7840 : void ParseContext::SetError(int error, int subcode, std::string type,
     144             :                             const uint8_t *data, int data_size) {
     145        7840 :     if (error_context_.error_code) {
     146             :         // Error already set. Ignore this one.
     147         300 :         return;
     148             :     }
     149        7540 :     error_context_.error_code = error;
     150        7540 :     error_context_.error_subcode = subcode;
     151        7540 :     error_context_.type_name = type;
     152        7540 :     error_context_.data = data;
     153        7540 :     error_context_.data_size = data_size;
     154             : }
     155             : 
     156             : struct EncodeContext::StackFrame {
     157             :     typedef boost::function<void(EncodeContext *)> CallbackFn;
     158             :     typedef std::vector<CallbackFn>::iterator CallbackIterator;
     159     5065221 :     StackFrame() : offset(0) {
     160     5065189 :     }
     161             :     int offset;
     162             :     std::vector<CallbackFn> callbacks;
     163             : };
     164             : 
     165      275751 : EncodeContext::EncodeContext() {
     166      275741 : }
     167             : 
     168      275762 : EncodeContext::~EncodeContext() {
     169      275762 : }
     170             : 
     171     5064622 : void EncodeContext::Push() {
     172     5064622 :     StackFrame *frame = new StackFrame();
     173     5065172 :     stack_.push_back(frame);
     174     5063361 : }
     175             : 
     176     5064034 : void EncodeContext::Pop(bool callback) {
     177     5064034 :     StackFrame *frame = &stack_.back();
     178     5062755 :     if (callback) {
     179     5062578 :         for (StackFrame::CallbackIterator iter =
     180    12554027 :              frame->callbacks.begin(); iter != frame->callbacks.end(); ++iter) {
     181     2428671 :             StackFrame::CallbackFn cb = *iter;
     182     2428753 :             (cb)(this);
     183     2428421 :         }
     184             :     }
     185             : 
     186     5063157 :     int p_offset = frame->offset;
     187     5063157 :     stack_.pop_back();                  // deletes frame
     188     5063422 :     if (!stack_.empty()) {
     189     4787593 :         StackFrame *top = &(stack_.back());
     190     4786447 :         top->offset += p_offset;
     191             :     }
     192     5061689 : }
     193             : 
     194     8572870 : void EncodeContext::advance(int delta) {
     195     8572870 :     if (stack_.empty()) {
     196           0 :         return;
     197             :     }
     198     8570901 :     StackFrame *frame = &stack_.back();
     199     8566474 :     frame->offset += delta;
     200             : }
     201             : 
     202     2192141 : int EncodeContext::length() const {
     203     2192141 :     const StackFrame *frame = &stack_.back();
     204     2191893 :     return frame->offset;
     205             : };
     206             : 
     207     2429601 : void EncodeContext::AddCallback(CallbackType cb, uint8_t *data,
     208             :                                 int element_size) {
     209     2429601 :     StackFrame *top = &(stack_.back());
     210     2429169 :     top->callbacks.push_back(
     211     4857738 :         boost::bind(cb, _1, data, top->offset, element_size));
     212     2428477 : }
     213             : 
     214      572925 : void EncodeOffsets::SaveOffset(std::string key, int offset) {
     215             :     std::pair<std::map<std::string, int>::iterator, bool > result =
     216      572925 :             offsets_.insert(make_pair(key, offset));
     217      573170 :     if (!result.second) {
     218           4 :         PROTO_DEBUG("Offset for " << key << " already set");
     219             :     }
     220      573170 : }
     221             : 
     222      572890 : void EncodeContext::SaveOffset(std::string key) {
     223      572890 :     int length = 0;
     224      572890 :     for (boost::ptr_vector<StackFrame>::iterator it = stack_.begin();
     225     2211144 :          it != stack_.end(); ++it) {
     226     1638271 :         length += it->offset;
     227             :     }
     228      572713 :     PROTO_DEBUG("Saving Offset for " << key << " at " << length);
     229      572713 :     offsets_.SaveOffset(key, length);
     230      573168 : }
     231             : 
     232      190165 : int EncodeOffsets::FindOffset(const char *key) {
     233      190165 :     std::map<std::string, int>::iterator it = offsets_.find(std::string(key));
     234      190149 :     if (it == offsets_.end())
     235           0 :         return -1;
     236      190147 :     return it->second;
     237             : }

Generated by: LCOV version 1.14