LCOV - code coverage report
Current view: top level - root/contrail/src/contrail-common/sandesh/library/cpp/protocol - TJSONProtocol.h (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 0 17 0.0 %
Date: 2026-08-03 02:19:58 Functions: 0 2 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2018 Juniper Networks, Inc. All rights reserved.
       3             :  */
       4             : 
       5             : #ifndef _SANDESH_PROTOCOL_TJSONPROTOCOL_H_
       6             : #define _SANDESH_PROTOCOL_TJSONPROTOCOL_H_ 1
       7             : 
       8             : #include <string.h>
       9             : #include "TVirtualProtocol.h"
      10             : 
      11             : #include <boost/shared_ptr.hpp>
      12             : #include <boost/tokenizer.hpp>
      13             : #include <boost/algorithm/string.hpp>
      14             : #include <boost/algorithm/string/replace.hpp>
      15             : #include <boost/container/set.hpp>
      16             : #include <base/time_util.h>
      17             : 
      18             : namespace contrail { namespace sandesh { namespace protocol {
      19             : 
      20             : /**
      21             :  * Protocol that prints the payload in JSON format.
      22             :  */
      23             : class TJSONProtocol : public TVirtualProtocol<TJSONProtocol> {
      24             :  private:
      25             :   enum write_state_t
      26             :   { UNINIT
      27             :   , STRUCT
      28             :   , LIST
      29             :   , SET
      30             :   , MAP
      31             :   , SNDESH
      32             :   };
      33             : 
      34             :  public:
      35             :   TJSONProtocol(boost::shared_ptr<TTransport> trans)
      36             :     : TVirtualProtocol<TJSONProtocol>(trans)
      37             :     , trans_(trans.get())
      38             :     , string_limit_(DEFAULT_STRING_LIMIT)
      39             :     , string_prefix_size_(DEFAULT_STRING_PREFIX_SIZE)
      40             :     , reader_(*trans)
      41             :   {
      42             :     TType ttypes_arr[] = { T_STRUCT, T_MAP, T_SET, T_LIST, T_SANDESH };
      43             :     complexTypeSet[T_STRUCT] = true;
      44             :     complexTypeSet[T_MAP] = true;
      45             :     complexTypeSet[T_SET] = true;
      46             :     complexTypeSet[T_LIST] = true;
      47             :     write_state_.push_back(UNINIT);
      48             :   }
      49             : 
      50             :   static const int32_t DEFAULT_STRING_LIMIT = 256;
      51             :   static const int32_t DEFAULT_STRING_PREFIX_SIZE = 16;
      52             : 
      53             :   void setStringSizeLimit(int32_t string_limit) {
      54             :     string_limit_ = string_limit;
      55             :   }
      56             : 
      57             :   void setStringPrefixSize(int32_t string_prefix_size) {
      58             :     string_prefix_size_ = string_prefix_size;
      59             :   }
      60             : 
      61           0 :   static std::string escapeJSONControlCharsInternal(const std::string& str) {
      62           0 :     std::string xmlstr;
      63           0 :     xmlstr.reserve(str.length());
      64           0 :     for (std::string::const_iterator it = str.begin();
      65           0 :          it != str.end(); ++it) {
      66           0 :       switch(*it) {
      67           0 :        case '&':  xmlstr += "&amp;";  break;
      68           0 :        case '\'': xmlstr += "&apos;"; break;
      69           0 :        case '<':  xmlstr += "&lt;";   break;
      70           0 :        case '>':  xmlstr += "&gt;";   break;
      71           0 :        default:   xmlstr += *it;
      72             :       }
      73             :     }
      74           0 :     return xmlstr;
      75           0 :   }
      76             : 
      77           0 :   static std::string escapeJSONControlChars(const std::string& str) {
      78           0 :     if (strpbrk(str.c_str(), "&'<>") != NULL) {
      79           0 :       return escapeJSONControlCharsInternal(str);
      80             :     } else {
      81           0 :       return str;
      82             :     }
      83             :   }
      84             : 
      85             :   static void unescapeJSONControlChars(std::string& str) {
      86             :       boost::algorithm::replace_all(str, "&amp;", "&");
      87             :       boost::algorithm::replace_all(str, "&apos;", "\'");
      88             :       boost::algorithm::replace_all(str, "&lt;", "<");
      89             :       boost::algorithm::replace_all(str, "&gt;", ">");
      90             :   }
      91             : 
      92             :   /**
      93             :    * Writing functions
      94             :    */
      95             : 
      96             :   int32_t writeMessageBegin(const std::string& name,
      97             :                             const TMessageType messageType,
      98             :                             const int32_t seqid);
      99             : 
     100             :   int32_t writeMessageEnd();
     101             : 
     102             :   int32_t writeStructBegin(const char* name);
     103             : 
     104             :   int32_t writeStructEnd();
     105             : 
     106             :   int32_t writeSandeshBegin(const char* name);
     107             : 
     108             :   int32_t writeSandeshEnd();
     109             : 
     110             :   int32_t writeContainerElementBegin();
     111             : 
     112             :   int32_t writeContainerElementEnd();
     113             : 
     114             :   int32_t writeFieldBegin(const char* name,
     115             :                           const TType fieldType,
     116             :                           const int16_t fieldId,
     117             :                           const std::map<std::string, std::string> *const amap = NULL);
     118             : 
     119             :   int32_t writeFieldEnd();
     120             : 
     121             :   int32_t writeFieldStop();
     122             : 
     123             :   int32_t writeMapBegin(const TType keyType,
     124             :                         const TType valType,
     125             :                         const uint32_t size);
     126             : 
     127             :   int32_t writeMapEnd();
     128             : 
     129             :   int32_t writeListBegin(const TType elemType,
     130             :                          const uint32_t size);
     131             : 
     132             :   int32_t writeListEnd();
     133             : 
     134             :   int32_t writeSetBegin(const TType elemType,
     135             :                         const uint32_t size);
     136             : 
     137             :   int32_t writeSetEnd();
     138             : 
     139             :   int32_t writeBool(const bool value);
     140             : 
     141             :   int32_t writeByte(const int8_t byte);
     142             : 
     143             :   int32_t writeI16(const int16_t i16);
     144             : 
     145             :   int32_t writeI32(const int32_t i32);
     146             : 
     147             :   int32_t writeI64(const int64_t i64);
     148             : 
     149             :   int32_t writeU16(const uint16_t u16);
     150             : 
     151             :   int32_t writeU32(const uint32_t u32);
     152             :   
     153             :   int32_t writeU64(const uint64_t u64);
     154             : 
     155             :   int32_t writeIPV4(const uint32_t ip4);
     156             : 
     157             :   int32_t writeIPADDR(const boost::asio::ip::address& ipaddress);
     158             :   
     159             :   int32_t writeDouble(const double dub);
     160             : 
     161             :   int32_t writeString(const std::string& str);
     162             : 
     163             :   int32_t writeBinary(const std::string& str);
     164             : 
     165             :   int32_t writeJSON(const std::string& str);
     166             : 
     167             :   int32_t writeUUID(const boost::uuids::uuid& uuid);
     168             : 
     169             :   /**
     170             :    * Reading functions
     171             :    */
     172             :   void setSandeshEnd(bool val) {
     173             :       sandesh_end_ = val;
     174             :   }
     175             : 
     176             :   class LookaheadReader {
     177             : 
     178             :    public:
     179             : 
     180             :     LookaheadReader(TTransport &trans) :
     181             :       trans_(&trans),
     182             :       hasData_(false),
     183             :       has2Data_(false),
     184             :       firstRead_(false) {
     185             :     }
     186             : 
     187             :     uint8_t read() {
     188             :       if (hasData_) {
     189             :         hasData_ = false;
     190             :       }
     191             :       else {
     192             :         if (has2Data_) {
     193             :           if (firstRead_) {
     194             :             has2Data_ = false;
     195             :             firstRead_ = false;
     196             :             return data2_[1];
     197             :           } else {
     198             :             firstRead_ = true;
     199             :             return data2_[0];
     200             :           }
     201             :         } else {
     202             :           trans_->readAll(&data_, 1);
     203             :         }
     204             :       }
     205             :       return data_;
     206             :     }
     207             : 
     208             :     uint8_t peek() {
     209             :       if (!hasData_) {
     210             :         trans_->readAll(&data_, 1);
     211             :       }
     212             :       hasData_ = true;
     213             :       return data_;
     214             :     }
     215             : 
     216             :     uint8_t peek2() {
     217             :       bool first = false;
     218             :       if (!has2Data_) {
     219             :         trans_->readAll(data2_, 2);
     220             :         first = true;
     221             :       }
     222             :       has2Data_ = true;
     223             :       return first ? data2_[0] : data2_[1];
     224             :     }
     225             : 
     226             :    private:
     227             :     TTransport *trans_;
     228             :     bool hasData_;
     229             :     uint8_t data_;
     230             :     bool has2Data_;
     231             :     uint8_t data2_[2];
     232             :     bool firstRead_;
     233             :   };
     234             : 
     235             :  private:
     236             :   typedef boost::tokenizer<boost::char_separator<char> >
     237             :       tokenizer;
     238             :   void indentUp();
     239             :   void indentDown();
     240             :   int32_t writePlain(const std::string& str);
     241             :   int32_t writeIndented(const std::string& str);
     242             : 
     243             :   static const std::string& fieldTypeName(TType type);
     244             :   static TType getTypeIDForTypeName(const std::string &name);
     245             : 
     246             :   TTransport* trans_;
     247             : 
     248             :   int32_t string_limit_;
     249             :   int32_t string_prefix_size_;
     250             : 
     251             :   std::string indent_str_;
     252             : 
     253             :   static const int indent_inc = 2;
     254             : 
     255             :   std::vector<write_state_t> write_state_;
     256             : 
     257             :   bool sandesh_begin_;
     258             :   
     259             :   bool sandesh_end_;
     260             : 
     261             :   std::vector<bool> is_struct_begin_list_;
     262             :  
     263             :   std::vector<bool> is_list_begin_list_;
     264             : 
     265             :   bool is_primitive_list_begin_;
     266             : 
     267             :   bool is_first_primitve_list_elem_;
     268             : 
     269             :   bool is_data_map_key_;
     270             : 
     271             :   bool is_beginning_of_map;
     272             : 
     273             :   bool is_string_begin_;
     274             : 
     275             :   bool is_struct_begin_;
     276             : 
     277             :   bool in_list_context_;
     278             : 
     279             :   bool is_list_begin_;
     280             : 
     281             :   bool is_map_begin_;
     282             : 
     283             :   bool in_map_context_;
     284             : 
     285             :   bool in_non_primitive_map_context_;
     286             : 
     287             :   bool in_primitive_list_context_;
     288             : 
     289             :   bool in_non_primitive_list_context_;
     290             : 
     291             :   bool is_map_primitive_;
     292             : 
     293             :   bool is_map_val_;
     294             : 
     295             :   bool is_list_elem_string_;
     296             : 
     297             :   std::vector<std::string> current_sandesh_context_;
     298             : 
     299             :   std::vector<bool> is_first_element_context_;
     300             : 
     301             :   std::vector<bool> is_primitive_element_list_;
     302             : 
     303             :   std::vector<bool> is_map_val_primitive_;
     304             : 
     305             :   std::vector<bool> in_map_val_context_;
     306             :   std::vector<std::string> xml_state_;
     307             :   LookaheadReader reader_;
     308             :   std::map<TType, bool> complexTypeSet;
     309             : 
     310             : };
     311             : 
     312             : /**
     313             :  * Constructs JSON protocol handlers
     314             :  */
     315             : class TJSONProtocolFactory : public TProtocolFactory {
     316             :  public:
     317             :   TJSONProtocolFactory() {}
     318             :   virtual ~TJSONProtocolFactory() {}
     319             : 
     320             :   boost::shared_ptr<TProtocol> getProtocol(boost::shared_ptr<TTransport> trans) {
     321             :     return boost::shared_ptr<TProtocol>(new TJSONProtocol(trans));
     322             :   }
     323             : 
     324             : };
     325             : 
     326             : }}} // contrail::sandesh::protocol
     327             : 
     328             : #endif // #ifndef _SANDESH_PROTOCOL_TJSONPROTOCOL_H_
     329             : 
     330             : 

Generated by: LCOV version 1.14