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

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
       3             :  */
       4             : 
       5             : #ifndef _SANDESH_PROTOCOL_TXMLPROTOCOL_H_
       6             : #define _SANDESH_PROTOCOL_TXMLPROTOCOL_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             : 
      16             : namespace contrail { namespace sandesh { namespace protocol {
      17             : 
      18             : /**
      19             :  * Protocol that prints the payload in XML format.
      20             :  */
      21             : class TXMLProtocol : public TVirtualProtocol<TXMLProtocol> {
      22             :  private:
      23             :   enum write_state_t
      24             :   { UNINIT
      25             :   , STRUCT
      26             :   , LIST
      27             :   , SET
      28             :   , MAP
      29             :   , SNDESH
      30             :   };
      31             : 
      32             :  public:
      33             :   TXMLProtocol(boost::shared_ptr<TTransport> trans)
      34             :     : TVirtualProtocol<TXMLProtocol>(trans)
      35             :     , trans_(trans.get())
      36             :     , string_limit_(DEFAULT_STRING_LIMIT)
      37             :     , string_prefix_size_(DEFAULT_STRING_PREFIX_SIZE)
      38             :     , reader_(*trans)
      39             :   {
      40             :     write_state_.push_back(UNINIT);
      41             :   }
      42             : 
      43             :   static const int32_t DEFAULT_STRING_LIMIT = 256;
      44             :   static const int32_t DEFAULT_STRING_PREFIX_SIZE = 16;
      45             : 
      46             :   void setStringSizeLimit(int32_t string_limit) {
      47             :     string_limit_ = string_limit;
      48             :   }
      49             : 
      50             :   void setStringPrefixSize(int32_t string_prefix_size) {
      51             :     string_prefix_size_ = string_prefix_size;
      52             :   }
      53             : 
      54           3 :   static std::string escapeXMLControlCharsInternal(const std::string& str) {
      55           3 :     std::string xmlstr;
      56           3 :     xmlstr.reserve(str.length());
      57           3 :     for (std::string::const_iterator it = str.begin();
      58         476 :          it != str.end(); ++it) {
      59         473 :       switch(*it) {
      60           3 :        case '&':  xmlstr += "&amp;";  break;
      61           0 :        case '\'': xmlstr += "&apos;"; break;
      62           0 :        case '<':  xmlstr += "&lt;";   break;
      63           1 :        case '>':  xmlstr += "&gt;";   break;
      64         469 :        default:   xmlstr += *it;
      65             :       }
      66             :     }
      67           3 :     return xmlstr;
      68           0 :   }
      69             : 
      70      168939 :   static std::string escapeXMLControlChars(const std::string& str) {
      71      168939 :     if (strpbrk(str.c_str(), "&'<>") != NULL) {
      72           3 :       return escapeXMLControlCharsInternal(str);
      73             :     } else {
      74      168936 :       return str;
      75             :     }
      76             :   }
      77             : 
      78        1225 :   static void unescapeXMLControlChars(std::string& str) {
      79        1225 :       boost::algorithm::replace_all(str, "&amp;", "&");
      80        1225 :       boost::algorithm::replace_all(str, "&apos;", "\'");
      81        1225 :       boost::algorithm::replace_all(str, "&lt;", "<");
      82        1225 :       boost::algorithm::replace_all(str, "&gt;", ">");
      83        1225 :   }
      84             : 
      85             :   /**
      86             :    * Writing functions
      87             :    */
      88             : 
      89             :   int32_t writeMessageBegin(const std::string& name,
      90             :                             const TMessageType messageType,
      91             :                             const int32_t seqid);
      92             : 
      93             :   int32_t writeMessageEnd();
      94             : 
      95             :   int32_t writeStructBegin(const char* name);
      96             : 
      97             :   int32_t writeStructEnd();
      98             : 
      99             :   int32_t writeSandeshBegin(const char* name);
     100             : 
     101             :   int32_t writeSandeshEnd();
     102             : 
     103             :   int32_t writeContainerElementBegin();
     104             : 
     105             :   int32_t writeContainerElementEnd();
     106             : 
     107             :   int32_t writeFieldBegin(const char* name,
     108             :                           const TType fieldType,
     109             :                           const int16_t fieldId,
     110             :                           const std::map<std::string, std::string> *const amap = NULL);
     111             : 
     112             :   int32_t writeFieldEnd();
     113             : 
     114             :   int32_t writeFieldStop();
     115             : 
     116             :   int32_t writeMapBegin(const TType keyType,
     117             :                         const TType valType,
     118             :                         const uint32_t size);
     119             : 
     120             :   int32_t writeMapEnd();
     121             : 
     122             :   int32_t writeListBegin(const TType elemType,
     123             :                          const uint32_t size);
     124             : 
     125             :   int32_t writeListEnd();
     126             : 
     127             :   int32_t writeSetBegin(const TType elemType,
     128             :                         const uint32_t size);
     129             : 
     130             :   int32_t writeSetEnd();
     131             : 
     132             :   int32_t writeBool(const bool value);
     133             : 
     134             :   int32_t writeByte(const int8_t byte);
     135             : 
     136             :   int32_t writeI16(const int16_t i16);
     137             : 
     138             :   int32_t writeI32(const int32_t i32);
     139             : 
     140             :   int32_t writeI64(const int64_t i64);
     141             : 
     142             :   int32_t writeU16(const uint16_t u16);
     143             : 
     144             :   int32_t writeU32(const uint32_t u32);
     145             :   
     146             :   int32_t writeU64(const uint64_t u64);
     147             : 
     148             :   int32_t writeIPV4(const uint32_t ip4);
     149             : 
     150             :   int32_t writeIPADDR(const boost::asio::ip::address& ipaddress);
     151             :   
     152             :   int32_t writeDouble(const double dub);
     153             : 
     154             :   int32_t writeString(const std::string& str);
     155             : 
     156             :   int32_t writeBinary(const std::string& str);
     157             : 
     158             :   int32_t writeXML(const std::string& str);
     159             : 
     160             :   int32_t writeUUID(const boost::uuids::uuid& uuid);
     161             : 
     162             :   /**
     163             :    * Reading functions
     164             :    */
     165             : 
     166             :   int32_t readMessageBegin(std::string& name,
     167             :                            TMessageType& messageType,
     168             :                            int32_t& seqid);
     169             : 
     170             :   int32_t readMessageEnd();
     171             : 
     172             :   int32_t readSandeshBegin(std::string& name);
     173             : 
     174             :   int32_t readSandeshEnd();
     175             : 
     176             :   int32_t readStructBegin(std::string& name);
     177             : 
     178             :   int32_t readStructEnd();
     179             : 
     180             :   int32_t readContainerElementBegin();
     181             : 
     182             :   int32_t readContainerElementEnd();
     183             : 
     184             :   int32_t readFieldBegin(std::string& name,
     185             :                          TType& fieldType,
     186             :                          int16_t& fieldId);
     187             : 
     188             :   int32_t readFieldEnd();
     189             : 
     190             :   int32_t readMapBegin(TType& keyType,
     191             :                        TType& valType,
     192             :                        uint32_t& size);
     193             : 
     194             :   int32_t readMapEnd();
     195             : 
     196             :   int32_t readListBegin(TType& elemType,
     197             :                         uint32_t& size);
     198             : 
     199             :   int32_t readListEnd();
     200             : 
     201             :   int32_t readSetBegin(TType& elemType,
     202             :                        uint32_t& size);
     203             : 
     204             :   int32_t readSetEnd();
     205             : 
     206             :   int32_t readBool(bool& value);
     207             : 
     208             :   // Provide the default readBool() implementation for std::vector<bool>
     209             :   using TVirtualProtocol<TXMLProtocol>::readBool;
     210             : 
     211             :   int32_t readByte(int8_t& byte);
     212             : 
     213             :   int32_t readI16(int16_t& i16);
     214             : 
     215             :   int32_t readI32(int32_t& i32);
     216             : 
     217             :   int32_t readI64(int64_t& i64);
     218             : 
     219             :   int32_t readU16(uint16_t& u16);
     220             : 
     221             :   int32_t readU32(uint32_t& u32);
     222             :   
     223             :   int32_t readU64(uint64_t& u64);
     224             : 
     225             :   int32_t readIPV4(uint32_t& ip4);
     226             : 
     227             :   int32_t readIPADDR(boost::asio::ip::address& ipaddress);
     228             : 
     229             :   int32_t readDouble(double& dub);
     230             : 
     231             :   int32_t readString(std::string& str);
     232             : 
     233             :   int32_t readBinary(std::string& str);
     234             : 
     235             :   int32_t readXML(std::string& str);
     236             : 
     237             :   int32_t readUUID(boost::uuids::uuid& uuid);
     238             : 
     239             :   class LookaheadReader {
     240             : 
     241             :    public:
     242             : 
     243             :     LookaheadReader(TTransport &trans) :
     244             :       trans_(&trans),
     245             :       hasData_(false),
     246             :       has2Data_(false),
     247             :       firstRead_(false) {
     248             :     }
     249             : 
     250      146151 :     uint8_t read() {
     251      146151 :       if (hasData_) {
     252       21698 :         hasData_ = false;
     253             :       }
     254             :       else {
     255      124453 :         if (has2Data_) {
     256        4592 :           if (firstRead_) {
     257        2296 :             has2Data_ = false;
     258        2296 :             firstRead_ = false;
     259        2296 :             return data2_[1];
     260             :           } else {
     261        2296 :             firstRead_ = true;
     262        2296 :             return data2_[0];
     263             :           }
     264             :         } else {
     265      119861 :           trans_->readAll(&data_, 1);
     266             :         }
     267             :       }
     268      141559 :       return data_;
     269             :     }
     270             : 
     271       21698 :     uint8_t peek() {
     272       21698 :       if (!hasData_) {
     273       21698 :         trans_->readAll(&data_, 1);
     274             :       }
     275       21698 :       hasData_ = true;
     276       21698 :       return data_;
     277             :     }
     278             : 
     279        4592 :     uint8_t peek2() {
     280        4592 :       bool first = false;
     281        4592 :       if (!has2Data_) {
     282        2296 :         trans_->readAll(data2_, 2);
     283        2296 :         first = true;
     284             :       }
     285        4592 :       has2Data_ = true;
     286        4592 :       return first ? data2_[0] : data2_[1];
     287             :     }
     288             : 
     289             :    private:
     290             :     TTransport *trans_;
     291             :     bool hasData_;
     292             :     uint8_t data_;
     293             :     bool has2Data_;
     294             :     uint8_t data2_[2];
     295             :     bool firstRead_;
     296             :   };
     297             : 
     298             :  private:
     299             :   typedef boost::tokenizer<boost::char_separator<char> >
     300             :       tokenizer;
     301             : 
     302             :   int32_t readXMLSyntaxChar(uint8_t ch);
     303             : 
     304             :   int32_t readXMLSyntaxString(const std::string &str);
     305             : 
     306             :   int32_t readXMLString(std::string &str);
     307             : 
     308             :   int32_t readXMLTag(std::string &str, bool endTag = false);
     309             : 
     310             :   int32_t readXMLNumericChars(std::string &str);
     311             : 
     312             :   int32_t readXMLCDATA(std::string &str);
     313             : 
     314             :   template <typename NumberType>
     315             :   int32_t readXMLInteger(NumberType &num);
     316             : 
     317             :   int32_t readXMLDouble(double &num);
     318             : 
     319             :   int32_t readXMLUuid(boost::uuids::uuid &uuid);
     320             : 
     321             :   void indentUp();
     322             :   void indentDown();
     323             :   int32_t writePlain(const std::string& str);
     324             :   int32_t writeIndented(const std::string& str);
     325             : 
     326             :   static const std::string& fieldTypeName(TType type);
     327             :   static TType getTypeIDForTypeName(const std::string &name);
     328             : 
     329             :   TTransport* trans_;
     330             : 
     331             :   int32_t string_limit_;
     332             :   int32_t string_prefix_size_;
     333             : 
     334             :   std::string indent_str_;
     335             : 
     336             :   static const int indent_inc = 2;
     337             : 
     338             :   std::vector<write_state_t> write_state_;
     339             : 
     340             :   std::vector<std::string> xml_state_;
     341             :   LookaheadReader reader_;
     342             : };
     343             : 
     344             : /**
     345             :  * Constructs XML protocol handlers
     346             :  */
     347             : class TXMLProtocolFactory : public TProtocolFactory {
     348             :  public:
     349             :   TXMLProtocolFactory() {}
     350             :   virtual ~TXMLProtocolFactory() {}
     351             : 
     352             :   boost::shared_ptr<TProtocol> getProtocol(boost::shared_ptr<TTransport> trans) {
     353             :     return boost::shared_ptr<TProtocol>(new TXMLProtocol(trans));
     354             :   }
     355             : 
     356             : };
     357             : 
     358             : }}} // contrail::sandesh::protocol
     359             : 
     360             : #endif // #ifndef _SANDESH_PROTOCOL_TXMLPROTOCOL_H_
     361             : 
     362             : 

Generated by: LCOV version 1.14