OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
TJSONProtocol.h
Go to the documentation of this file.
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 
23 class TJSONProtocol : public TVirtualProtocol<TJSONProtocol> {
24  private:
28  , LIST
29  , SET
30  , MAP
32  };
33 
34  public:
35  TJSONProtocol(boost::shared_ptr<TTransport> trans)
37  , trans_(trans.get())
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  static std::string escapeJSONControlCharsInternal(const std::string& str) {
62  std::string xmlstr;
63  xmlstr.reserve(str.length());
64  for (std::string::const_iterator it = str.begin();
65  it != str.end(); ++it) {
66  switch(*it) {
67  case '&': xmlstr += "&amp;"; break;
68  case '\'': xmlstr += "&apos;"; break;
69  case '<': xmlstr += "&lt;"; break;
70  case '>': xmlstr += "&gt;"; break;
71  default: xmlstr += *it;
72  }
73  }
74  return xmlstr;
75  }
76 
77  static std::string escapeJSONControlChars(const std::string& str) {
78  if (strpbrk(str.c_str(), "&'<>") != NULL) {
80  } else {
81  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 
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 
172  void setSandeshEnd(bool val) {
173  sandesh_end_ = val;
174  }
175 
177 
178  public:
179 
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:
228  bool hasData_;
229  uint8_t data_;
230  bool has2Data_;
231  uint8_t data2_[2];
233  };
234 
235  private:
236  typedef boost::tokenizer<boost::char_separator<char> >
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 
247 
248  int32_t string_limit_;
250 
251  std::string indent_str_;
252 
253  static const int indent_inc = 2;
254 
255  std::vector<write_state_t> write_state_;
256 
258 
260 
261  std::vector<bool> is_struct_begin_list_;
262 
263  std::vector<bool> is_list_begin_list_;
264 
266 
268 
270 
272 
274 
276 
278 
280 
282 
284 
286 
288 
290 
292 
294 
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_;
308  std::map<TType, bool> complexTypeSet;
309 
310 };
311 
316  public:
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 
int32_t writeBinary(const std::string &str)
int32_t writeU64(const uint64_t u64)
static std::string escapeJSONControlChars(const std::string &str)
Definition: TJSONProtocol.h:77
int32_t writeJSON(const std::string &str)
int32_t writeStructBegin(const char *name)
void setStringPrefixSize(int32_t string_prefix_size)
Definition: TJSONProtocol.h:57
int32_t writeU16(const uint16_t u16)
int32_t writeIPV4(const uint32_t ip4)
boost::uuids::uuid uuid
int32_t writeMapBegin(const TType keyType, const TType valType, const uint32_t size)
boost::tokenizer< boost::char_separator< char > > tokenizer
static const int32_t DEFAULT_STRING_PREFIX_SIZE
Definition: TJSONProtocol.h:51
int32_t writeFieldBegin(const char *name, const TType fieldType, const int16_t fieldId, const std::map< std::string, std::string > *const amap=NULL)
int32_t writeString(const std::string &str)
static const std::string & fieldTypeName(TType type)
int32_t writeSetBegin(const TType elemType, const uint32_t size)
int32_t readAll(uint8_t *buf, uint32_t len)
Definition: TTransport.h:125
uint8_t type
Definition: load_balance.h:109
int32_t writeIPADDR(const boost::asio::ip::address &ipaddress)
int32_t writePlain(const std::string &str)
int32_t writeI32(const int32_t i32)
int32_t writeMessageBegin(const std::string &name, const TMessageType messageType, const int32_t seqid)
static void unescapeJSONControlChars(std::string &str)
Definition: TJSONProtocol.h:85
static TType getTypeIDForTypeName(const std::string &name)
int32_t writeByte(const int8_t byte)
int32_t writeU32(const uint32_t u32)
std::vector< write_state_t > write_state_
static std::string escapeJSONControlCharsInternal(const std::string &str)
Definition: TJSONProtocol.h:61
std::vector< std::string > xml_state_
int32_t writeI16(const int16_t i16)
int32_t writeI64(const int64_t i64)
int32_t writeUUID(const boost::uuids::uuid &uuid)
int32_t writeSandeshBegin(const char *name)
int32_t writeListBegin(const TType elemType, const uint32_t size)
int32_t writeIndented(const std::string &str)
TJSONProtocol(boost::shared_ptr< TTransport > trans)
Definition: TJSONProtocol.h:35
boost::shared_ptr< TProtocol > getProtocol(boost::shared_ptr< TTransport > trans)
void setStringSizeLimit(int32_t string_limit)
Definition: TJSONProtocol.h:53
std::vector< std::string > current_sandesh_context_
int32_t writeDouble(const double dub)