LCOV - code coverage report
Current view: top level - root/contrail/src/contrail-common/sandesh/library/cpp/protocol - TJSONProtocol.cpp (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 0 522 0.0 %
Date: 2026-08-03 02:19:58 Functions: 0 37 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             : #include <cassert>
       6             : #include <cctype>
       7             : #include <cstdio>
       8             : #include <stdexcept>
       9             : #include <boost/static_assert.hpp>
      10             : #include <boost/algorithm/string/replace.hpp>
      11             : 
      12             : #include <base/logging.h>
      13             : #include <base/util.h>
      14             : #include <base/string_util.h>
      15             : 
      16             : #include "TJSONProtocol.h"
      17             : 
      18             : using std::string;
      19             : 
      20             : #ifdef TJSONPROTOCOL_DEBUG_PRETTY_PRINT
      21             : static const string endl = "\n";
      22             : #else
      23             : static const string endl = "";
      24             : #endif // !TJSONPROTOCOL_DEBUG_PRETTY_PRINT
      25             : 
      26             : namespace contrail { namespace sandesh { namespace protocol {
      27             : 
      28             : // Static data
      29             : 
      30             : static const std::string kJSONTagO("{");
      31             : static const std::string kJSONTagC("}");
      32             : static const std::string kJSONType("type");
      33             : static const std::string kJSONIdentifier("identifier");
      34             : static const std::string kJSONName("name");
      35             : static const std::string kJSONKey("key");
      36             : static const std::string kJSONValue("value");
      37             : static const std::string kJSONSize("size");
      38             : static const std::string kJSONBoolTrue("true");
      39             : static const std::string kJSONBoolFalse("false");
      40             : static const std::string kJSONCDATAO("<![CDATA[");
      41             : static const std::string kJSONCDATAC("]]>");
      42             : 
      43             : static const std::string kTypeNameBool("bool");
      44             : static const std::string kTypeNameByte("byte");
      45             : static const std::string kTypeNameI16("i16");
      46             : static const std::string kTypeNameI32("i32");
      47             : static const std::string kTypeNameI64("i64");
      48             : static const std::string kTypeNameU16("u16");
      49             : static const std::string kTypeNameU32("u32");
      50             : static const std::string kTypeNameU64("u64");
      51             : static const std::string kTypeNameIPV4("ipv4");
      52             : static const std::string kTypeNameIPADDR("ipaddr");
      53             : static const std::string kTypeNameDouble("double");
      54             : static const std::string kTypeNameStruct("struct");
      55             : static const std::string kTypeNameString("string");
      56             : static const std::string kTypeNameXML("xml");
      57             : static const std::string kTypeNameUUID("uuid_t");
      58             : static const std::string kTypeNameMap("map");
      59             : static const std::string kTypeNameList("list");
      60             : static const std::string kTypeNameSet("set");
      61             : static const std::string kTypeNameSandesh("sandesh");
      62             : static const std::string kTypeNameUnknown("unknown");
      63             : 
      64             : static const std::string kAttrTypeSandesh("type=\"sandesh\"");
      65             : static const std::string kJSONListTagO("<list ");
      66             : static const std::string kJSONListTagC("</list>" + endl);
      67             : static const std::string kJSONSetTagO("<set ");
      68             : static const std::string kJSONSetTagC("</set>" + endl);
      69             : static const std::string kJSONMapTagO("<map ");
      70             : static const std::string kJSONMapTagC("</map>" + endl);
      71             : static const std::string kType("\"TYPE\":");
      72             : static const std::string kTYPEStruct("TYPE: STRUCT");
      73             : static const std::string kFieldId("\"ID\":");
      74             : static const std::string kVal("\"VAL\":");
      75             : 
      76           0 : const std::string& TJSONProtocol::fieldTypeName(TType type) {
      77           0 :   switch (type) {
      78           0 :     case T_BOOL   : return kTypeNameBool   ;
      79           0 :     case T_BYTE   : return kTypeNameByte   ;
      80           0 :     case T_I16    : return kTypeNameI16    ;
      81           0 :     case T_I32    : return kTypeNameI32    ;
      82           0 :     case T_I64    : return kTypeNameI64    ;
      83           0 :     case T_U16    : return kTypeNameU16    ;
      84           0 :     case T_U32    : return kTypeNameU32    ;
      85           0 :     case T_U64    : return kTypeNameU64    ;
      86           0 :     case T_IPV4   : return kTypeNameIPV4   ;
      87           0 :     case T_IPADDR : return kTypeNameIPADDR ;
      88           0 :     case T_DOUBLE : return kTypeNameDouble ;
      89           0 :     case T_STRING : return kTypeNameString ;
      90           0 :     case T_STRUCT : return kTypeNameStruct ;
      91           0 :     case T_MAP    : return kTypeNameMap    ;
      92           0 :     case T_SET    : return kTypeNameSet    ;
      93           0 :     case T_LIST   : return kTypeNameList   ;
      94           0 :     case T_SANDESH: return kTypeNameSandesh;
      95           0 :     case T_XML    : return kTypeNameXML    ;
      96           0 :     case T_UUID   : return kTypeNameUUID   ;
      97           0 :     default: return kTypeNameUnknown;
      98             :   }
      99             : }
     100             : 
     101           0 : TType TJSONProtocol::getTypeIDForTypeName(const std::string &name) {
     102           0 :   TType result = T_STOP; // Sentinel value
     103           0 :   if (name.length() > 1) {
     104           0 :     switch (name[0]) {
     105           0 :     case 'b':
     106           0 :         switch (name[1]) {
     107           0 :         case 'o':
     108           0 :             result = T_BOOL;
     109           0 :             break;
     110           0 :         case 'y':
     111           0 :             result = T_BYTE;
     112           0 :             break;
     113             :         }
     114           0 :         break;
     115           0 :     case 'd':
     116           0 :       result = T_DOUBLE;
     117           0 :       break;
     118           0 :     case 'i':
     119           0 :       switch (name[1]) {
     120           0 :       case '1':
     121           0 :         result = T_I16;
     122           0 :         break;
     123           0 :       case '3':
     124           0 :         result = T_I32;
     125           0 :         break;
     126           0 :       case '6':
     127           0 :         result = T_I64;
     128           0 :         break;
     129           0 :       case 'p':
     130           0 :         switch (name[2]) {
     131           0 :         case 'a':
     132           0 :           result = T_IPADDR;
     133           0 :           break;
     134           0 :         case 'v':
     135           0 :           result = T_IPV4;
     136           0 :           break;
     137             :         }
     138           0 :         break;
     139             :       }
     140           0 :       break;
     141           0 :     case 'l':
     142           0 :       result = T_LIST;
     143           0 :       break;
     144           0 :     case 'm':
     145           0 :       result = T_MAP;
     146           0 :       break;
     147           0 :     case 's':
     148           0 :         switch (name[1]) {
     149           0 :         case 'a':
     150           0 :             result = T_SANDESH;
     151           0 :             break;
     152           0 :         case 'e':
     153           0 :             result = T_SET;
     154           0 :             break;
     155           0 :         case 't':
     156           0 :             switch (name[3]) {
     157           0 :             case 'i':
     158           0 :                 result = T_STRING;
     159           0 :                 break;
     160           0 :             case 'u':
     161           0 :                 result = T_STRUCT;
     162           0 :                 break;
     163             :             }
     164           0 :             break;
     165             :         }
     166           0 :         break;
     167           0 :     case 'u':
     168           0 :       switch(name[1]) {
     169           0 :         case '1':
     170           0 :           result = T_U16;
     171           0 :           break;
     172           0 :         case '3':
     173           0 :           result = T_U32;
     174           0 :           break;
     175           0 :         case '6':
     176           0 :           result = T_U64;
     177           0 :           break;
     178           0 :         case 'u':
     179           0 :           result = T_UUID;
     180           0 :           break;
     181             :       }
     182           0 :       break;
     183           0 :     case 'x':
     184           0 :       result = T_XML;
     185           0 :       break;
     186             :     }
     187             :   }
     188           0 :   if (result == T_STOP) {
     189           0 :     LOG(ERROR, __func__ << "Unrecognized type: " << name);
     190             :   }
     191           0 :   return result;
     192             : }
     193             : 
     194             : static inline void formJSONAttr(std::string &dest, const std::string& name, 
     195             :                                const std::string & value) {
     196             :   dest += name;
     197             :   dest += "=\"";
     198             :   dest += value; 
     199             :   dest += "\"";
     200             : }
     201             : 
     202           0 : void TJSONProtocol::indentUp() {
     203             : #if TJSONPROTOCOL_DEBUG_PRETTY_PRINT
     204             :   indent_str_ += string(indent_inc, ' ');
     205             : #endif // !TJSONPROTOCOL_DEBUG_PRETTY_PRINT
     206           0 : }
     207             : 
     208           0 : void TJSONProtocol::indentDown() {
     209             : #if TJSONPROTOCOL_DEBUG_PRETTY_PRINT
     210             :   if (indent_str_.length() < (string::size_type)indent_inc) {
     211             :     LOG(ERROR, __func__ << "Indent string length " <<
     212             :         indent_str_.length() << " less than indent length " <<
     213             :         (string::size_type)indent_inc);
     214             :     return;
     215             :   }
     216             :   indent_str_.erase(indent_str_.length() - indent_inc);
     217             : #endif // !TJSONPROTOOL_DEBUG_PRETTY_PRINT
     218           0 : }
     219             : 
     220             : // Returns the number of bytes written on success, -1 otherwise
     221           0 : int32_t TJSONProtocol::writePlain(const string& str) {
     222           0 :   int ret = trans_->write((uint8_t*)str.data(), str.length());
     223           0 :   if (ret) {
     224           0 :       return -1;
     225             :   }
     226           0 :   return str.length();
     227             : }
     228             : 
     229             : // Returns the number of bytes written on success, -1 otherwise
     230           0 : int32_t TJSONProtocol::writeIndented(const string& str) {
     231             :   int ret;
     232             : #if TJSONPROTOCOL_DEBUG_PRETTY_PRINT
     233             :   ret = trans_->write((uint8_t*)indent_str_.data(), indent_str_.length());
     234             :   if (ret) {
     235             :       return -1;
     236             :   }
     237             : #endif // !TJSONPROTOCOL_DEBUG_PRETTY_PRINT
     238           0 :   ret = trans_->write((uint8_t*)str.data(), str.length());
     239           0 :   if (ret) {
     240           0 :      return -1;
     241             :   }
     242           0 :   return indent_str_.length() + str.length();
     243             : }
     244             : 
     245           0 : int32_t TJSONProtocol::writeMessageBegin(const std::string& name,
     246             :                                         const TMessageType messageType,
     247             :                                         const int32_t seqid) {
     248           0 :   return 0;
     249             : }
     250             : 
     251           0 : int32_t TJSONProtocol::writeMessageEnd() {
     252           0 :   return 0;
     253             : }
     254             : 
     255             : 
     256             : /*
     257             : * As a part of structBegin call, we open 2 {{
     258             : * Inside the outer bracket, we will have
     259             : * meta data about the structure itself.
     260             : * Inside the inner bracket, we will have the
     261             : * actual fields of the structure
     262             : */
     263           0 : int32_t TJSONProtocol::writeStructBegin(const char* name) {
     264           0 :   int32_t size = 0, ret;
     265           0 :   string sname(name);
     266           0 :   string json;
     267           0 :   json.reserve(512);
     268             : 
     269             :   // Handle list of struct
     270           0 :   if (is_first_element_context_.size() > 0 &&
     271           0 :       !is_first_element_context_.back() &&
     272           0 :       current_sandesh_context_.back() == "LIST") {
     273           0 :       json += ",";
     274           0 :   } else if (!is_first_element_context_.empty()) {
     275           0 :       is_first_element_context_.back() = false;
     276             :   }
     277             : 
     278           0 :   json += "{";
     279           0 :   if(current_sandesh_context_.back() == "SANDESH") {
     280           0 :      json += "\"STAT_TYPE\":";
     281           0 :      json += "\""+sname+"\"";
     282           0 :      json += ",";
     283             :   }
     284           0 :   current_sandesh_context_.push_back("STRUCT");
     285           0 :   is_first_element_context_.push_back(true);
     286           0 :   is_primitive_element_list_.push_back(false);
     287           0 :   json += "\"VAL\":";
     288           0 :   json += kJSONTagO;
     289           0 :   indentUp();
     290             :   // Write to transport
     291           0 :   if ((ret = writeIndented(json)) < 0) {
     292           0 :     LOG(ERROR, __func__ << ": " << sname << " FAILED");
     293           0 :     return ret;
     294             :   }
     295             :   // push a value to is_struct_begin
     296           0 :   is_struct_begin_list_.push_back(true);
     297           0 :   size += ret;
     298           0 :   return size;
     299           0 : }
     300             : 
     301             : /*
     302             :  * Close the brackets that were opened as part of
     303             :  * struct begin. Some variables are maintained to
     304             :  * identify if we are in struct context or not.
     305             :  */
     306           0 : int32_t TJSONProtocol::writeStructEnd() {
     307           0 :   int32_t size = 0, ret;
     308           0 :   indentDown();
     309           0 :   string json;
     310           0 :   json.reserve(128);
     311           0 :   json += kJSONTagC;
     312           0 :   indentDown();
     313           0 :   json += endl;
     314           0 :   json += kJSONTagC;
     315           0 :   json += endl;
     316           0 :   indentDown();
     317             :   // Write to transport
     318           0 :   if ((ret = writeIndented(json)) < 0) {
     319           0 :     LOG(ERROR, __func__ << ": " << json << " FAILED");
     320           0 :     return ret;
     321             :   }
     322           0 :   size += ret;
     323             : 
     324           0 :   current_sandesh_context_.pop_back();
     325           0 :   is_first_element_context_.pop_back();
     326           0 :   if(is_first_element_context_.size() > 0) {
     327           0 :       is_first_element_context_.back() = false;
     328             :   }
     329           0 :   is_primitive_element_list_.pop_back();
     330           0 :   return size;
     331           0 : }
     332             : 
     333             : /*
     334             :  * Open a couple of brackets when this call is made
     335             :  * The first bracket to store metadata about the
     336             :  * sandesh. The second bracket to store the actual
     337             :  * fields of the sandesh.
     338             :  */
     339           0 : int32_t TJSONProtocol::writeSandeshBegin(const char* name) {
     340           0 :   int32_t size = 0, ret;
     341           0 :   string sname(name);
     342           0 :   string json;
     343           0 :   current_sandesh_context_.push_back("SANDESH");
     344           0 :   is_first_element_context_.push_back(true);
     345           0 :   json.reserve(512);
     346           0 :   json += kJSONTagO;
     347           0 :   json += endl;
     348           0 :   indentUp();
     349           0 :   json += "\"";
     350           0 :   json += name;
     351           0 :   json += "\"";
     352           0 :   json += ":";
     353           0 :   json += kJSONTagO;
     354           0 :   json += endl;
     355           0 :   indentUp();
     356             :   // Write to transport
     357           0 :   ret = writeIndented(json);
     358           0 :   if (ret < 0) {
     359           0 :     LOG(ERROR, __func__ << ": " << sname << " FAILED");
     360           0 :     return ret;
     361             :   }
     362           0 :   size += ret;
     363           0 :   is_primitive_element_list_.push_back(false);
     364           0 :   indentUp();
     365           0 :   return size;
     366           0 : }
     367             : 
     368           0 : int32_t TJSONProtocol::writeSandeshEnd() {
     369             : 
     370           0 :   int32_t size = 0, ret;
     371           0 :   indentDown();
     372           0 :   string json;
     373           0 :   json.reserve(128);
     374             :   //indentDown();
     375           0 :   json += kJSONTagC;
     376           0 :   json += endl;
     377           0 :   indentDown();
     378           0 :   json += ",";
     379           0 :   json += "\"TIMESTAMP\":";
     380           0 :   std::stringstream ss;
     381           0 :   std::string t_s;
     382           0 :   ss << UTCTimestampUsec();
     383           0 :   ss >> t_s;
     384           0 :   json += t_s;
     385           0 :   json += kJSONTagC;
     386           0 :   json += endl;
     387             :   // Write to transport
     388           0 :   if ((ret = writeIndented(json)) < 0) {
     389           0 :     LOG(ERROR, __func__ << ": " << json << " FAILED");
     390           0 :     return ret;
     391             :   }
     392           0 :   size += ret;
     393           0 :   current_sandesh_context_.pop_back();
     394           0 :   is_first_element_context_.pop_back();
     395           0 :   is_primitive_element_list_.pop_back();
     396           0 :   return size;
     397           0 : }
     398             : 
     399           0 : int32_t TJSONProtocol::writeContainerElementBegin() {
     400           0 :   int32_t size = 0, ret;
     401           0 :   indentDown();
     402           0 :   string json;
     403           0 :   json.reserve(128);
     404             : 
     405           0 :   if (!is_first_element_context_.back()) {
     406             :       // could be in map or list context, print , only in case of map val
     407           0 :       if (current_sandesh_context_.back() == "MAP") {
     408           0 :           if (!in_map_val_context_.back()) {
     409             :               // print only before keys
     410           0 :               json += ",";
     411             :           }
     412             :       } else {
     413           0 :           json += ",";
     414             :       }
     415             :   } else {
     416           0 :      is_first_element_context_.back() = false;
     417             :   }
     418             : 
     419           0 :   if (current_sandesh_context_.back() == "LIST" &&
     420           0 :       is_primitive_element_list_.back()) {
     421           0 :       if(is_list_elem_string_) {
     422           0 :           json += "\"";
     423             :       }
     424             :   }
     425             : 
     426           0 :   if (current_sandesh_context_.back() == "MAP") {
     427           0 :      if (is_primitive_element_list_.back()) {
     428           0 :          json+= "\"";
     429             :      }
     430             :   }
     431           0 :   return writeIndented(json);
     432             :   //return writeIndented(kJSONElementTagO);
     433           0 : }
     434             : 
     435             : /*
     436             :  * This fn will be called for primitive
     437             :  * types.
     438             :  */
     439           0 : int32_t TJSONProtocol::writeContainerElementEnd() {
     440           0 :   int32_t size = 0, ret;
     441           0 :   indentDown();
     442           0 :   string json;
     443           0 :   json.reserve(128);
     444             : 
     445           0 :   if (current_sandesh_context_.back() == "MAP") {
     446           0 :       if (is_primitive_element_list_.back()) {
     447           0 :           json += "\"";
     448             :       }
     449             :       // print : if its map key else dont
     450           0 :       if (in_map_val_context_.back()) {
     451           0 :           in_map_val_context_.back() = false;
     452             :       } else {
     453             :           // In map key context
     454           0 :           json += ":";
     455           0 :           if (is_map_val_primitive_.back()) {
     456           0 :               in_map_val_context_.back() = true;
     457             :           }
     458             :       }
     459             :   }
     460             : 
     461           0 :   if (current_sandesh_context_.back() == "LIST" &&
     462           0 :       is_primitive_element_list_.back()) {
     463           0 :       if (is_list_elem_string_) {
     464           0 :           json += "\"";
     465             :       }
     466             :   }
     467             : 
     468           0 :   return writeIndented(json);
     469           0 : }
     470             : 
     471             : 
     472             : /*
     473             :  * This function is called for every field
     474             :  * of type struct. JSON uses "," seperated
     475             :  * entries to hold list of values. We
     476             :  * maintain state variables to add comma or
     477             :  * not after each entry.
     478             :  * First we write meta data about the field,
     479             :  * then we store the actual value under the
     480             :  * tag "VAL". The new stats collections are
     481             :  * decided based on the annotations of the individual
     482             :  * fields.
     483             :  */
     484           0 : int32_t TJSONProtocol::writeFieldBegin(const char *name,
     485             :                                       const TType fieldType,
     486             :                                       const int16_t fieldId,
     487             :                                       const std::map<std::string, std::string> *const amap) {
     488           0 :   int32_t size = 0, ret;
     489           0 :   string sname(name);
     490           0 :   string json;
     491           0 :   json.reserve(512);
     492             : 
     493           0 :   if (!is_first_element_context_.back() &&
     494           0 :       current_sandesh_context_.back() != "MAP") {
     495           0 :       json += ",";
     496             :   } else {
     497           0 :       is_first_element_context_.back() = false;
     498             :   }
     499             : 
     500           0 :   json += "\"";
     501           0 :   json += sname;
     502           0 :   json += "\"";
     503           0 :   json += ":";
     504           0 :   json += kJSONTagO; // : {
     505           0 :   json += endl;
     506           0 :   indentUp();
     507           0 :   json += kType; // "TYPE":
     508           0 :   json += "\"";
     509           0 :   json += fieldTypeName(fieldType);
     510           0 :   json += "\"";
     511           0 :   json += ",";
     512           0 :   json += endl;
     513             : 
     514           0 :   if(amap != NULL) {
     515           0 :       json += "\"ANNOTATION\":";
     516           0 :       json += "{";
     517           0 :       std::map<std::string, std::string>::const_iterator it;
     518           0 :       for(it = amap->begin(); it != amap->end(); it++) {
     519           0 :           json += "\""+it->first+"\"";
     520           0 :           json += ":";
     521           0 :           json += "\""+it->second+"\"";
     522           0 :           json += ",";
     523             :       }
     524           0 :       json.erase(json.size()-1);
     525           0 :       json += "},";
     526             :   }
     527             : 
     528           0 :   json += "\"VAL\":";
     529             :   //If field type is string quote it
     530           0 :   if(fieldType == T_STRING || fieldType == T_IPADDR || fieldType == T_UUID) {
     531           0 :       is_string_begin_ = true;
     532           0 :       json += "\"";
     533             :   }
     534           0 :   json += endl;
     535             :   // Write to transport
     536           0 :   if ((ret = writeIndented(json)) < 0) {
     537           0 :     LOG(ERROR, __func__ << ": " << json << " FAILED");
     538           0 :     return ret;
     539             :   }
     540           0 :   size += ret;
     541           0 :   return size;
     542           0 : }
     543             : 
     544           0 : int32_t TJSONProtocol::writeFieldEnd() {
     545           0 :   int32_t size = 0, ret;
     546           0 :   string json;
     547           0 :   indentDown();
     548           0 :   if(is_string_begin_) {
     549           0 :       is_string_begin_ = false;
     550           0 :       json += "\"";
     551             :   }
     552           0 :   json += "}";
     553           0 :   if ((ret = writeIndented(json)) < 0) {
     554           0 :     LOG(ERROR, __func__ << ": " << json << " FAILED");
     555           0 :     return ret;
     556             :   }
     557           0 :   size += ret;
     558           0 :   return size;
     559           0 : }
     560             : 
     561           0 : int32_t TJSONProtocol::writeFieldStop() {
     562           0 :   return 0;
     563             : }
     564             : 
     565           0 : int32_t TJSONProtocol::writeMapBegin(const TType keyType,
     566             :                                     const TType valType,
     567             :                                     const uint32_t size) {
     568             : 
     569           0 :   int32_t bsize = 0, ret;
     570           0 :   string json;
     571           0 :   json.reserve(256);
     572           0 :   current_sandesh_context_.push_back("MAP");
     573           0 :   is_first_element_context_.push_back(true);
     574           0 :   json += "{";
     575           0 :   json += endl;
     576           0 :   json += "\"VALUE\":";
     577           0 :   json += "\"";
     578           0 :   json += fieldTypeName(valType);
     579           0 :   json += "\"";
     580           0 :   json += ",";
     581           0 :   json += "\"VAL\":";
     582           0 :   json += "{";
     583             : 
     584           0 :   indentUp();
     585             :   // Write to transport
     586           0 :   ret = writeIndented(json);
     587           0 :   if (ret < 0) {
     588           0 :     LOG(ERROR, __func__ << ": Key: " << fieldTypeName(keyType) <<
     589             :         " Value: " << fieldTypeName(valType) << " FAILED");
     590           0 :     return ret;
     591             :   }
     592             : 
     593           0 :   if (keyType == T_MAP || keyType == T_STRUCT || keyType == T_LIST) {
     594           0 :       is_primitive_element_list_.push_back(false);
     595             :   } else {
     596           0 :       is_primitive_element_list_.push_back(true);
     597             :   }
     598             : 
     599           0 :   if(valType == T_MAP || valType == T_STRUCT || valType == T_LIST) {
     600           0 :      in_non_primitive_map_context_ = true;
     601           0 :      is_map_val_primitive_.push_back(false);
     602           0 :      in_map_val_context_.push_back(false);
     603             :   } else {
     604           0 :      is_map_primitive_ = true;
     605           0 :      is_map_val_primitive_.push_back(true);
     606           0 :      in_map_val_context_.push_back(false);
     607             :   }
     608             : 
     609           0 :   bsize += ret;
     610           0 :   indentUp();
     611           0 :   return bsize;
     612             : 
     613           0 : }
     614             : 
     615           0 : int32_t TJSONProtocol::writeMapEnd() {
     616           0 :   int32_t size = 0, ret;
     617           0 :   string json;
     618           0 :   json.reserve(256);
     619           0 :   indentDown();
     620           0 :   json += "}";
     621           0 :   json += endl;
     622             : 
     623           0 :   indentDown();
     624           0 :   json += "}";
     625           0 :   json += endl;
     626             : 
     627             : 
     628           0 :   if ((ret = writeIndented(json)) < 0) {
     629           0 :     LOG(ERROR, __func__ << " FAILED");
     630           0 :     return ret;
     631             :   }
     632           0 :   current_sandesh_context_.pop_back();
     633           0 :   is_first_element_context_.pop_back();
     634           0 :   if (is_first_element_context_.size() > 0) {
     635           0 :       is_first_element_context_.back() = false;
     636             :   }
     637           0 :   is_primitive_element_list_.pop_back();
     638           0 :   in_map_val_context_.pop_back();
     639           0 :   is_map_val_primitive_.pop_back();
     640           0 :   size += ret;
     641           0 :   return size;
     642           0 : }
     643             : 
     644           0 : int32_t TJSONProtocol::writeListBegin(const TType elemType,
     645             :                                      const uint32_t size) {
     646           0 :   int32_t bsize = 0, ret;
     647           0 :   string json;
     648           0 :   json.reserve(256);
     649             : 
     650           0 :   if (is_first_element_context_.size() > 0 &&
     651           0 :       !is_first_element_context_.back() &&
     652           0 :       current_sandesh_context_.back() == "LIST") {
     653           0 :       json += ",";
     654           0 :   } else if (is_first_element_context_.size() > 0) {
     655           0 :       is_first_element_context_.back() = false;
     656             :   }
     657             : 
     658           0 :   current_sandesh_context_.push_back("LIST");
     659           0 :   is_first_element_context_.push_back(true);
     660           0 :   json += "{";
     661           0 :   json += "\"VAL\":";
     662           0 :   json += "[";
     663           0 :   json += endl;
     664             :   // Write to transport
     665           0 :   ret = writeIndented(json);
     666           0 :   if (ret < 0) {
     667           0 :     LOG(ERROR, __func__ << ": " << fieldTypeName(elemType) <<
     668             :         " FAILED");
     669           0 :     return ret;
     670             :   }
     671           0 :   is_list_begin_list_.push_back(true);
     672           0 :   if(elemType != T_STRUCT || elemType != T_MAP ) {
     673             :       //primitive type
     674           0 :       if(elemType == T_STRING || elemType == T_IPADDR || elemType == T_UUID) {
     675           0 :           is_list_elem_string_ = true;
     676             :       }
     677           0 :       is_primitive_element_list_.push_back(true);
     678             :       //in_list_context_ = true;
     679             :   } else {
     680           0 :       is_primitive_element_list_.push_back(false);
     681             :   }
     682           0 :   bsize += ret;
     683           0 :   indentUp();
     684           0 :   return bsize;
     685           0 : }
     686             : 
     687           0 : int32_t TJSONProtocol::writeListEnd() {
     688           0 :   int32_t size = 0, ret;
     689           0 :   string json;
     690           0 :   json.reserve(32);
     691           0 :   indentDown();
     692           0 :   json += "]";
     693           0 :   indentDown();
     694           0 :   json += "}";
     695           0 :   ret = writeIndented(json);
     696             :   
     697           0 :   if (ret < 0) {
     698           0 :     LOG(ERROR, __func__ << " FAILED");
     699           0 :     return ret;
     700             :   }
     701           0 :   size += ret;
     702           0 :   current_sandesh_context_.pop_back();
     703           0 :   is_first_element_context_.pop_back();
     704           0 :   if (is_first_element_context_.size() > 0) {
     705           0 :       is_first_element_context_.back() = false;
     706             :   }
     707           0 :   is_primitive_element_list_.pop_back();
     708           0 :   return size;
     709           0 : }
     710             : 
     711           0 : int32_t TJSONProtocol::writeSetBegin(const TType elemType,
     712             :                                     const uint32_t size) {
     713           0 :   int32_t bsize = 0, ret;
     714           0 :   string json;
     715           0 :   json.reserve(256);
     716             : 
     717           0 :   if (is_first_element_context_.size() > 0 &&
     718           0 :       !is_first_element_context_.back() &&
     719           0 :       current_sandesh_context_.back() == "SET") {
     720           0 :       json += ",";
     721           0 :   } else if (is_first_element_context_.size() > 0) {
     722           0 :       is_first_element_context_.back() = false;
     723             :   }
     724             : 
     725           0 :   current_sandesh_context_.push_back("SET");
     726           0 :   is_first_element_context_.push_back(true);
     727           0 :   json += "{";
     728           0 :   json += "\"VAL\":";
     729           0 :   json += "[";
     730           0 :   json += endl;
     731             :   // Write to transport
     732           0 :   ret = writeIndented(json);
     733           0 :   if (ret < 0) {
     734           0 :     LOG(ERROR, __func__ << ": " << fieldTypeName(elemType) <<
     735             :         " FAILED");
     736           0 :     return ret;
     737             :   }
     738           0 :   is_list_begin_list_.push_back(true);
     739           0 :   if(elemType != T_STRUCT || elemType != T_MAP ) {
     740             :       //primitive type
     741           0 :       if(elemType == T_STRING || elemType == T_IPADDR || elemType == T_UUID) {
     742           0 :           is_list_elem_string_ = true;
     743             :       }
     744           0 :       is_primitive_element_list_.push_back(true);
     745             :       //in_list_context_ = true;
     746             :   } else {
     747           0 :       is_primitive_element_list_.push_back(false);
     748             :   }
     749           0 :   bsize += ret;
     750           0 :   indentUp();
     751           0 :   return bsize;
     752           0 : }
     753             : 
     754           0 : int32_t TJSONProtocol::writeSetEnd() {
     755           0 :   int32_t size = 0, ret;
     756           0 :   string json;
     757           0 :   json.reserve(32);
     758           0 :   indentDown();
     759           0 :   json += "]";
     760           0 :   indentDown();
     761           0 :   json += "}";
     762           0 :   ret = writeIndented(json);
     763             :   
     764           0 :   if (ret < 0) {
     765           0 :     LOG(ERROR, __func__ << " FAILED");
     766           0 :     return ret;
     767             :   }
     768           0 :   size += ret;
     769           0 :   current_sandesh_context_.pop_back();
     770           0 :   is_first_element_context_.pop_back();
     771           0 :   if (is_first_element_context_.size() > 0) {
     772           0 :       is_first_element_context_.back() = false;
     773             :   }
     774           0 :   is_primitive_element_list_.pop_back();
     775           0 :   return size;
     776           0 : }
     777             : 
     778           0 : int32_t TJSONProtocol::writeBool(const bool value) {
     779           0 :   int32_t size = 0, ret;
     780           0 :   return writePlain(value ? kJSONBoolTrue : kJSONBoolFalse);
     781             : }
     782             : 
     783           0 : int32_t TJSONProtocol::writeByte(const int8_t byte) {
     784           0 :   return writePlain(integerToString(byte));
     785             : }
     786             : 
     787           0 : int32_t TJSONProtocol::writeI16(const int16_t i16) {
     788           0 :   return writePlain(integerToString(i16));
     789             : }
     790             : 
     791           0 : int32_t TJSONProtocol::writeI32(const int32_t i32) {
     792           0 :   int32_t size = 0, ret;
     793           0 :   string json;
     794           0 :   json.reserve(512);
     795           0 :   json += integerToString(i32);
     796           0 :   return writePlain(json);
     797           0 : }
     798             : 
     799           0 : int32_t TJSONProtocol::writeI64(const int64_t i64) {
     800           0 :   return writePlain(integerToString(i64));
     801             : }
     802             : 
     803           0 : int32_t TJSONProtocol::writeU16(const uint16_t u16) {
     804           0 :   return writePlain(integerToString(u16));
     805             : }
     806             : 
     807           0 : int32_t TJSONProtocol::writeU32(const uint32_t u32) {
     808           0 :   return writePlain(integerToString(u32));
     809             : }
     810             : 
     811           0 : int32_t TJSONProtocol::writeU64(const uint64_t u64) {
     812           0 :   return writePlain(integerToString(u64));
     813             : }
     814             : 
     815           0 : int32_t TJSONProtocol::writeIPV4(const uint32_t ip4) {
     816           0 :   return writePlain(integerToString(ip4));
     817             : }
     818             : 
     819           0 : int32_t TJSONProtocol::writeIPADDR(const boost::asio::ip::address& ipaddress) {
     820           0 :   return writePlain(ipaddress.to_string());
     821             : }
     822             : 
     823           0 : int32_t TJSONProtocol::writeDouble(const double dub) {
     824           0 :   return writePlain(integerToString(dub));
     825             : }
     826             : 
     827           0 : int32_t TJSONProtocol::writeString(const string& str) {
     828           0 :   int32_t size = 0, ret;
     829           0 :   string json;
     830           0 :   json.reserve(512);
     831           0 :   json += str;
     832             :   // Escape JSON control characters in the string before writing
     833           0 :   return writePlain(escapeJSONControlChars(json));
     834           0 : }
     835             : 
     836           0 : int32_t TJSONProtocol::writeBinary(const string& str) {
     837             :   // XXX Hex?
     838           0 :   return writeString(str);
     839             : }
     840             : 
     841           0 : int32_t TJSONProtocol::writeUUID(const boost::uuids::uuid& uuid) {
     842           0 :   const std::string str = boost::uuids::to_string(uuid);
     843           0 :   return writeString(str);
     844           0 : }
     845             : 
     846             : }}} // contrail::sandesh::protocol

Generated by: LCOV version 1.14