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

Generated by: LCOV version 1.14