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

Generated by: LCOV version 1.14