OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
t_c_generator.cc
Go to the documentation of this file.
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied. See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  *
19  * Contains some contributions under the Thrift Software License.
20  * Please see doc/old-thrift-license.txt in the Thrift distribution for
21  * details.
22  */
23 
24 #include <fstream>
25 #include <iostream>
26 #include <string>
27 #include <vector>
28 
29 #include <ctype.h>
30 
31 #include "platform.h"
32 #include "t_oop_generator.h"
33 
34 using namespace std;
35 
36 /* forward declarations */
37 string initial_caps_to_underscores(string name);
38 string to_upper_case(string name);
39 string to_lower_case(string name);
40 
45  public:
46 
47  /* constructor */
49  const map<string, string> &parsed_options,
50  const string &option_string) : t_oop_generator(program)
51  {
52  (void) parsed_options;
53  (void) option_string;
54  /* set the output directory */
55  this->out_dir_base_ = "gen-c";
56 
57  /* set the namespace */
58  this->nspace = program_->get_namespace("c");
59 
60  if (this->nspace.empty()) {
61  this->nspace = "";
62  this->nspace_u = "";
63  this->nspace_uc = "";
64  this->nspace_lc = "";
65  } else {
66  /* replace dots with underscores */
67  char *tmp = strdup(this->nspace.c_str());
68  for (unsigned int i = 0; i < strlen(tmp); i++) {
69  if (tmp[i] == '.') {
70  tmp[i] = '_';
71  }
72  }
73  this->nspace = string(tmp, strlen(tmp));
74  free(tmp);
75 
76  /* clean up the namespace for C.
77  * An input of 'namespace foo' should result in:
78  * - nspace = foo - for thrift objects and typedefs
79  * - nspace_u = Foo - for internal GObject prefixes
80  * - nspace_uc = FOO_ - for macro prefixes
81  * - nspace_lc = foo_ - for filename and method prefixes
82  * The underscores are there since uc and lc strings are used as file and
83  * variable prefixes.
84  */
85  this->nspace_u = initial_caps_to_underscores(this->nspace);
86  this->nspace_uc = to_upper_case(this->nspace_u) + "_";
87  this->nspace_lc = to_lower_case(this->nspace_u) + "_";
88  }
89  }
90 
91  /* initialization and destruction */
92  void init_generator();
93  void close_generator();
94 
95  /* generation functions */
96  void generate_typedef(t_typedef *ttypedef);
97  void generate_enum(t_enum *tenum);
98  void generate_consts(vector<t_const *> consts);
99  void generate_struct(t_struct *tstruct);
100  void generate_service(t_service *tservice);
101  void generate_xception(t_struct *tstruct);
102  void generate_sandesh(t_sandesh *tsandesh);
103  void generate_sandesh_info();
104 
105  private:
106 
107  /* file streams */
108  ofstream f_types_;
109  ofstream f_types_impl_;
110  ofstream f_header_;
111  ofstream f_service_;
112 
113  /* namespace variables */
114  string nspace;
115  string nspace_u;
116  string nspace_uc;
117  string nspace_lc;
118 
119  /* helper functions */
120  bool is_complex_type(t_type *ttype);
121  string type_name(t_type* ttype, bool in_typedef=false, bool is_const=false);
122  string base_type_name(t_base_type *type);
123  string type_to_enum(t_type *type);
124  string constant_value(string name, t_type *type, t_const_value *value);
125  string argument_list(t_struct *tstruct);
126  string declare_field(t_field *tfield, bool init=false, bool pointer=false, bool constant=false, bool reference=false);
127 
128  /* generation functions */
129  void generate_const_initializer(string name, t_type *type, t_const_value *value);
130  void generate_service_client(t_service *tservice);
131  void generate_service_server(t_service *tservice);
132  void generate_object(t_struct *tstruct);
133  void generate_object(t_sandesh *tsandesh);
134  void generate_object_internal(string name, const vector<t_field *> &members, bool is_sandesh);
135  void generate_struct_writer(ofstream &out, string name, const vector<t_field *> &fields, bool is_sandesh, bool is_function=true);
136  void generate_struct_writer_to_buffer(ofstream &out, string name, const vector<t_field *> &fields, bool is_sandesh, bool is_function=true);
137  void generate_struct_reader(ofstream &out, string name, const vector<t_field *> &fields, bool is_sandesh, bool is_function=true);
138  void generate_struct_reader_from_buffer(ofstream &out, string name, const vector<t_field *> &fields, bool is_sandesh, bool is_function=true);
139  void generate_struct_deleter(ofstream &out, string name, const vector<t_field *> &fields, bool is_sandesh, bool is_function=true);
140 
141  void generate_buffer_bounds_chk(ofstream &out, string length, int error_ret);
142  void generate_buffer_incr_offset(ofstream &out, string length);
143 
144  void generate_write_buffer_memcpy(ofstream &out, string source, string length, bool ref);
145  void generate_write_buffer_memcpy_incr_offset(ofstream &out, string source, string length, bool ref);
146  void generate_write_buffer_chk_memcpy_incr_offset(ofstream &out, string source, string length, int error_ret, bool ref);
147  void generate_write_buffer_binary(ofstream &out, string buf, string buf_len, int error_ret);
148 
149  void generate_struct_begin_writer_to_buffer(ofstream &out, string name, bool is_sandesh, int error_ret);
150  void generate_struct_end_writer_to_buffer(ofstream &out, bool is_sandesh);
151  void generate_field_begin_writer_to_buffer(ofstream &out, string key, string field_type, int error_ret);
152  void generate_field_end_writer_to_buffer(ofstream &out);
153  void generate_field_stop_writer_to_buffer(ofstream &out, int error_ret);
154  void generate_list_begin_writer_to_buffer(ofstream &out, string element_type, string length, int error_ret);
155  void generate_list_end_writer_to_buffer(ofstream &out);
156 
157  void generate_serialize_bool_to_buffer(ofstream &out, string name, int error_ret);
158  void generate_serialize_byte_to_buffer(ofstream &out, string name, int error_ret);
159  void generate_serialize_i16_to_buffer(ofstream &out, string name, int error_ret);
160  void generate_serialize_i32_to_buffer(ofstream &out, string name, int error_ret);
161  void generate_serialize_i64_to_buffer(ofstream &out, string name, int error_ret);
162  void generate_serialize_u16_to_buffer(ofstream &out, string name, int error_ret);
163  void generate_serialize_u32_to_buffer(ofstream &out, string name, int error_ret);
164  void generate_serialize_u64_to_buffer(ofstream &out, string name, int error_ret);
165  void generate_serialize_string_to_buffer(ofstream &out, string name, int error_ret);
166  void generate_serialize_xml_to_buffer(ofstream &out, string name, int error_ret);
167  void generate_serialize_ipaddr_to_buffer(ofstream &out, string name, int error_ret);
168  void generate_serialize_uuid_t_to_buffer(ofstream &out, string name, int error_ret);
169  void generate_serialize_double_to_buffer(ofstream &out, string name, int error_ret);
170 
171  void generate_read_buffer_memcpy(ofstream &out, string dest, string length, bool ref);
172  void generate_read_buffer_memcpy_incr_offset(ofstream &out, string dest, string length, bool ref);
173  void generate_read_buffer_chk_memcpy_incr_offset(ofstream &out, string dest, string length, int error_ret, bool ref);
174 
175  void generate_struct_begin_reader_from_buffer(ofstream &out, string name, bool is_sandesh, int error_ret);
176  void generate_struct_end_reader_from_buffer(ofstream &out, bool is_sandesh);
177  void generate_field_begin_reader_from_buffer(ofstream &out, string field_type, string field_id, int error_ret);
178  void generate_field_end_reader_from_buffer(ofstream &out);
179  void generate_list_begin_reader_from_buffer(ofstream &out, string element_size, int error_ret);
180  void generate_list_end_reader_from_buffer(ofstream &out);
181 
182  void generate_deserialize_bool_from_buffer(ofstream &out, string name, int error_ret);
183  void generate_deserialize_byte_from_buffer(ofstream &out, string name, int error_ret);
184  void generate_deserialize_i16_from_buffer(ofstream &out, string name, int error_ret);
185  void generate_deserialize_i32_from_buffer(ofstream &out, string name, int error_ret);
186  void generate_deserialize_i64_from_buffer(ofstream &out, string name, int error_ret);
187  void generate_deserialize_u16_from_buffer(ofstream &out, string name, int error_ret);
188  void generate_deserialize_u32_from_buffer(ofstream &out, string name, int error_ret);
189  void generate_deserialize_u64_from_buffer(ofstream &out, string name, int error_ret);
190  void generate_deserialize_string_from_buffer(ofstream &out, string name, int error_ret);
191  void generate_deserialize_xml_from_buffer(ofstream &out, string name, int error_ret);
192  void generate_deserialize_ipaddr_from_buffer(ofstream &out, string name, int error_ret);
193  void generate_deserialize_uuid_t_from_buffer(ofstream &out, string name, int error_ret);
194  void generate_deserialize_double_from_buffer(ofstream &out, string name, int error_ret);
195 
196  void generate_serialize_field(ofstream &out, t_field *tfield, string prefix, string suffix, int error_ret);
197  void generate_serialize_field_to_buffer(ofstream &out, t_field *tfield, string prefix, string suffix, int error_ret);
198  void generate_serialize_struct(ofstream &out, t_struct *tstruct, string prefix, int error_ret);
199  void generate_serialize_struct_to_buffer(ofstream &out, t_struct *tstruct, string prefix, int error_ret);
200  void generate_serialize_container(ofstream &out, t_type *ttype, string prefix, int error_ret);
201  void generate_serialize_container_to_buffer(ofstream &out, t_type *ttype, string prefix, int error_ret);
202  void generate_serialize_list_element(ofstream &out, t_list *tlist, string list, string index, int error_ret);
203  void generate_serialize_list_element_to_buffer(ofstream &out, t_list *tlist, string list, string index, int error_ret);
204 
205  void generate_deserialize_field(ofstream &out, t_field *tfield, string prefix, string suffix, int error_ret);
206  void generate_deserialize_field_from_buffer(ofstream &out, t_field *tfield, string prefix, string suffix, int error_ret);
207  void generate_deserialize_struct(ofstream &out, t_struct *tstruct, string prefix, int error_ret);
208  void generate_deserialize_struct_from_buffer(ofstream &out, t_struct *tstruct, string prefix, int error_ret);
209  void generate_deserialize_container(ofstream &out, t_type *ttype, string prefix, int error_ret);
210  void generate_deserialize_container_from_buffer(ofstream &out, t_type *ttype, string prefix, int error_ret);
211  void generate_deserialize_list_element(ofstream &out, t_list *tlist, string prefix, string index, int error_ret);
212  void generate_deserialize_list_element_from_buffer(ofstream &out, t_list *tlist, string prefix, string index, int error_ret);
213 };
214 
220  /* create output directory */
221  MKDIR(get_out_dir().c_str());
222 
223  string program_name_u = initial_caps_to_underscores(program_name_);
224  string program_name_uc = to_upper_case(program_name_u);
225  string program_name_lc = to_lower_case(program_name_u);
226 
227  /* create output files */
228  string f_types_name = get_out_dir() + this->nspace_lc
229  + program_name_lc + "_types.h";
230  f_types_.open(f_types_name.c_str());
231  string f_types_impl_name = get_out_dir() + this->nspace_lc
232  + program_name_lc + "_types.c";
233  f_types_impl_.open(f_types_impl_name.c_str());
234 
235  /* add thrift boilerplate headers */
236  f_types_ << autogen_comment();
237  f_types_impl_ << autogen_comment();
238 
239  /* include inclusion guard */
240  f_types_ <<
241  "#ifndef " << this->nspace_uc << program_name_uc << "_TYPES_H" << endl <<
242  "#define " << this->nspace_uc << program_name_uc << "_TYPES_H" << endl <<
243  endl;
244 
245  /* include C++ compatibility */
246  f_types_ <<
247  "#ifdef __cplusplus" << endl <<
248  "extern \"C\" {" << endl <<
249  "#endif" << endl <<
250  endl;
251 
252  /* include base types */
253  f_types_ <<
254  "/* base includes */" << endl <<
255  "#include \"sandesh/library/c/sandesh.h\"" << endl;
256 
257  /* include other thrift includes */
258  const vector<t_program *> &includes = program_->get_includes();
259  for (size_t i = 0; i < includes.size(); ++i) {
260  f_types_ <<
261  "/* other thrift includes */" << endl <<
262  "#include \"" << this->nspace_lc << includes[i]->get_name() <<
263  "_types.h\"" << endl;
264  }
265  f_types_ << endl;
266 
267  /* include custom headers */
268  const vector<string> &c_includes = program_->get_c_includes();
269  f_types_ << "/* custom thrift includes */" << endl;
270  for (size_t i = 0; i < c_includes.size(); ++i) {
271  if (c_includes[i][0] == '<') {
272  f_types_ <<
273  "#include " << c_includes[i] << endl;
274  } else {
275  f_types_ <<
276  "#include \"" << c_includes[i] << "\"" << endl;
277  }
278  }
279  f_types_ << endl;
280 
281  // include the types file
282  f_types_impl_ <<
283  endl <<
284  "#include \"" << this->nspace_lc << program_name_u <<
285  "_types.h\"" << endl <<
286  endl;
287 
288  f_types_ <<
289  "/* begin types */" << endl << endl;
290 }
291 
296  string program_name_uc = to_upper_case
297  (initial_caps_to_underscores(program_name_));
298 
299  /* end the C++ compatibility */
300  f_types_ <<
301  "#ifdef __cplusplus" << endl <<
302  "}" << endl <<
303  "#endif" << endl <<
304  endl;
305 
306  /* end the header inclusion guard */
307  f_types_ <<
308  "#endif /* " << this->nspace_uc << program_name_uc << "_TYPES_H */" << endl;
309 
310  /* close output file */
311  f_types_.close();
312  f_types_impl_.close();
313 }
314 
325  f_types_ <<
326  indent() << "typedef " << type_name(ttypedef->get_type(), true) <<
327  " " << this->nspace << ttypedef->get_symbolic() << ";" << endl <<
328  endl;
329 }
330 
348  string name = tenum->get_name();
349  string name_uc = to_upper_case(initial_caps_to_underscores(name));
350 
351  f_types_ <<
352  indent() << "enum _" << this->nspace << name << " {" << endl;
353 
354  indent_up();
355 
356  vector<t_enum_value *> constants = tenum->get_constants();
357  vector<t_enum_value *>::iterator c_iter;
358  bool first = true;
359 
360  /* output each of the enumeration elements */
361  for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) {
362  if (first) {
363  first = false;
364  } else {
365  f_types_ << "," << endl;
366  }
367 
368  f_types_ <<
369  indent() << this->nspace_uc << name_uc << "_" << (*c_iter)->get_name();
370  if ((*c_iter)->has_value()) {
371  f_types_ <<
372  " = " << (*c_iter)->get_value();
373  }
374  }
375 
376  indent_down();
377  f_types_ <<
378  endl <<
379  "};" << endl <<
380  "typedef enum _" << this->nspace << name << " " << this->nspace << name << ";" << endl <<
381  endl;
382 }
383 
387 void t_c_generator::generate_consts (vector<t_const *> consts) {
388  f_types_ << "/* constants */" << endl;
389  f_types_impl_ << "/* constants */" << endl;
390 
391  vector<t_const *>::iterator c_iter;
392  for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter) {
393  string name = (*c_iter)->get_name();
394  string name_uc = to_upper_case(name);
395  string name_lc = to_lower_case(name);
396  t_type *type = (*c_iter)->get_type();
397  t_const_value *value = (*c_iter)->get_value();
398 
399  f_types_ <<
400  indent() << "#define " << this->nspace_uc << name_uc << " " <<
401  constant_value (name_lc, type, value) << endl;
402 
403  generate_const_initializer (name_lc, type, value);
404  }
405 
406  f_types_ << endl;
407  f_types_impl_ << endl;
408 }
409 
430  f_types_ << "/* struct " << tstruct->get_name() << " */" << endl;
431  generate_object(tstruct);
432 }
433 
438  f_types_ << "/* sandesh " << tsandesh->get_name() << " */" << endl;
439  generate_object(tsandesh);
440 }
441 
446  string program_name_u = initial_caps_to_underscores(program_name_);
447  string program_name_lc = to_lower_case(program_name_u);
448  ofstream &out = f_types_impl_;
449  out << endl <<
450  "static sandesh_info_t " << program_name_lc << "_infos[] = {" << endl;
451  vector<t_sandesh*> sandeshs = program_->get_sandeshs();
452  vector<t_sandesh*>::iterator s_iter;
453  indent_up();
454  for (s_iter = sandeshs.begin(); s_iter != sandeshs.end(); ++s_iter) {
455  string sandesh_name = get_sandesh_name(*s_iter);
456  string sandesh_name_u = initial_caps_to_underscores(sandesh_name);
457  out << indent() << "{" << endl;
458  indent_up();
459  out <<
460  indent() << ".name = \"" << sandesh_name << "\"," << endl <<
461  indent() << ".size = sizeof(" << sandesh_name << ")," << endl <<
462  indent() << ".read = " << sandesh_name_u << "_read," << endl <<
463  indent() << ".read_binary_from_buffer = " << sandesh_name_u << "_read_binary_from_buffer," << endl <<
464  indent() << ".write = " << sandesh_name_u << "_write," << endl <<
465  indent() << ".write_binary_to_buffer = " << sandesh_name_u << "_write_binary_to_buffer," << endl <<
466  indent() << ".process = " << sandesh_name_u << "_process," << endl <<
467  indent() << ".free = " << sandesh_name_u << "_free," << endl;
468  indent_down();
469  out << indent() << "}," << endl;
470  }
471  // Add end of array marker
472  out << indent() << "{" << endl;
473  indent_up();
474  out <<
475  indent() << ".name = NULL," << endl <<
476  indent() << ".size = 0," << endl <<
477  indent() << ".read = NULL," << endl <<
478  indent() << ".read_binary_from_buffer = NULL," << endl <<
479  indent() << ".write = NULL," << endl <<
480  indent() << ".write_binary_to_buffer = NULL," << endl <<
481  indent() << ".process = NULL," << endl <<
482  indent() << ".free = NULL," << endl;
483  indent_down();
484  out << indent() << "}, " << endl;
485  indent_down();
486  out << "};" << endl << endl;
487 
488  // Generate the extract function
489  out << "sandesh_info_t *" << endl
490  << program_name_lc <<
491  "_find_sandesh_info (const char *sname)" << endl;
492  out << "{" << endl;
493  indent_up();
494  out << indent() << "return sandesh_find_info(" << program_name_lc <<
495  "_infos, sname);" << endl;
496  indent_down();
497  out << "}" << endl << endl;
498 
499  // Generate the extract function declaration
500  f_types_ << endl <<
501  "sandesh_info_t * " << program_name_lc <<
502  "_find_sandesh_info(const char *sname);" << endl;
503 }
504 
510  // NOT IMPLEMENTED
511 }
512 
517  // NOT IMPLEMENTED
518 }
519 
520 /********************
521  * HELPER FUNCTIONS *
522  ********************/
523 
528  ttype = get_true_type (ttype);
529 
530  return ttype->is_container()
531  || ttype->is_struct()
532  || ttype->is_xception()
533  || (ttype->is_base_type()
534  && (((t_base_type *) ttype)->get_base()
536  ((t_base_type *) ttype)->get_base()
537  == t_base_type::TYPE_XML));
538 }
539 
540 
544 string t_c_generator::type_name (t_type* ttype, bool in_typedef, bool is_const) {
545  (void) in_typedef;
546  if (ttype->is_base_type()) {
547  string bname = base_type_name ((t_base_type *) ttype);
548 
549  if (is_const) {
550  return "const " + bname;
551  } else {
552  return bname;
553  }
554  }
555 
556  if (ttype->is_container()) {
557  string cname;
558 
559  t_container *tcontainer = (t_container *) ttype;
560  if (tcontainer->has_cpp_name()) {
561  cname = tcontainer->get_cpp_name();
562  } else if (ttype->is_map()) {
563  throw "compiler error: no C support for map";
564  } else if (ttype->is_set()) {
565  throw "compiler error: no C support for set";
566  } else if (ttype->is_list()) {
567  t_type *etype = ((t_list *) ttype)->get_elem_type();
568  if (etype->is_base_type()) {
569  cname = base_type_name((t_base_type *) etype) + " *";
570  } else {
571  cname = type_name(etype, in_typedef, is_const);
572  }
573  }
574 
575  if (is_const) {
576  return "const " + cname;
577  } else {
578  return cname;
579  }
580  }
581 
582  // check for a namespace
583  string pname = this->nspace + ttype->get_name();
584 
585  if (is_complex_type (ttype)) {
586  pname += " *";
587  }
588 
589  if (is_const) {
590  return "const " + pname;
591  } else {
592  return pname;
593  }
594 }
595 
600  t_base_type::t_base tbase = type->get_base();
601 
602  switch (tbase) {
604  return "void";
606  if (type->is_binary()) {
607  return "u_int8_t *";
608  } else {
609  return "char *";
610  }
611  case t_base_type::TYPE_XML:
612  return "char *";
614  return "u_int8_t";
616  return "int8_t";
618  return "int16_t";
620  return "int32_t";
622  return "int64_t";
623  case t_base_type::TYPE_U16:
624  return "uint16_t";
625  case t_base_type::TYPE_U32:
626  return "uint32_t";
627  case t_base_type::TYPE_U64:
628  return "uint64_t";
630  return "double";
631  case t_base_type::TYPE_IPV4:
632  return "uint32_t";
633  case t_base_type::TYPE_IPADDR:
634  return "ipaddr_t";
635  case t_base_type::TYPE_UUID:
636  return "ct_uuid_t";
637  default:
638  throw "compiler error: no C base type name for base type "
639  + t_base_type::t_base_name (tbase);
640  }
641 }
642 
648  type = get_true_type (type);
649 
650  if (type->is_base_type()) {
651  t_base_type::t_base tbase = ((t_base_type *) type)->get_base();
652 
653  switch (tbase) {
655  throw "NO T_VOID CONSTRUCT";
657  case t_base_type::TYPE_STATIC_CONST_STRING:
658  case t_base_type::TYPE_SANDESH_SYSTEM:
659  case t_base_type::TYPE_SANDESH_REQUEST:
660  case t_base_type::TYPE_SANDESH_RESPONSE:
661  case t_base_type::TYPE_SANDESH_TRACE:
662  case t_base_type::TYPE_SANDESH_TRACE_OBJECT:
663  case t_base_type::TYPE_SANDESH_BUFFER:
664  case t_base_type::TYPE_SANDESH_UVE:
665  case t_base_type::TYPE_SANDESH_OBJECT:
666  case t_base_type::TYPE_SANDESH_FLOW:
667  return "T_STRING";
669  return "T_BOOL";
671  return "T_BYTE";
673  return "T_I16";
675  return "T_I32";
677  return "T_I64";
678  case t_base_type::TYPE_U16:
679  return "T_U16";
680  case t_base_type::TYPE_U32:
681  return "T_U32";
682  case t_base_type::TYPE_U64:
683  return "T_U64";
684  case t_base_type::TYPE_XML:
685  return "T_XML";
687  return "T_DOUBLE";
688  case t_base_type::TYPE_IPV4:
689  return "T_IPV4";
690  case t_base_type::TYPE_IPADDR:
691  return "T_IPADDR";
692  case t_base_type::TYPE_UUID:
693  return "T_UUID";
694  }
695  } else if (type->is_enum()) {
696  return "T_I32";
697  } else if (type->is_struct()) {
698  return "T_STRUCT";
699  } else if (type->is_xception()) {
700  return "T_STRUCT";
701  } else if (type->is_map()) {
702  return "T_MAP";
703  } else if (type->is_set()) {
704  return "T_SET";
705  } else if (type->is_list()) {
706  return "T_LIST";
707  }
708 
709  throw "INVALID TYPE IN type_to_enum: " + type->get_name();
710 }
711 
712 
717  ostringstream render;
718 
719  if (type->is_base_type()) {
720  /* primitives */
721  t_base_type::t_base tbase = ((t_base_type *) type)->get_base();
722  switch (tbase) {
724  case t_base_type::TYPE_XML:
725  render << "\"" + value->get_string() + "\"";
726  break;
728  render << ((value->get_integer() != 0) ? 1 : 0);
729  break;
734  case t_base_type::TYPE_U16:
735  case t_base_type::TYPE_U32:
736  case t_base_type::TYPE_U64:
737  case t_base_type::TYPE_IPV4:
738  render << value->get_integer();
739  break;
740  case t_base_type::TYPE_UUID:
741  render << value->get_uuid(); // Need to fix later, c structure is not getting initialize.
742  break;
744  if (value->get_type() == t_const_value::CV_INTEGER) {
745  render << value->get_integer();
746  } else {
747  render << value->get_double();
748  }
749  break;
750  default:
751  throw "compiler error: no const of base type "
752  + t_base_type::t_base_name (tbase);
753  }
754  } else if (type->is_enum()) {
755  render << "(" << type_name (type) << ")" << value->get_integer();
756  } else if (type->is_struct() || type->is_xception() || type->is_list()
757  || type->is_set() || type->is_map()) {
758  render << "(" << this->nspace_lc <<
759  to_lower_case(name) << "_constant())";
760  } else {
761  render << "NULL /* not supported */";
762  }
763 
764  return render.str();
765 }
766 
774  string result = "";
775 
776  const vector<t_field*>& fields = tstruct->get_members();
777  vector<t_field*>::const_iterator f_iter;
778  bool first = true;
779  for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
780  if (first) {
781  first = false;
782  } else {
783  result += ", ";
784  }
785  result += type_name((*f_iter)->get_type(), false, true) + " " +
786  (*f_iter)->get_name();
787  }
788  return result;
789 }
790 
795  bool init,
796  bool pointer,
797  bool constant,
798  bool reference) {
799  string result = "";
800  if (constant) {
801  result += "const ";
802  }
803  result += type_name(tfield->get_type());
804  if (pointer) {
805  result += "*";
806  }
807  if (reference) {
808  result += "*";
809  }
810  result += " " + tfield->get_name();
811  if (init) {
812  t_type* type = get_true_type(tfield->get_type());
813 
814  if (type->is_base_type()) {
815  t_base_type::t_base tbase = ((t_base_type *) type)->get_base();
816  switch (tbase) {
818  break;
824  case t_base_type::TYPE_U16:
825  case t_base_type::TYPE_U32:
826  case t_base_type::TYPE_U64:
827  case t_base_type::TYPE_IPV4:
828  result += " = 0";
829  break;
831  result += " = (gdouble) 0";
832  break;
834  case t_base_type::TYPE_XML:
835  result += " = NULL";
836  break;
837  case t_base_type::TYPE_UUID:
838  result += "{0}";
839  break;
840  default:
841  throw "compiler error: no C intializer for base type "
842  + t_base_type::t_base_name (tbase);
843  }
844  } else if (type->is_enum()) {
845  result += " = (" + type_name (type) + ") 0";
846  }
847  }
848 
849  if (!reference) {
850  result += ";";
851  }
852 
853  return result;
854 }
855 
860  string name_u = initial_caps_to_underscores(name);
861  string name_lc = to_lower_case(name_u);
862  string type_u = initial_caps_to_underscores(type->get_name());
863  string type_uc = to_upper_case(type_u);
864 
865  if (type->is_struct() || type->is_xception()) {
866  throw "compiler error: no support for const struct or exception";
867  } else if (type->is_list()) {
868  throw "compiler error: no support for const array";
869  } else if (type->is_set()) {
870  throw "compiler error: no support for const set";
871  } else if (type->is_map()) {
872  throw "compiler error: no support for const map";
873  }
874 }
875 
880  // NOT IMPLEMENTED
881 }
882 
887  // NOT IMPLEMENTED
888 }
889 
894  string name = tsandesh->get_name();
895  generate_object_internal(name, tsandesh->get_members(), true);
896 }
897 
902  string name = tstruct->get_name();
903  generate_object_internal(name, tstruct->get_members(), false);
904 }
905 
910  const vector<t_field *> &members,
911  bool is_sandesh) {
912  string name_u = initial_caps_to_underscores(name);
913  string name_uc = to_upper_case(name_u);
914  string dtname = is_sandesh ? "void" : name;
915  string dvname = is_sandesh ? "sandesh" : name_u;
916 
917  // write the instance definition
918  f_types_ <<
919  "struct _" << this->nspace << name << endl <<
920  "{ " << endl <<
921  " /* public */" << endl;
922 
923  // for each field, add a member variable
924  vector<t_field *>::const_iterator m_iter;
925  for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
926  // Ignore auto generated fields
927  if ((*m_iter)->get_auto_generated()) {
928  continue;
929  }
930  t_type *t = get_true_type ((*m_iter)->get_type());
931  f_types_ <<
932  " " << type_name (t) << " " << (*m_iter)->get_name() << ";" << endl;
933  if (t->is_list()) {
934  // Auto-generate size for the list
935  f_types_ << " " << "u_int32_t " << (*m_iter)->get_name() << "_size;"
936  << endl;
937  }
938  if ((*m_iter)->get_req() != t_field::T_REQUIRED) {
939  f_types_ <<
940  " u_int8_t __isset_" << (*m_iter)->get_name() << ";" << endl;
941  }
942  }
943 
944  // close the structure definition and create a typedef
945  f_types_ <<
946  "};" << endl <<
947  "typedef struct _" << this->nspace << name << " " <<
948  this->nspace << name << ";" << endl <<
949  endl;
950 
951  // prototypes for struct I/O methods
952  f_types_ <<
953  "int32_t " <<
954  this->nspace_lc << name_u <<
955  "_write (" << dtname <<
956  "* w" << dvname << ", ThriftProtocol *protocol, int *error);" << endl;
957  f_types_ <<
958  "int32_t " <<
959  this->nspace_lc << name_u <<
960  "_write_binary_to_buffer (" << dtname <<
961  "* w" << dvname << ", uint8_t *buf, const size_t buf_len, int *error);" << endl;
962  f_types_ <<
963  "int32_t " <<
964  this->nspace_lc << name_u <<
965  "_read (" << dtname <<
966  "* r" << dvname << ", ThriftProtocol *protocol, int *error);" << endl;
967  f_types_ <<
968  "int32_t " <<
969  this->nspace_lc << name_u <<
970  "_read_binary_from_buffer (" << dtname <<
971  "* r" << dvname << ", uint8_t *buf, const size_t buf_len, int *error);" << endl;
972  f_types_ <<
973  "void " <<
974  this->nspace_lc << name_u <<
975  "_free(" << dtname <<
976  "* f" << dvname << ");" << endl;
977  if (is_sandesh) {
978  f_types_ <<
979  "void " <<
980  this->nspace_lc << name_u <<
981  "_process (void *p" << name_u << ");" << endl;
982  }
983 
984  // start writing the object implementation .c file
985  // generate struct I/O methods
986  generate_struct_reader (f_types_impl_, name, members, is_sandesh);
987  generate_struct_reader_from_buffer (f_types_impl_, name, members, is_sandesh);
988  generate_struct_writer (f_types_impl_, name, members, is_sandesh);
989  generate_struct_writer_to_buffer (f_types_impl_, name, members, is_sandesh);
990  generate_struct_deleter (f_types_impl_, name, members, is_sandesh);
991 }
992 
997  string name,
998  const vector<t_field *> &fields,
999  bool is_sandesh,
1000  bool is_function) {
1001  string name_u = initial_caps_to_underscores(name);
1002  string fname = "f" + name_u;
1003  string sname = is_sandesh ? "sandesh" : "struct";
1004  string dname = is_sandesh ? "void" : name;
1005  string dfname = is_sandesh ? "fsandesh" : fname;
1006 
1007  vector <t_field *>::const_iterator f_iter;
1008 
1009  if (is_function) {
1010  indent(out) <<
1011  "void" << endl <<
1012  this->nspace_lc << name_u <<
1013  "_free (" << dname <<
1014  "* " << dfname << ")" << endl;
1015  }
1016  indent(out) << "{" << endl;
1017  indent_up();
1018 
1019  if (is_sandesh) {
1020  out << indent() << name << "* " << fname << " = " <<
1021  "(" << name << "* ) " << dfname << ";" <<
1022  endl << endl;
1023  }
1024 
1025  // satisfy -Wall in case we don't use some variables
1026  out <<
1027  indent() << "/* satisfy -Wall in case these aren't used */" << endl <<
1028  indent() << "THRIFT_UNUSED_VAR (" << fname << ");" << endl;
1029 
1030  for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
1031  // Ignore auto generated fields
1032  if ((*f_iter)->get_auto_generated()) {
1033  continue;
1034  }
1035  t_type *type = get_true_type ((*f_iter)->get_type());
1036  string fvname = fname + "->" + (*f_iter)->get_name();
1037  if (type->is_struct() || type->is_xception()) {
1038  indent(out) << "if (" << fvname << ") {" << endl;
1039  indent_up();
1040  indent(out) << ((t_struct *)type)->get_name() << "_free(" <<
1041  fvname << ");" << endl;
1042  indent(out) << "os_free(" << fvname << ");" << endl;
1043  indent(out) << fvname << " = NULL;" << endl;
1044  scope_down(out);
1045  } else if (type->is_container()) {
1046  indent(out) << "if (" << fvname << ") {" << endl;
1047  indent_up();
1048  indent(out) << "os_free(" << fvname << ");" << endl;
1049  indent(out) << fvname << "_size = 0;" << endl;
1050  indent(out) << fvname << " = NULL;" << endl;
1051  scope_down(out);
1052  } else if (type->is_base_type()) {
1053  t_base_type::t_base tbase = ((t_base_type *) type)->get_base();
1054  switch (tbase) {
1056  case t_base_type::TYPE_XML:
1057  indent(out) << "if (" << fvname << ") {" << endl;
1058  indent_up();
1059  indent(out) << "os_free(" << fvname << ");" << endl;
1060  indent(out) << fvname << " = NULL;" << endl;
1061  scope_down(out);
1062  break;
1063 
1064  default:
1065  break;
1066  }
1067  }
1068  }
1069  indent_down();
1070  indent(out) <<
1071  "}" << endl <<
1072  endl;
1073 }
1074 
1076  string length,
1077  int error_ret) {
1078  out <<
1079  indent() << "if (Xbuflen < Xoffset + " << length << ") {" << endl <<
1080  indent() << " return " << error_ret << ";" << endl <<
1081  indent() << "}" << endl;
1082 }
1083 
1085  string length) {
1086  out <<
1087  indent() << "Xoffset += " << length << ";" << endl;
1088 }
1089 
1091  string source,
1092  string length,
1093  bool ref) {
1094  if (ref) {
1095  out <<
1096  indent() << "memcpy (Xbuf + Xoffset, &" << source << ", " <<
1097  length << ");" << endl;
1098  } else {
1099  out <<
1100  indent() << "memcpy (Xbuf + Xoffset, " << source << ", " <<
1101  length << ");" << endl;
1102  }
1103 }
1104 
1106  string dest,
1107  string length,
1108  bool ref) {
1109  if (ref) {
1110  out <<
1111  indent() << "memcpy (&" << dest << ", Xbuf + Xoffset, " <<
1112  length << ");" << endl;
1113  } else {
1114  out <<
1115  indent() << "memcpy (" << dest << ", Xbuf + Xoffset, " <<
1116  length << ");" << endl;
1117  }
1118 }
1119 
1121  string source,
1122  string length,
1123  bool ref) {
1124  generate_write_buffer_memcpy (out, source, length, ref);
1125  generate_buffer_incr_offset (out, length);
1126 }
1127 
1129  string dest,
1130  string length,
1131  bool ref) {
1132  generate_read_buffer_memcpy (out, dest, length, ref);
1133  generate_buffer_incr_offset (out, length);
1134 }
1135 
1137  string source,
1138  string length,
1139  int error_ret,
1140  bool ref) {
1141  generate_buffer_bounds_chk (out, length, error_ret);
1142  generate_write_buffer_memcpy_incr_offset (out, source, length, ref);
1143 }
1144 
1146  string dest,
1147  string length,
1148  int error_ret,
1149  bool ref) {
1150  generate_buffer_bounds_chk (out, length, error_ret);
1151  generate_read_buffer_memcpy_incr_offset (out, dest, length, ref);
1152 }
1153 
1154 void t_c_generator::generate_write_buffer_binary(ofstream &out, string buf,
1155  string buf_len, int error_ret) {
1156  string nbuf_len(tmp("Xnbuflen"));
1157  generate_buffer_bounds_chk (out, "4", error_ret);
1158  scope_up(out);
1159  out <<
1160  indent() << "int32_t " << nbuf_len << " = htonl (" <<
1161  buf_len << ");" << endl;
1162  generate_write_buffer_memcpy_incr_offset (out, nbuf_len, "4", true);
1163  scope_down(out);
1164  generate_write_buffer_chk_memcpy_incr_offset (out, buf, buf_len, error_ret,
1165  false);
1166 }
1167 
1169  string name,
1170  bool is_sandesh,
1171  int error_ret) {
1172  if (is_sandesh) {
1173  ostringstream os;
1174  os << name.length();
1175  string name_len(os.str());
1176  out <<
1177  indent() << "/* thrift_protocol_write_sandesh_begin */" << endl;
1178  generate_write_buffer_binary (out, "\"" + name + "\"", name_len,
1179  error_ret);
1180  } else {
1181  out << indent() << "/* thrift_protocol_write_struct_begin */" << endl;
1182  }
1183 }
1184 
1186  string name,
1187  bool is_sandesh,
1188  int error_ret) {
1189  if (is_sandesh) {
1190  out <<
1191  indent() << "/* thrift_protocol_read_sandesh_begin */" << endl;
1192  generate_deserialize_string_from_buffer (out, name, error_ret);
1193  out <<
1194  indent() << "if (" << name << ") { os_free (" << name << "); " <<
1195  name << " = NULL; }" << endl << endl;
1196  } else {
1197  out << indent() << "/* thrift_protocol_read_struct_begin */" << endl;
1198  }
1199 }
1200 
1202  bool is_sandesh) {
1203  if (is_sandesh) {
1204  out << indent() << "/* thrift_protocol_write_sandesh_send */" << endl;
1205  } else {
1206  out << indent() << "/* thrift_protocol_write_struct_send */" << endl;
1207  }
1208 }
1209 
1211  bool is_sandesh) {
1212  if (is_sandesh) {
1213  out << indent() << "/* thrift_protocol_read_sandesh_send */" << endl;
1214  } else {
1215  out << indent() << "/* thrift_protocol_read_struct_send */" << endl;
1216  }
1217 }
1218 
1220  int error_ret) {
1221  string field_stop(tmp("Xfield_stop"));
1222  out << endl <<
1223  indent() << "/* thrift_protocol_field_stop */" << endl;
1224  generate_buffer_bounds_chk (out, "1", error_ret);
1225  scope_up(out);
1226  out <<
1227  indent() << "int8_t " << field_stop << " = (int8_t) T_STOP;" << endl;
1228  generate_write_buffer_memcpy_incr_offset (out, field_stop, "1", true);
1229  scope_down(out);
1230 }
1231 
1233  string name,
1234  const vector<t_field *> &fields,
1235  bool is_sandesh,
1236  bool is_function) {
1237  string name_u = initial_caps_to_underscores(name);
1238  string wname = "w" + name_u;
1239  string sname = is_sandesh ? "sandesh" : "struct";
1240  string dname = is_sandesh ? "void" : name;
1241  string dwname = is_sandesh ? "wsandesh" : wname;
1242 
1243  vector <t_field *>::const_iterator f_iter;
1244  int error_ret = 0;
1245 
1246  if (is_function) {
1247  error_ret = -1;
1248  indent(out) <<
1249  "int32_t" << endl <<
1250  this->nspace_lc << name_u << "_write_binary_to_buffer (" <<
1251  dname << "* " << dwname <<
1252  ", uint8_t *Xbuf, const size_t Xbuflen, int *Xerror)" << endl;
1253  }
1254  indent(out) << "{" << endl;
1255  indent_up();
1256 
1257  out <<
1258  indent() << "int32_t Xret;" << endl <<
1259  indent() << "int32_t Xoffset = 0;" << endl <<
1260  indent() << "u_int32_t Xi;" << endl <<
1261  endl;
1262 
1263  if (is_sandesh) {
1264  out << indent() << name << "* " << wname << " = " <<
1265  "(" << name << "* ) " << dwname << ";" <<
1266  endl << endl;
1267  }
1268 
1269  // satisfy -Wall in case we don't use some variables
1270  out <<
1271  indent() << "/* satisfy -Wall in case these aren't used */" << endl <<
1272  indent() << "THRIFT_UNUSED_VAR (Xret);" << endl <<
1273  indent() << "THRIFT_UNUSED_VAR (Xi);" << endl <<
1274  indent() << "THRIFT_UNUSED_VAR (" << wname << ");" << endl;
1275 
1276  out << endl;
1277 
1278  generate_struct_begin_writer_to_buffer(out, name, is_sandesh, error_ret);
1279 
1280  for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
1281  // Ignore auto generated fields
1282  if ((*f_iter)->get_auto_generated()) {
1283  continue;
1284  }
1285  if ((*f_iter)->get_req() == t_field::T_OPTIONAL) {
1286  indent(out) << "if (" << wname << "->__isset_" << (*f_iter)->get_name() << " == 1) {" << endl;
1287  indent_up();
1288  }
1289  ostringstream key_os;
1290  key_os << (*f_iter)->get_key();
1291  string key(key_os.str());
1292  string tenum(type_to_enum((*f_iter)->get_type()));
1293  generate_field_begin_writer_to_buffer (out, key, tenum, error_ret);
1294  generate_serialize_field_to_buffer (out, *f_iter, wname + "->", "", error_ret);
1295  generate_field_end_writer_to_buffer (out);
1296  if ((*f_iter)->get_req() == t_field::T_OPTIONAL) {
1297  indent(out) << "if (" << wname << "->__isset_" << (*f_iter)->get_name() << " == 1) {" << endl;
1298  indent_up();
1299  }
1300  }
1301  generate_field_stop_writer_to_buffer(out, error_ret);
1302  generate_struct_end_writer_to_buffer(out, is_sandesh);
1303  if (is_function) {
1304  indent(out) << "return Xoffset;" << endl;
1305  }
1306 
1307  indent_down();
1308  indent(out) <<
1309  "}" << endl <<
1310  endl;
1311 }
1312 
1317  string name,
1318  const vector<t_field *> &fields,
1319  bool is_sandesh,
1320  bool is_function) {
1321  string name_u = initial_caps_to_underscores(name);
1322  string wname = "w" + name_u;
1323  string sname = is_sandesh ? "sandesh" : "struct";
1324  string dname = is_sandesh ? "void" : name;
1325  string dwname = is_sandesh ? "wsandesh" : wname;
1326 
1327  vector <t_field *>::const_iterator f_iter;
1328  int error_ret = 0;
1329 
1330  if (is_function) {
1331  error_ret = -1;
1332  indent(out) <<
1333  "int32_t" << endl <<
1334  this->nspace_lc << name_u <<
1335  "_write (" << dname <<
1336  "* " << dwname << ", ThriftProtocol *protocol, int *error)" << endl;
1337  }
1338  indent(out) << "{" << endl;
1339  indent_up();
1340 
1341  out <<
1342  indent() << "int32_t ret;" << endl <<
1343  indent() << "int32_t xfer = 0;" << endl <<
1344  indent() << "u_int32_t i;" << endl <<
1345  endl;
1346 
1347  if (is_sandesh) {
1348  out << indent() << name << "* " << wname << " = " <<
1349  "(" << name << "* ) " << dwname << ";" <<
1350  endl << endl;
1351  }
1352 
1353  // satisfy -Wall in case we don't use some variables
1354  out <<
1355  indent() << "/* satisfy -Wall in case these aren't used */" << endl <<
1356  indent() << "THRIFT_UNUSED_VAR (i);" << endl <<
1357  indent() << "THRIFT_UNUSED_VAR (" << wname << ");" << endl;
1358 
1359  out << endl;
1360 
1361  out <<
1362  indent() << "if ((ret = thrift_protocol_write_" << sname << "_begin (protocol, \"" << name << "\", error)) < 0)" << endl <<
1363  indent() << " return " << error_ret << ";" << endl <<
1364  indent() << "xfer += ret;" << endl;
1365 
1366  for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
1367  // Ignore auto generated fields
1368  if ((*f_iter)->get_auto_generated()) {
1369  continue;
1370  }
1371  if ((*f_iter)->get_req() == t_field::T_OPTIONAL) {
1372  indent(out) << "if (" << wname << "->__isset_" << (*f_iter)->get_name() << " == 1) {" << endl;
1373  indent_up();
1374  }
1375 
1376  out <<
1377  indent() << "if ((ret = thrift_protocol_write_field_begin (protocol, " <<
1378  "\"" << (*f_iter)->get_name() << "\", " <<
1379  type_to_enum ((*f_iter)->get_type()) << ", " <<
1380  (*f_iter)->get_key() << ", error)) < 0)" << endl <<
1381  indent() << " return " << error_ret << ";" << endl <<
1382  indent() << "xfer += ret;" << endl;
1383  generate_serialize_field (out, *f_iter, wname + "->", "", error_ret);
1384  out <<
1385  indent() << "xfer += ret;" << endl;
1386  out <<
1387  indent() << "if ((ret = thrift_protocol_write_field_end (protocol, error)) < 0)" << endl <<
1388  indent() << " return " << error_ret << ";" << endl <<
1389  indent() << "xfer += ret;" << endl;
1390 
1391  if ((*f_iter)->get_req() == t_field::T_OPTIONAL) {
1392  indent_down();
1393  indent(out) << "}" << endl;
1394  }
1395  }
1396 
1397  // write the struct map
1398  out <<
1399  indent() << "if ((ret = thrift_protocol_write_field_stop (protocol, error)) < 0)" << endl <<
1400  indent() << " return " << error_ret << ";" << endl <<
1401  indent() << "xfer += ret;" << endl <<
1402  indent() << "if ((ret = thrift_protocol_write_" << sname << "_end (protocol, error)) < 0)" << endl <<
1403  indent() << " return " << error_ret << ";" << endl <<
1404  indent() << "xfer += ret;" << endl <<
1405  endl;
1406 
1407  if (is_function) {
1408  indent(out) << "return xfer;" << endl;
1409  }
1410 
1411  indent_down();
1412  indent(out) <<
1413  "}" << endl <<
1414  endl;
1415 }
1416 
1421  string name,
1422  const vector <t_field *> &fields,
1423  bool is_sandesh,
1424  bool is_function) {
1425  string name_u = initial_caps_to_underscores(name);
1426  string rname = "r" + name_u;
1427  int error_ret = 0;
1428  vector <t_field *>::const_iterator f_iter;
1429  string sname = is_sandesh ? "sandesh" : "struct";
1430  string dname = is_sandesh ? "void" : name;
1431  string drname = is_sandesh ? "rsandesh" : rname;
1432 
1433  if (is_function) {
1434  error_ret = -1;
1435  indent(out) <<
1436  "/* reads a " << name_u << " " << sname << " */" << endl <<
1437  "int32_t" << endl <<
1438  this->nspace_lc << name_u <<
1439  "_read (" << dname <<
1440  " *" << drname << ", ThriftProtocol *protocol, int *error)" << endl;
1441  }
1442 
1443  indent(out) << "{" << endl;
1444  indent_up();
1445 
1446  // declare stack temp variables
1447  out <<
1448  indent() << "int32_t ret;" << endl <<
1449  indent() << "int32_t xfer = 0;" << endl <<
1450  indent() << "char *name;" << endl <<
1451  indent() << "ThriftType ftype;" << endl <<
1452  indent() << "int16_t fid;" << endl <<
1453  indent() << "u_int32_t len = 0, i;" << endl <<
1454  indent() << "void *data = NULL;" << endl;
1455 
1456  if (is_sandesh) {
1457  out << indent() << name << "* " << rname << " = " <<
1458  "(" << name << "* ) " << drname << ";" << endl;
1459  }
1460 
1461  for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
1462  // Ignore auto generated fields
1463  if ((*f_iter)->get_auto_generated()) {
1464  continue;
1465  }
1466  if ((*f_iter)->get_req() == t_field::T_REQUIRED) {
1467  indent(out) << "u_int8_t isset_" << (*f_iter)->get_name() << " = 0;" << endl;
1468  }
1469  }
1470 
1471  // satisfy -Wall in case we don't use some variables
1472  out <<
1473  indent() << "/* satisfy -Wall in case these aren't used */" << endl <<
1474  indent() << "THRIFT_UNUSED_VAR (len);" << endl <<
1475  indent() << "THRIFT_UNUSED_VAR (data);" << endl <<
1476  indent() << "THRIFT_UNUSED_VAR (i);" << endl <<
1477  indent() << "THRIFT_UNUSED_VAR (" << rname << ");" << endl;
1478 
1479  out << endl;
1480 
1481  // read the beginning of the structure marker
1482  out <<
1483  indent() << "/* read the " << sname << " begin marker */" << endl <<
1484  indent() << "if ((ret = thrift_protocol_read_" << sname << "_begin (protocol, &name, error)) < 0)" << endl <<
1485  indent() << "{" << endl <<
1486  indent() << " if (name) os_free (name);" << endl <<
1487  indent() << " return " << error_ret << ";" << endl <<
1488  indent() << "}" << endl <<
1489  indent() << "xfer += ret;" << endl <<
1490  indent() << "if (name) { os_free (name); name = NULL; }" << endl <<
1491  endl;
1492 
1493  // read the struct fields
1494  out <<
1495  indent() << "/* read the struct fields */" << endl <<
1496  indent() << "while (1)" << endl;
1497  scope_up(out);
1498 
1499  // read beginning field marker
1500  out <<
1501  indent() << "/* read the beginning of a field */" << endl <<
1502  indent() << "if ((ret = thrift_protocol_read_field_begin (protocol, &name, &ftype, &fid, error)) < 0)" << endl <<
1503  indent() << "{" << endl <<
1504  indent() << " if (name) os_free (name);" << endl <<
1505  indent() << " return " << error_ret << ";" << endl <<
1506  indent() << "}" << endl <<
1507  indent() << "xfer += ret;" << endl <<
1508  indent() << "if (name) { os_free (name); name = NULL; }" << endl <<
1509  endl;
1510 
1511  // check for field STOP marker
1512  out <<
1513  indent() << "/* break if we get a STOP field */" << endl <<
1514  indent() << "if (ftype == T_STOP)" << endl <<
1515  indent() << "{" << endl <<
1516  indent() << " break;" << endl <<
1517  indent() << "}" << endl <<
1518  endl;
1519 
1520  // switch depending on the field type
1521  indent(out) <<
1522  "switch (fid)" << endl;
1523 
1524  // start switch
1525  scope_up(out);
1526 
1527  // generate deserialization code for known types
1528  for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
1529  // Ignore auto generated fields
1530  if ((*f_iter)->get_auto_generated()) {
1531  continue;
1532  }
1533  indent(out) <<
1534  "case " << (*f_iter)->get_key() << ":" << endl;
1535  indent_up();
1536  indent(out) <<
1537  "if (ftype == " << type_to_enum ((*f_iter)->get_type()) << ")" << endl;
1538  indent(out) <<
1539  "{" << endl;
1540 
1541 
1542  indent_up();
1543  // generate deserialize field
1544  generate_deserialize_field (out, *f_iter, rname + "->", "", error_ret);
1545  indent_down();
1546 
1547  out <<
1548  indent() << "} else {" << endl <<
1549  indent() << " if ((ret = thrift_protocol_skip (protocol, ftype, error)) < 0)" << endl <<
1550  indent() << " return " << error_ret << ";" << endl <<
1551  indent() << " xfer += ret;" << endl <<
1552  indent() << "}" << endl <<
1553  indent() << "break;" << endl;
1554  indent_down();
1555  }
1556 
1557  // create the default case
1558  out <<
1559  indent() << "default:" << endl <<
1560  indent() << " if ((ret = thrift_protocol_skip (protocol, ftype, error)) < 0)" << endl <<
1561  indent() << " return " << error_ret << ";" << endl <<
1562  indent() << " xfer += ret;" << endl <<
1563  indent() << " break;" << endl;
1564 
1565  // end switch
1566  scope_down(out);
1567 
1568  // read field end marker
1569  out <<
1570  indent() << "if ((ret = thrift_protocol_read_field_end (protocol, error)) < 0)" << endl <<
1571  indent() << " return " << error_ret << ";" << endl <<
1572  indent() << "xfer += ret;" << endl;
1573 
1574  // end while loop
1575  scope_down(out);
1576  out << endl;
1577 
1578  // read the end of the structure
1579  out <<
1580  indent() << "if ((ret = thrift_protocol_read_" << sname << "_end (protocol, error)) < 0)" << endl <<
1581  indent() << " return " << error_ret << ";" << endl <<
1582  indent() << "xfer += ret;" << endl <<
1583  endl;
1584 
1585  // if a required field is missing, throw an error
1586  for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
1587  // Ignore auto generated fields
1588  if ((*f_iter)->get_auto_generated()) {
1589  continue;
1590  }
1591  if ((*f_iter)->get_req() == t_field::T_REQUIRED) {
1592  out <<
1593  indent() << "if (!isset_" << (*f_iter)->get_name() << ")" << endl <<
1594  indent() << "{" << endl <<
1595  indent() << " *error = THRIFT_PROTOCOL_ERROR_INVALID_DATA;" << endl <<
1596  indent() << " syslog(LOG_ERROR, \"THRIFT_PROTOCOL_ERROR: missing field\");" << endl <<
1597  indent() << " return -1;" << endl <<
1598  indent() << "}" << endl <<
1599  endl;
1600  }
1601  }
1602 
1603  if (is_function) {
1604  indent(out) <<
1605  "return xfer;" << endl;
1606  }
1607 
1608  // end the function/structure
1609  indent_down();
1610  indent(out) <<
1611  "}" << endl <<
1612  endl;
1613 }
1614 
1619  string name,
1620  const vector <t_field *> &fields,
1621  bool is_sandesh,
1622  bool is_function) {
1623  string name_u = initial_caps_to_underscores(name);
1624  string rname = "r" + name_u;
1625  int error_ret = 0;
1626  vector <t_field *>::const_iterator f_iter;
1627  string sname = is_sandesh ? "sandesh" : "struct";
1628  string dname = is_sandesh ? "void" : name;
1629  string drname = is_sandesh ? "rsandesh" : rname;
1630 
1631  if (is_function) {
1632  error_ret = -1;
1633  indent(out) <<
1634  "/* reads a " << name_u << " " << sname << " */" << endl <<
1635  "int32_t" << endl <<
1636  this->nspace_lc << name_u <<
1637  "_read_binary_from_buffer (" << dname <<
1638  " *" << drname << ", uint8_t *Xbuf, const size_t Xbuflen, int *Xerror)" << endl;
1639  }
1640 
1641  indent(out) << "{" << endl;
1642  indent_up();
1643 
1644  // declare stack temp variables
1645  out <<
1646  indent() << "int32_t Xret;" << endl <<
1647  indent() << "int32_t Xoffset = 0;" << endl <<
1648  indent() << "char *Xname;" << endl <<
1649  indent() << "ThriftType Xftype;" << endl <<
1650  indent() << "int16_t Xfid;" << endl <<
1651  indent() << "u_int32_t Xi;" << endl;
1652 
1653  if (is_sandesh) {
1654  out << indent() << name << "* " << rname << " = " <<
1655  "(" << name << "* ) " << drname << ";" << endl;
1656  }
1657 
1658  for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
1659  // Ignore auto generated fields
1660  if ((*f_iter)->get_auto_generated()) {
1661  continue;
1662  }
1663  if ((*f_iter)->get_req() == t_field::T_REQUIRED) {
1664  indent(out) << "u_int8_t isset_" << (*f_iter)->get_name() << " = 0;" << endl;
1665  }
1666  }
1667 
1668  // satisfy -Wall in case we don't use some variables
1669  out <<
1670  indent() << "/* satisfy -Wall in case these aren't used */" << endl <<
1671  indent() << "THRIFT_UNUSED_VAR (Xret);" << endl <<
1672  indent() << "THRIFT_UNUSED_VAR (Xname);" << endl <<
1673  indent() << "THRIFT_UNUSED_VAR (Xi);" << endl <<
1674  indent() << "THRIFT_UNUSED_VAR (" << rname << ");" << endl;
1675 
1676  out << endl;
1677 
1678  // read the beginning of the structure marker
1679  out <<
1680  indent() << "/* read the " << sname << " begin marker */" << endl;
1681  generate_struct_begin_reader_from_buffer (out, "Xname", is_sandesh, error_ret);
1682 
1683  // read the struct fields
1684  out <<
1685  indent() << "/* read the struct fields */" << endl <<
1686  indent() << "while (1)" << endl;
1687  scope_up(out);
1688 
1689  // read beginning field marker
1690  out <<
1691  indent() << "/* read the beginning of a field */" << endl;
1692  generate_field_begin_reader_from_buffer (out, "Xftype", "Xfid", error_ret);
1693  out << endl;
1694 
1695  // switch depending on the field type
1696  indent(out) <<
1697  "switch (Xfid)" << endl;
1698 
1699  // start switch
1700  scope_up(out);
1701 
1702  // generate deserialization code for known types
1703  for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
1704  // Ignore auto generated fields
1705  if ((*f_iter)->get_auto_generated()) {
1706  continue;
1707  }
1708  indent(out) <<
1709  "case " << (*f_iter)->get_key() << ":" << endl;
1710  indent_up();
1711  indent(out) <<
1712  "if (Xftype == " << type_to_enum ((*f_iter)->get_type()) << ")" << endl;
1713  indent(out) <<
1714  "{" << endl;
1715 
1716 
1717  indent_up();
1718  // generate deserialize field
1719  generate_deserialize_field_from_buffer (out, *f_iter, rname + "->", "", error_ret);
1720  indent_down();
1721 
1722  out <<
1723  indent() << "} else {" << endl <<
1724  indent() << " if ((Xret = thrift_binary_protocol_skip_from_buffer (Xbuf + Xoffset, Xbuflen - Xoffset, Xftype, Xerror)) < 0)" << endl <<
1725  indent() << " return " << error_ret << ";" << endl <<
1726  indent() << " Xoffset += Xret;" << endl <<
1727  indent() << "}" << endl <<
1728  indent() << "break;" << endl;
1729  indent_down();
1730  }
1731 
1732  // create the default case
1733  out <<
1734  indent() << "default:" << endl <<
1735  indent() << " if ((Xret = thrift_binary_protocol_skip_from_buffer (Xbuf + Xoffset, Xbuflen - Xoffset, Xftype, Xerror)) < 0)" << endl <<
1736  indent() << " return " << error_ret << ";" << endl <<
1737  indent() << " Xoffset += Xret;" << endl <<
1738  indent() << " break;" << endl;
1739 
1740  // end switch
1741  scope_down(out);
1742 
1743  // read field end marker
1744  generate_field_end_reader_from_buffer (out);
1745 
1746  // end while loop
1747  scope_down(out);
1748  out << endl;
1749 
1750  // read the end of the structure
1751  generate_struct_end_reader_from_buffer (out, is_sandesh);
1752 
1753  // if a required field is missing, throw an error
1754  for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
1755  // Ignore auto generated fields
1756  if ((*f_iter)->get_auto_generated()) {
1757  continue;
1758  }
1759  if ((*f_iter)->get_req() == t_field::T_REQUIRED) {
1760  out <<
1761  indent() << "if (!isset_" << (*f_iter)->get_name() << ")" << endl <<
1762  indent() << "{" << endl <<
1763  indent() << " *error = THRIFT_PROTOCOL_ERROR_INVALID_DATA;" << endl <<
1764  indent() << " syslog(LOG_ERROR, \"THRIFT_PROTOCOL_ERROR: missing field\");" << endl <<
1765  indent() << " return -1;" << endl <<
1766  indent() << "}" << endl <<
1767  endl;
1768  }
1769  }
1770 
1771  if (is_function) {
1772  indent(out) <<
1773  "return Xoffset;" << endl;
1774  }
1775 
1776  // end the function/structure
1777  indent_down();
1778  indent(out) <<
1779  "}" << endl <<
1780  endl;
1781 }
1782 
1784  string key,
1785  string field_type,
1786  int error_ret) {
1787  out <<
1788  indent() << "/* thrift_protocol_write_field_begin */" << endl;
1789  generate_buffer_bounds_chk (out, "1", error_ret);
1790  string field_type8(tmp("Xfield_type8"));
1791  scope_up(out);
1792  out <<
1793  indent() << "int8_t " << field_type8 << " = (int8_t) " <<
1794  field_type << ";" << endl;
1795  generate_write_buffer_memcpy_incr_offset (out, field_type8,
1796  "1", true);
1797  scope_down(out);
1798  generate_buffer_bounds_chk (out, "2", error_ret);
1799  string nkey(tmp("Xnfield_id"));
1800  scope_up(out);
1801  out <<
1802  indent() << "int16_t " << nkey << " = htons (" << key << ");" << endl;
1803  generate_write_buffer_memcpy_incr_offset (out, nkey, "2", true);
1804  scope_down(out);
1805  out << endl;
1806 }
1807 
1809  string field_type,
1810  string field_id,
1811  int error_ret) {
1812  out <<
1813  indent() << "/* thrift_protocol_read_field_begin */" << endl;
1814  generate_deserialize_byte_from_buffer (out, field_type, error_ret);
1815  // check for field STOP marker
1816  out <<
1817  indent() << "/* break if we get a STOP field */" << endl <<
1818  indent() << "if (" << field_type << " == T_STOP)" << endl <<
1819  indent() << "{" << endl <<
1820  indent() << " break;" << endl <<
1821  indent() << "}" << endl;
1822  out <<
1823  indent() << " else" << endl;
1824  scope_up(out);
1825  generate_deserialize_i16_from_buffer (out, field_id, error_ret);
1826  scope_down(out);
1827 }
1828 
1830  out <<
1831  indent() << "/* thrift_protocol_write_field_end */" << endl;
1832 }
1833 
1835  out <<
1836  indent() << "/* thrift_protocol_read_field_end */" << endl;
1837 }
1838 
1840  string name,
1841  int error_ret) {
1842  string nbool(tmp("Xbool"));
1843  out <<
1844  indent() << "/* thrift_protocol_write_bool */" << endl;
1845  scope_up(out);
1846  out <<
1847  indent() << "uint8_t " << nbool << " = " << name << " ? 1 : 0;" << endl;
1848  generate_serialize_byte_to_buffer (out, nbool, error_ret);
1849  scope_down(out);
1850 }
1851 
1853  string name,
1854  int error_ret) {
1855  out <<
1856  indent() << "/* thrift_protocol_read_bool */" << endl;
1857  scope_up(out);
1858  out << indent() << "void * b[1];" << endl;
1859  generate_read_buffer_chk_memcpy_incr_offset (out, "b", "1", error_ret,
1860  false);
1861  out <<
1862  indent() << name << " = *(int8_t *) b != 0;" << endl;
1863  scope_down(out);
1864 }
1865 
1867  string name,
1868  int error_ret) {
1869  out <<
1870  indent() << "/* thrift_protocol_write_byte */" << endl;
1871  generate_write_buffer_chk_memcpy_incr_offset (out, name, "1", error_ret,
1872  true);
1873 }
1874 
1876  string name,
1877  int error_ret) {
1878  out <<
1879  indent() << "/* thrift_protocol_read_byte */" << endl;
1880  scope_up(out);
1881  out << indent() << "void * b[1];" << endl;
1882  generate_read_buffer_chk_memcpy_incr_offset (out, "b", "1", error_ret,
1883  false);
1884  out <<
1885  indent() << name << " = *(int8_t *) b;" << endl;
1886  scope_down(out);;
1887 }
1888 
1890  string name,
1891  int error_ret) {
1892  string ni16(tmp("Xni16"));
1893  out << indent() << "/* thrift_protocol_write_i16 */" << endl;
1894  scope_up(out);
1895  out <<
1896  indent() << "int16_t " << ni16 << " = htons (" << name << ");" << endl;
1897  generate_write_buffer_chk_memcpy_incr_offset (out, ni16, "2", error_ret,
1898  true);
1899  scope_down(out);
1900 }
1901 
1903  string name,
1904  int error_ret) {
1905  out << indent() << "/* thrift_protocol_read_i16 */" << endl;
1906  scope_up(out);
1907  out <<
1908  indent() << "union {"<< endl <<
1909  indent() << " void * b[2];" << endl <<
1910  indent() << " int16_t all;" << endl <<
1911  indent() << "} bytes;" << endl;
1912  generate_read_buffer_chk_memcpy_incr_offset (out, "bytes.b", "2", error_ret,
1913  false);
1914  out <<
1915  indent() << name << " = ntohs (bytes.all);" << endl;
1916  scope_down(out);
1917 }
1918 
1920  string name,
1921  int error_ret) {
1922  string nu16(tmp("Xnu16"));
1923  out << indent() << "/* thrift_protocol_write_u16 */" << endl;
1924  scope_up(out);
1925  out <<
1926  indent() << "uint16_t " << nu16 << " = htons (" << name << ");" << endl;
1927  generate_write_buffer_chk_memcpy_incr_offset (out, nu16, "2", error_ret,
1928  true);
1929  scope_down(out);
1930 }
1931 
1933  string name,
1934  int error_ret) {
1935  out << indent() << "/* thrift_protocol_read_u16 */" << endl;
1936  scope_up(out);
1937  out <<
1938  indent() << "union {"<< endl <<
1939  indent() << " void * b[2];" << endl <<
1940  indent() << " uint16_t all;" << endl <<
1941  indent() << "} bytes;" << endl;
1942  generate_read_buffer_chk_memcpy_incr_offset (out, "bytes.b", "2", error_ret,
1943  false);
1944  out <<
1945  indent() << name << " = ntohs (bytes.all);" << endl;
1946  scope_down(out);
1947 }
1948 
1950  string name,
1951  int error_ret) {
1952  string ni32(tmp("Xni32"));
1953  out << indent() << "/* thrift_protocol_write_i32 */" << endl;
1954  scope_up(out);
1955  out <<
1956  indent() << "int32_t " << ni32 << " = htonl (" << name << ");" << endl;
1957  generate_write_buffer_chk_memcpy_incr_offset (out, ni32, "4", error_ret,
1958  true);
1959  scope_down(out);
1960 }
1961 
1963  string name,
1964  int error_ret) {
1965  out << indent() << "/* thrift_protocol_read_i32 */" << endl;
1966  scope_up(out);
1967  out <<
1968  indent() << "union {"<< endl <<
1969  indent() << " void * b[4];" << endl <<
1970  indent() << " int32_t all;" << endl <<
1971  indent() << "} bytes;" << endl;
1972  generate_read_buffer_chk_memcpy_incr_offset (out, "bytes.b", "4", error_ret,
1973  false);
1974  out <<
1975  indent() << name << " = ntohl (bytes.all);" << endl;
1976  scope_down(out);
1977 }
1978 
1980  string name,
1981  int error_ret) {
1982  string nu32(tmp("Xnu32"));
1983  out << indent() << "/* thrift_protocol_write_u32 */" << endl;
1984  scope_up(out);
1985  out <<
1986  indent() << "uint32_t " << nu32 << " = htonl (" << name << ");" << endl;
1987  generate_write_buffer_chk_memcpy_incr_offset (out, nu32, "4", error_ret,
1988  true);
1989  scope_down(out);
1990 }
1991 
1993  string name,
1994  int error_ret) {
1995  out << indent() << "/* thrift_protocol_read_u32 */" << endl;
1996  scope_up(out);
1997  out <<
1998  indent() << "union {"<< endl <<
1999  indent() << " void * b[4];" << endl <<
2000  indent() << " uint32_t all;" << endl <<
2001  indent() << "} bytes;" << endl;
2002  generate_read_buffer_chk_memcpy_incr_offset (out, "bytes.b", "4", error_ret,
2003  false);
2004  out <<
2005  indent() << name << " = ntohl (bytes.all);" << endl;
2006  scope_down(out);
2007 }
2008 
2010  string name,
2011  int error_ret) {
2012  string ni64(tmp("Xni64"));
2013  out << indent() << "/* thrift_protocol_write_i64 */" << endl;
2014  scope_up(out);
2015  out <<
2016  indent() << "int64_t " << ni64 << ";" << endl <<
2017  indent() << "os_put_value64((uint8_t *)&" << ni64 << ", " << name <<
2018  ");" << endl;
2019  generate_write_buffer_chk_memcpy_incr_offset (out, ni64, "8", error_ret,
2020  true);
2021  scope_down(out);
2022 }
2023 
2025  string name,
2026  int error_ret) {
2027  out << indent() << "/* thrift_protocol_read_i64 */" << endl;
2028  scope_up(out);
2029  out <<
2030  indent() << "void * b[8];" << endl;
2031  generate_read_buffer_chk_memcpy_incr_offset (out, "b", "8", error_ret,
2032  false);
2033  out <<
2034  indent() << name << " = os_get_value64((uint8_t *)b);" << endl;
2035  scope_down(out);
2036 }
2037 
2039  string name,
2040  int error_ret) {
2041  string nu64(tmp("Xnu64"));
2042  out << indent() << "/* thrift_protocol_write_u64 */" << endl;
2043  scope_up(out);
2044  out <<
2045  indent() << "uint64_t " << nu64 << ";" << endl <<
2046  indent() << "os_put_value64((uint8_t *)&" << nu64 << ", " << name <<
2047  ");" << endl;
2048  generate_write_buffer_chk_memcpy_incr_offset (out, nu64, "8", error_ret,
2049  true);
2050  scope_down(out);
2051 }
2052 
2054  string name,
2055  int error_ret) {
2056  out << indent() << "/* thrift_protocol_read_u64 */" << endl;
2057  scope_up(out);
2058  out <<
2059  indent() << "void * b[8];" << endl;
2060  generate_read_buffer_chk_memcpy_incr_offset (out, "b", "8", error_ret,
2061  false);
2062  out <<
2063  indent() << name << " = os_get_value64((uint8_t *)b);" << endl;
2064  scope_down(out);
2065 }
2066 
2068  string name,
2069  int error_ret) {
2070  generate_serialize_string_to_buffer(out, name, error_ret);
2071 }
2072 
2074  string name,
2075  int error_ret) {
2076  generate_deserialize_string_from_buffer(out, name, error_ret);
2077 }
2078 
2080  string name,
2081  int error_ret) {
2082  string s_strlen(tmp("Xsstrlen"));
2083  out << indent() << "/* thrift_protocol_write_string */" << endl;
2084  scope_up(out);
2085  out <<
2086  indent() << "int32_t " << s_strlen << " = " << name <<
2087  " != NULL ? strlen (" << name << ") : 0;" << endl;
2088  generate_write_buffer_binary (out, name, s_strlen, error_ret);
2089  scope_down(out);
2090 }
2091 
2093  string name,
2094  int error_ret) {
2095  string s_strlen(tmp("Xread_len"));
2096  out << indent() << "/* thrift_protocol_read_string */" << endl;
2097  scope_up(out);
2098  out <<
2099  indent() << "int32_t " << s_strlen << " = 0;" << endl;
2100  generate_deserialize_i32_from_buffer (out, s_strlen, error_ret);
2101  out <<
2102  indent() << "if (" << s_strlen << " > 0)" << endl;
2103  scope_up(out);
2104  out <<
2105  indent() << "if (Xbuflen < Xoffset + " << s_strlen << ") {" << endl <<
2106  indent() << " return " << error_ret << ";" << endl <<
2107  indent() << "}" << endl <<
2108  indent() << name << " = os_malloc (" << s_strlen << " + 1);" << endl;
2109  generate_read_buffer_memcpy_incr_offset (out, name, s_strlen, false);
2110  out <<
2111  indent() << name << "[" << s_strlen << "] = 0;" << endl;
2112  scope_down(out);
2113  out <<
2114  indent() << " else" << endl;
2115  scope_up(out);
2116  out <<
2117  indent() << name << " = NULL;" << endl;
2118  scope_down(out);
2119  scope_down(out);
2120 }
2121 
2123  string name,
2124  int error_ret) {
2125  out <<
2126  indent() << "/* thrift_protocol_write_ipaddr */" << endl;
2127  string iptype(name + ".iptype");
2128  out <<
2129  indent() << "if (" << iptype << " == AF_INET)" << endl;
2130  scope_up(out);
2131  generate_write_buffer_chk_memcpy_incr_offset (out, iptype, "1", error_ret,
2132  true);
2133  string ipv4(name + ".ipv4");
2134  generate_write_buffer_chk_memcpy_incr_offset (out, ipv4, "4", error_ret,
2135  true);
2136  scope_down(out);
2137  out <<
2138  indent() << " else if (" << iptype << " == AF_INET6)" << endl;
2139  scope_up(out);
2140  generate_write_buffer_chk_memcpy_incr_offset (out, iptype, "1", error_ret,
2141  true);
2142  string ipv6(name + ".ipv6");
2143  generate_write_buffer_chk_memcpy_incr_offset (out, ipv6, "16", error_ret,
2144  true);
2145  scope_down(out);
2146  out <<
2147  indent() << " else" << endl;
2148  scope_up(out);
2149  out <<
2150  indent() << "return -1;" << endl;
2151  scope_down(out);
2152 }
2153 
2155  string name,
2156  int error_ret) {
2157  out <<
2158  indent() << "/* thrift_protocol_read_ipaddr */" << endl;
2159  string iptype(name + ".iptype");
2160  generate_deserialize_byte_from_buffer (out, iptype, error_ret);
2161  out <<
2162  indent() << "if (" << iptype << " == AF_INET)" << endl;
2163  scope_up(out);
2164  string ipv4(name + ".ipv4");
2165  generate_read_buffer_chk_memcpy_incr_offset (out, ipv4, "4", error_ret,
2166  true);
2167  scope_down(out);
2168  out <<
2169  indent() << "else if (" << iptype << " == AF_INET6)" << endl;
2170  scope_up(out);
2171  string ipv6(name + ".ipv6");
2172  generate_read_buffer_chk_memcpy_incr_offset (out, ipv6, "16", error_ret,
2173  true);
2174  scope_down(out);
2175  out <<
2176  indent() << " else" << endl;
2177  scope_up(out);
2178  out <<
2179  indent() << "return -1;" << endl;
2180  scope_down(out);
2181 }
2182 
2184  string name,
2185  int error_ret) {
2186  out <<
2187  indent() << "/* thrift_protocol_write_uuid_t */" << endl;
2188  generate_write_buffer_chk_memcpy_incr_offset (out, name, "16", error_ret,
2189  true);
2190 }
2191 
2193  string name,
2194  int error_ret) {
2195  out <<
2196  indent() << "/* thrift_protocol_read_uuid_t */" << endl;
2197  generate_read_buffer_chk_memcpy_incr_offset (out, name, "16", error_ret,
2198  true);
2199 }
2200 
2202  string name,
2203  int error_ret) {
2204  out <<
2205  indent() << "/* thrift_protocol_write_double */" << endl <<
2206  indent() << "/* NOT SUPPORTED */" << endl <<
2207  indent() << "return " << error_ret << ";" << endl;
2208 }
2209 
2211  string name,
2212  int error_ret) {
2213  out <<
2214  indent() << "/* thrift_protocol_read_double */" << endl <<
2215  indent() << "/* NOT SUPPORTED */" << endl <<
2216  indent() << "return " << error_ret << ";" << endl;
2217 }
2218 
2220  t_field *tfield,
2221  string prefix,
2222  string suffix,
2223  int error_ret) {
2224  t_type *type = get_true_type (tfield->get_type());
2225  string name = prefix + tfield->get_name() + suffix;
2226 
2227  if (type->is_void()) {
2228  throw "CANNOT GENERATE SERIALIZE CODE FOR void TYPE: " + name;
2229  }
2230 
2231  if (type->is_struct() || type->is_xception()) {
2232  generate_serialize_struct (out, (t_struct *) type, name, error_ret);
2233  } else if (type->is_container()) {
2234  generate_serialize_container (out, type, name, error_ret);
2235  } else if (type->is_base_type() || type->is_enum()) {
2236  indent(out) <<
2237  "if ((ret = thrift_protocol_write_";
2238 
2239  if (type->is_base_type()) {
2240  t_base_type::t_base tbase = ((t_base_type *) type)->get_base();
2241  switch (tbase) {
2243  throw "compiler error: cannot serialize void field in a struct: "
2244  + name;
2245  break;
2247  out << "bool (protocol, " << name;
2248  break;
2250  out << "byte (protocol, " << name;
2251  break;
2252  case t_base_type::TYPE_I16:
2253  out << "i16 (protocol, " << name;
2254  break;
2255  case t_base_type::TYPE_I32:
2256  out << "i32 (protocol, " << name;
2257  break;
2258  case t_base_type::TYPE_I64:
2259  out << "i64 (protocol, " << name;
2260  break;
2261  case t_base_type::TYPE_U16:
2262  out << "u16 (protocol, " << name;
2263  break;
2264  case t_base_type::TYPE_U32:
2265  out << "u32 (protocol, " << name;
2266  break;
2267  case t_base_type::TYPE_U64:
2268  out << "u64 (protocol, " << name;
2269  break;
2271  out << "double (protocol, " << name;
2272  break;
2273  case t_base_type::TYPE_IPV4:
2274  out << "ipv4 (protocol, " << name;
2275  break;
2276  case t_base_type::TYPE_IPADDR:
2277  out << "ipaddr (protocol, &" << name;
2278  break;
2280  if (((t_base_type *) type)->is_binary()) {
2281  throw "CANNOT GENERATE SERIALIZE CODE FOR binary TYPE: " + name;
2282  } else {
2283  out << "string (protocol, " << name;
2284  }
2285  break;
2286  case t_base_type::TYPE_XML:
2287  out << "xml (protocol, " << name;
2288  break;
2289  case t_base_type::TYPE_UUID:
2290  out << "uuid_t (protocol, " << name;
2291  break;
2292  default:
2293  throw "compiler error: no C writer for base type "
2294  + t_base_type::t_base_name (tbase) + name;
2295  }
2296  } else if (type->is_enum()) {
2297  out << "i32 (protocol, " << name;
2298  }
2299  out << ", error)) < 0)" << endl <<
2300  indent() << " return " << error_ret << ";" << endl;
2301  } else {
2302  printf ("DO NOT KNOW HOW TO SERIALIZE FIELD '%s' TYPE '%s'\n",
2303  name.c_str(), type_name (type).c_str());
2304  }
2305 }
2306 
2308  t_field *tfield,
2309  string prefix,
2310  string suffix,
2311  int error_ret) {
2312  t_type *type = get_true_type (tfield->get_type());
2313  string name = prefix + tfield->get_name() + suffix;
2314  ostringstream key_os;
2315  key_os << tfield->get_key();
2316  string key(key_os.str());
2317  string tenum(type_to_enum(tfield->get_type()));
2318 
2319  if (type->is_void()) {
2320  throw "CANNOT GENERATE SERIALIZE CODE FOR void TYPE: " + name;
2321  }
2322 
2323  if (type->is_struct() || type->is_xception()) {
2324  generate_serialize_struct_to_buffer (out, (t_struct *) type, name, error_ret);
2325  } else if (type->is_container()) {
2326  generate_serialize_container_to_buffer (out, type, name, error_ret);
2327  } else if (type->is_base_type() || type->is_enum()) {
2328  if (type->is_base_type()) {
2329  t_base_type::t_base tbase = ((t_base_type *) type)->get_base();
2330  switch (tbase) {
2332  throw "compiler error: cannot serialize void field in a struct: "
2333  + name;
2334  break;
2336  generate_serialize_bool_to_buffer (out, name, error_ret);
2337  break;
2339  generate_serialize_byte_to_buffer (out, name, error_ret);
2340  break;
2341  case t_base_type::TYPE_I16:
2342  generate_serialize_i16_to_buffer (out, name, error_ret);
2343  break;
2344  case t_base_type::TYPE_I32:
2345  generate_serialize_i32_to_buffer (out, name, error_ret);
2346  break;
2347  case t_base_type::TYPE_I64:
2348  generate_serialize_i64_to_buffer (out, name, error_ret);
2349  break;
2350  case t_base_type::TYPE_U16:
2351  generate_serialize_u16_to_buffer (out, name, error_ret);
2352  break;
2353  case t_base_type::TYPE_U32:
2354  generate_serialize_u32_to_buffer (out, name, error_ret);
2355  break;
2356  case t_base_type::TYPE_U64:
2357  generate_serialize_u64_to_buffer (out, name, error_ret);
2358  break;
2360  generate_serialize_double_to_buffer (out, name, error_ret);
2361  break;
2362  case t_base_type::TYPE_IPV4:
2363  generate_serialize_i32_to_buffer (out, name, error_ret);
2364  break;
2365  case t_base_type::TYPE_IPADDR:
2366  generate_serialize_ipaddr_to_buffer (out, name, error_ret);
2367  break;
2369  if (((t_base_type *) type)->is_binary()) {
2370  throw "CANNOT GENERATE SERIALIZE CODE FOR binary TYPE: " + name;
2371  } else {
2372  generate_serialize_string_to_buffer (out, name, error_ret);
2373  }
2374  break;
2375  case t_base_type::TYPE_XML:
2376  generate_serialize_xml_to_buffer (out, name, error_ret);
2377  break;
2378  case t_base_type::TYPE_UUID:
2379  generate_serialize_uuid_t_to_buffer (out, name, error_ret);
2380  break;
2381  default:
2382  throw "compiler error: no C writer for base type "
2383  + t_base_type::t_base_name (tbase) + name;
2384  }
2385  } else if (type->is_enum()) {
2386  generate_serialize_i32_to_buffer (out, name, error_ret);
2387  }
2388  } else {
2389  printf ("DO NOT KNOW HOW TO SERIALIZE FIELD '%s' TYPE '%s'\n",
2390  name.c_str(), type_name (type).c_str());
2391  }
2392 }
2393 
2395  t_struct *tstruct,
2396  string prefix,
2397  int error_ret) {
2398  out <<
2399  indent() << "if ((ret = " << tstruct->get_name() << "_write (" << prefix << " , protocol, error)) < 0)" << endl <<
2400  indent() << " return " << error_ret << ";" << endl <<
2401  endl;
2402 }
2403 
2405  t_struct *tstruct,
2406  string prefix,
2407  int error_ret) {
2408  out <<
2409  indent() << "if ((Xret = " << tstruct->get_name() <<
2410  "_write_binary_to_buffer (" << prefix <<
2411  ", Xbuf + Xoffset, Xbuflen - Xoffset, Xerror)) < 0)" << endl;
2412  out <<
2413  indent() << " return " << error_ret << ";" << endl <<
2414  indent() << "Xoffset += Xret;" << endl;
2415 }
2416 
2417 
2419  t_type *ttype,
2420  string prefix,
2421  int error_ret) {
2422  scope_up(out);
2423 
2424  if (ttype->is_map()) {
2425  throw "compiler error: serialize of map not supported in C";
2426  } else if (ttype->is_set()) {
2427  throw "compiler error: serialize of set not supported in C";
2428  } else if (ttype->is_list()) {
2429  string length = prefix + "_size";
2430  out <<
2431  indent() << "if ((ret = thrift_protocol_write_list_begin (protocol, " <<
2432  type_to_enum (((t_list *) ttype)->get_elem_type()) <<
2433  ", " << length << ", error)) < 0)" << endl <<
2434  indent() << " return " << error_ret << ";" << endl <<
2435  indent() << "xfer += ret;" << endl <<
2436  indent() << "for (i = 0; i < " << length << "; i++)" << endl;
2437 
2438  scope_up(out);
2439  generate_serialize_list_element (out, (t_list *) ttype, prefix, "i", error_ret);
2440  scope_down(out);
2441 
2442  out <<
2443  indent() << "if ((ret = thrift_protocol_write_list_end (protocol, error)) < 0)" << endl <<
2444  indent() << " return " << error_ret << ";" << endl;
2445  }
2446 
2447  scope_down(out);
2448 }
2449 
2451  t_type *ttype,
2452  string prefix,
2453  int error_ret) {
2454  scope_up(out);
2455 
2456  if (ttype->is_map()) {
2457  throw "compiler error: serialize of map not supported in C";
2458  } else if (ttype->is_set()) {
2459  throw "compiler error: serialize of set not supported in C";
2460  } else if (ttype->is_list()) {
2461  string length = prefix + "_size";
2462  generate_list_begin_writer_to_buffer (out,
2463  type_to_enum (((t_list *) ttype)->get_elem_type()), length,
2464  error_ret);
2465  out <<
2466  indent() << "for (Xi = 0; Xi < " << length << "; Xi++)" << endl;
2467  scope_up(out);
2468  generate_serialize_list_element_to_buffer (out, (t_list *) ttype, prefix, "Xi", error_ret);
2469  scope_down(out);
2470  generate_list_end_writer_to_buffer (out);
2471  out << endl;
2472  }
2473  scope_down(out);
2474 }
2475 
2477  string element_type,
2478  string length,
2479  int error_ret) {
2480  string element_type8(tmp("Xelement_type8"));
2481  out <<
2482  indent() << "/* thrift_protocol_write_list_begin */" << endl;
2483  generate_buffer_bounds_chk (out, "1", error_ret);
2484  scope_up(out);
2485  out <<
2486  indent() << "int8_t " << element_type8 << " = (int8_t) " <<
2487  element_type << ";" << endl;
2488  generate_write_buffer_memcpy_incr_offset (out, element_type8, "1",
2489  true);
2490  scope_down(out);
2491  string nelement_size(tmp("Xnelement_size"));
2492  generate_buffer_bounds_chk (out, "4", error_ret);
2493  scope_up(out);
2494  out <<
2495  indent() << "uint32_t " << nelement_size << " = htonl (" <<
2496  length << ");" << endl;
2497  generate_write_buffer_memcpy_incr_offset (out, nelement_size, "4",
2498  true);
2499  scope_down(out);
2500  out << endl;
2501 }
2502 
2504  out <<
2505  indent() << "/* thrift_protocol_write_list_end */" << endl;
2506 }
2507 
2508 
2510  t_list *tlist,
2511  string list,
2512  string index,
2513  int error_ret) {
2514  t_type *ttype = tlist->get_elem_type();
2515  string name = list + "[" + index + "]";
2516  t_field efield (ttype, name);
2517  generate_serialize_field (out, &efield, "", "", error_ret);
2518  out << indent() << "xfer += ret;" << endl;
2519 }
2520 
2522  t_list *tlist,
2523  string list,
2524  string index,
2525  int error_ret) {
2526  t_type *ttype = tlist->get_elem_type();
2527  string name = list + "[" + index + "]";
2528  t_field efield (ttype, name);
2529  generate_serialize_field_to_buffer (out, &efield, "", "", error_ret);
2530  out << endl;
2531 }
2532 
2533 /* deserializes a field of any type. */
2535  t_field *tfield,
2536  string prefix,
2537  string suffix,
2538  int error_ret) {
2539  t_type *type = get_true_type (tfield->get_type());
2540 
2541  if (type->is_void()) {
2542  throw "CANNOT GENERATE DESERIALIZE CODE FOR void TYPE: " +
2543  prefix + tfield->get_name();
2544  }
2545 
2546  string name = prefix + tfield->get_name() + suffix;
2547 
2548  if (type->is_struct() || type->is_xception()) {
2549  generate_deserialize_struct (out, (t_struct *) type, name, error_ret);
2550  } else if (type->is_container()) {
2551  generate_deserialize_container (out, type, name, error_ret);
2552  } else if (type->is_base_type()) {
2553  t_base_type::t_base tbase = ((t_base_type *) type)->get_base();
2554 
2555  indent(out) << "if ((ret = thrift_protocol_read_";
2556 
2557  switch (tbase) {
2559  throw "compiler error: cannot serialize void field in a struct: " + name;
2560  break;
2562  if (((t_base_type *) type)->is_binary()) {
2563  out << "binary (protocol, &data, &len";
2564  } else {
2565  out << "string (protocol, &" << name;
2566  }
2567  break;
2568  case t_base_type::TYPE_XML:
2569  out << "xml (protocol, &" << name;
2570  break;
2572  out << "bool (protocol, &" << name;
2573  break;
2575  out << "byte (protocol, &" << name;
2576  break;
2577  case t_base_type::TYPE_I16:
2578  out << "i16 (protocol, &" << name;
2579  break;
2580  case t_base_type::TYPE_I32:
2581  out << "i32 (protocol, &" << name;
2582  break;
2583  case t_base_type::TYPE_I64:
2584  out << "i64 (protocol, &" << name;
2585  break;
2586  case t_base_type::TYPE_U16:
2587  out << "u16 (protocol, &" << name;
2588  break;
2589  case t_base_type::TYPE_U32:
2590  out << "u32 (protocol, &" << name;
2591  break;
2592  case t_base_type::TYPE_U64:
2593  out << "u64 (protocol, &" << name;
2594  break;
2596  out << "double (protocol, &" << name;
2597  break;
2598  case t_base_type::TYPE_IPV4:
2599  out << "ipv4 (protocol, &" << name;
2600  break;
2601  case t_base_type::TYPE_IPADDR:
2602  out << "ipaddr (protocol, &" << name;
2603  break;
2604  case t_base_type::TYPE_UUID:
2605  out << "uuid_t (protocol, &" << name;
2606  break;
2607  default:
2608  throw "compiler error: no C reader for base type "
2609  + t_base_type::t_base_name (tbase) + name;
2610  }
2611  out << ", error)) < 0)" << endl;
2612  out << indent() << " return " << error_ret << ";" << endl <<
2613  indent() << "xfer += ret;" << endl;
2614 
2615  } else if (type->is_enum()) {
2616  string t = tmp ("ecast");
2617  out <<
2618  indent() << "int32_t " << t << ";" << endl <<
2619  indent() << "if ((ret = thrift_protocol_read_i32 (protocol, &" << t << ", error)) < 0)" << endl <<
2620  indent() << " return " << error_ret << ";" << endl <<
2621  indent() << "xfer += ret;" << endl <<
2622  indent() << name << " = (" << type_name (type) << ")" << t << ";" << endl;
2623  } else {
2624  printf ("DO NOT KNOW HOW TO DESERIALIZE FIELD '%s' TYPE '%s'\n",
2625  tfield->get_name().c_str(), type_name (type).c_str());
2626  }
2627 
2628  // if the type is not required and this is a thrift struct (no prefix),
2629  // set the isset variable. if the type is required, then set the
2630  // local variable indicating the value was set, so that we can do // validation later.
2631  if (tfield->get_req() != t_field::T_REQUIRED && prefix != "") {
2632  indent(out) << prefix << "__isset_" << tfield->get_name() << suffix << " = 1;" << endl;
2633  } else if (tfield->get_req() == t_field::T_REQUIRED && prefix != "") {
2634  indent(out) << "isset_" << tfield->get_name() << " = 1;" << endl;
2635  }
2636 }
2637 
2638 /* deserializes a field of any type. */
2640  t_field *tfield,
2641  string prefix,
2642  string suffix,
2643  int error_ret) {
2644  t_type *type = get_true_type (tfield->get_type());
2645 
2646  if (type->is_void()) {
2647  throw "CANNOT GENERATE DESERIALIZE CODE FOR void TYPE: " +
2648  prefix + tfield->get_name();
2649  }
2650 
2651  string name = prefix + tfield->get_name() + suffix;
2652 
2653  if (type->is_struct() || type->is_xception()) {
2654  generate_deserialize_struct_from_buffer (out, (t_struct *) type, name, error_ret);
2655  } else if (type->is_container()) {
2656  generate_deserialize_container_from_buffer (out, type, name, error_ret);
2657  } else if (type->is_base_type()) {
2658  t_base_type::t_base tbase = ((t_base_type *) type)->get_base();
2659 
2660  switch (tbase) {
2662  throw "compiler error: cannot serialize void field in a struct: " + name;
2663  break;
2665  if (((t_base_type *) type)->is_binary()) {
2666  throw "CANNOT GENERATE DESERIALIZE CODE FOR binary TYPE: " + name;
2667  } else {
2668  generate_deserialize_string_from_buffer (out, name, error_ret);
2669  }
2670  break;
2671  case t_base_type::TYPE_XML:
2672  generate_deserialize_xml_from_buffer (out, name, error_ret);
2673  break;
2675  generate_deserialize_bool_from_buffer (out, name, error_ret);
2676  break;
2678  generate_deserialize_byte_from_buffer (out, name, error_ret);
2679  break;
2680  case t_base_type::TYPE_I16:
2681  generate_deserialize_i16_from_buffer (out, name, error_ret);
2682  break;
2683  case t_base_type::TYPE_I32:
2684  generate_deserialize_i32_from_buffer (out, name, error_ret);
2685  break;
2686  case t_base_type::TYPE_I64:
2687  generate_deserialize_i64_from_buffer (out, name, error_ret);
2688  break;
2689  case t_base_type::TYPE_U16:
2690  generate_deserialize_u16_from_buffer (out, name, error_ret);
2691  break;
2692  case t_base_type::TYPE_U32:
2693  generate_deserialize_u32_from_buffer (out, name, error_ret);
2694  break;
2695  case t_base_type::TYPE_U64:
2696  generate_deserialize_u64_from_buffer (out, name, error_ret);
2697  break;
2699  generate_deserialize_double_from_buffer (out, name, error_ret);
2700  break;
2701  case t_base_type::TYPE_IPV4:
2702  generate_deserialize_i32_from_buffer (out, name, error_ret);
2703  break;
2704  case t_base_type::TYPE_IPADDR:
2705  generate_deserialize_ipaddr_from_buffer (out, name, error_ret);
2706  break;
2707  case t_base_type::TYPE_UUID:
2708  generate_deserialize_uuid_t_from_buffer (out, name, error_ret);
2709  break;
2710  default:
2711  throw "compiler error: no C reader for base type "
2712  + t_base_type::t_base_name (tbase) + name;
2713  }
2714  } else if (type->is_enum()) {
2715  generate_deserialize_i32_from_buffer (out, name, error_ret);
2716  } else {
2717  printf ("DO NOT KNOW HOW TO DESERIALIZE FIELD '%s' TYPE '%s'\n",
2718  tfield->get_name().c_str(), type_name (type).c_str());
2719  }
2720 
2721  // if the type is not required and this is a thrift struct (no prefix),
2722  // set the isset variable. if the type is required, then set the
2723  // local variable indicating the value was set, so that we can do // validation later.
2724  if (tfield->get_req() != t_field::T_REQUIRED && prefix != "") {
2725  indent(out) << prefix << "__isset_" << tfield->get_name() << suffix << " = 1;" << endl;
2726  } else if (tfield->get_req() == t_field::T_REQUIRED && prefix != "") {
2727  indent(out) << "isset_" << tfield->get_name() << " = 1;" << endl;
2728  }
2729 }
2730 
2732  t_struct *tstruct,
2733  string prefix,
2734  int error_ret) {
2735  out <<
2736  indent() << prefix << " = (" << tstruct->get_name() << "* ) os_zalloc (sizeof(*" << prefix << "));" << endl <<
2737  indent() << "if ((ret = " << tstruct->get_name() << "_read (" << prefix << ", protocol, error)) < 0)" << endl <<
2738  indent() << " return " << error_ret << ";" << endl <<
2739  indent() << "xfer += ret;" << endl;
2740 }
2741 
2743  t_struct *tstruct,
2744  string prefix,
2745  int error_ret) {
2746  out <<
2747  indent() << prefix << " = (" << tstruct->get_name() << "* ) os_zalloc (sizeof(*" << prefix << "));" << endl <<
2748  indent() << "if ((Xret = " << tstruct->get_name() << "_read_binary_from_buffer (" << prefix <<
2749  ", Xbuf + Xoffset, Xbuflen - Xoffset, Xerror)) < 0)" << endl <<
2750  indent() << " return " << error_ret << ";" << endl <<
2751  indent() << "Xoffset += Xret;" << endl;
2752 }
2753 
2755  string prefix, int error_ret) {
2756  scope_up(out);
2757 
2758  if (ttype->is_map()) {
2759  throw "compiler error: deserialize of map not supported in C";
2760  } else if (ttype->is_set()) {
2761  throw "compiler error: deserialize of set not supported in C";
2762  } else if (ttype->is_list()) {
2763  out <<
2764  indent() << "ThriftType element_type;" << endl <<
2765  indent() << "if ((ret = thrift_protocol_read_list_begin (protocol, &element_type, &" << prefix << "_size, error)) < 0)" << endl <<
2766  indent() << " return " << error_ret << ";" << endl <<
2767  indent() << "xfer += ret;" << endl <<
2768  endl;
2769 
2770  out <<
2771  indent() << prefix << " = (" << type_name(ttype, false, false) <<
2772  ") os_zalloc (sizeof(*" << prefix << ") * " << prefix << "_size);" << endl;
2773  out <<
2774  indent() << "/* iterate through list elements */" << endl <<
2775  indent() << "for (i = 0; i < " << prefix << "_size; i++)" << endl;
2776 
2777  scope_up(out);
2778  generate_deserialize_list_element (out, (t_list *) ttype, prefix, "i",
2779  error_ret);
2780  scope_down(out);
2781 
2782  out <<
2783  indent() << "if ((ret = thrift_protocol_read_list_end (protocol, error)) < 0)" << endl <<
2784  indent() << " return " << error_ret << ";" << endl <<
2785  indent() << "xfer += ret;" << endl <<
2786  endl;
2787  }
2788 
2789  scope_down(out);
2790 }
2791 
2793  string element_size,
2794  int error_ret) {
2795  string element_type8(tmp("Xelement_type8"));
2796  out <<
2797  indent() << "/* thrift_protocol_read_list_begin */" << endl;
2798  scope_up(out);
2799  out <<
2800  indent() << "int8_t " << element_type8 << ";" << endl;
2801  generate_deserialize_byte_from_buffer (out, element_type8, error_ret);
2802  scope_down(out);
2803  generate_deserialize_i32_from_buffer (out, element_size, error_ret);
2804 }
2805 
2807  out <<
2808  indent() << "/* thrift_protocol_read_list_end */" << endl;
2809 }
2810 
2812  string prefix, int error_ret) {
2813  scope_up(out);
2814 
2815  if (ttype->is_map()) {
2816  throw "compiler error: deserialize of map not supported in C";
2817  } else if (ttype->is_set()) {
2818  throw "compiler error: deserialize of set not supported in C";
2819  } else if (ttype->is_list()) {
2820  string element_size(prefix + "_size");
2821  generate_list_begin_reader_from_buffer (out, element_size, error_ret);
2822  out <<
2823  indent() << prefix << " = (" << type_name(ttype, false, false) <<
2824  ") os_zalloc (sizeof(*" << prefix << ") * " << element_size << ");" << endl;
2825  out <<
2826  indent() << "/* iterate through list elements */" << endl <<
2827  indent() << "for (Xi = 0; Xi < " << element_size << "; Xi++)" << endl;
2828 
2829  scope_up(out);
2830  generate_deserialize_list_element_from_buffer (out, (t_list *) ttype, prefix, "Xi",
2831  error_ret);
2832  scope_down(out);
2833 
2834  generate_list_end_reader_from_buffer (out);
2835  }
2836 
2837  scope_down(out);
2838 }
2839 
2841  t_list *tlist,
2842  string prefix,
2843  string index,
2844  int error_ret) {
2845  string elem = prefix + "[" + index + "]";
2846  t_field felem (tlist->get_elem_type(), elem);
2847  generate_deserialize_field (out, &felem, "", "", error_ret);
2848 }
2849 
2851  t_list *tlist,
2852  string prefix,
2853  string index,
2854  int error_ret) {
2855  string elem = prefix + "[" + index + "]";
2856  t_field felem (tlist->get_elem_type(), elem);
2857  generate_deserialize_field_from_buffer (out, &felem, "", "", error_ret);
2858 }
2859 
2860 /***************************************
2861  * UTILITY FUNCTIONS *
2862  ***************************************/
2863 
2867 string to_upper_case(string name) {
2868  string s (name);
2869  std::transform (s.begin(), s.end(), s.begin(), ::toupper);
2870  return s;
2871 // return boost::to_upper_copy (name);
2872 }
2873 
2877 string to_lower_case(string name) {
2878  string s (name);
2879  std::transform (s.begin(), s.end(), s.begin(), ::tolower);
2880  return s;
2881 // return boost::to_lower_copy (name);
2882 }
2883 
2891 string initial_caps_to_underscores(string name) {
2892  string ret;
2893  const char *tmp = name.c_str();
2894  int pos = 0;
2895 
2896  /* the first character isn't underscored if uppercase, just lowercased */
2897  ret += tolower (tmp[pos]);
2898  pos++;
2899  for (unsigned int i = pos; i < name.length(); i++) {
2900  char lc = tolower (tmp[i]);
2901  if (lc != tmp[i]) {
2902  ret += '_';
2903  }
2904  ret += lc;
2905  }
2906 
2907  return ret;
2908 }
2909 
2910 /* register this generator with the main program */
2911 THRIFT_REGISTER_GENERATOR(c, "C", "")
void generate_field_stop_writer_to_buffer(ofstream &out, int error_ret)
ofstream f_header_
void generate_read_buffer_chk_memcpy_incr_offset(ofstream &out, string dest, string length, int error_ret, bool ref)
virtual bool is_xception() const
Definition: t_type.h:74
const std::string & get_name() const
Definition: t_field.h:95
void generate_deserialize_i16_from_buffer(ofstream &out, string name, int error_ret)
void generate_struct_reader(ofstream &out, string name, const vector< t_field * > &fields, bool is_sandesh, bool is_function=true)
void generate_deserialize_u16_from_buffer(ofstream &out, string name, int error_ret)
void generate_deserialize_xml_from_buffer(ofstream &out, string name, int error_ret)
void init()
Definition: bgp_log.cc:37
t_type * get_type() const
Definition: t_typedef.h:42
string to_lower_case(string name)
void generate_serialize_i32_to_buffer(ofstream &out, string name, int error_ret)
bool has_cpp_name()
Definition: t_container.h:38
Definition: t_enum.h:30
void generate_deserialize_uuid_t_from_buffer(ofstream &out, string name, int error_ret)
void generate_deserialize_u64_from_buffer(ofstream &out, string name, int error_ret)
void generate_serialize_ipaddr_to_buffer(ofstream &out, string name, int error_ret)
void generate_buffer_incr_offset(ofstream &out, string length)
void generate_write_buffer_memcpy_incr_offset(ofstream &out, string source, string length, bool ref)
void generate_serialize_list_element_to_buffer(ofstream &out, t_list *tlist, string list, string index, int error_ret)
void generate_serialize_container_to_buffer(ofstream &out, t_type *ttype, string prefix, int error_ret)
void generate_struct_begin_writer_to_buffer(ofstream &out, string name, bool is_sandesh, int error_ret)
Definition: t_type.h:48
void generate_serialize_uuid_t_to_buffer(ofstream &out, string name, int error_ret)
static std::string t_base_name(t_base tbase)
Definition: t_base_type.h:218
void generate_write_buffer_binary(ofstream &out, string buf, string buf_len, int error_ret)
void generate_serialize_struct(ofstream &out, t_struct *tstruct, string prefix, int error_ret)
void generate_list_begin_writer_to_buffer(ofstream &out, string element_type, string length, int error_ret)
void generate_serialize_double_to_buffer(ofstream &out, string name, int error_ret)
virtual bool is_map() const
Definition: t_type.h:78
void generate_field_end_reader_from_buffer(ofstream &out)
void generate_deserialize_field(ofstream &out, t_field *tfield, string prefix, string suffix, int error_ret)
void generate_serialize_i64_to_buffer(ofstream &out, string name, int error_ret)
void generate_field_end_writer_to_buffer(ofstream &out)
std::string get_cpp_name()
Definition: t_container.h:42
void generate_deserialize_string_from_buffer(ofstream &out, string name, int error_ret)
void generate_list_end_reader_from_buffer(ofstream &out)
void generate_struct_end_reader_from_buffer(ofstream &out, bool is_sandesh)
virtual bool is_enum() const
Definition: t_type.h:72
t_type * get_type() const
Definition: t_field.h:91
virtual bool is_base_type() const
Definition: t_type.h:61
ofstream f_service_
void generate_deserialize_container(ofstream &out, t_type *ttype, string prefix, int error_ret)
void generate_struct(t_struct *tstruct)
void generate_deserialize_bool_from_buffer(ofstream &out, string name, int error_ret)
void generate_write_buffer_chk_memcpy_incr_offset(ofstream &out, string source, string length, int error_ret, bool ref)
void generate_list_begin_reader_from_buffer(ofstream &out, string element_size, int error_ret)
const members_type & get_members()
void generate_serialize_xml_to_buffer(ofstream &out, string name, int error_ret)
void generate_service(t_service *tservice)
string base_type_name(t_base_type *type)
int64_t get_integer() const
Definition: t_const_value.h:72
void generate_serialize_field(ofstream &out, t_field *tfield, string prefix, string suffix, int error_ret)
void generate_struct_begin_reader_from_buffer(ofstream &out, string name, bool is_sandesh, int error_ret)
t_const_value_type get_type() const
virtual bool is_container() const
Definition: t_type.h:75
void generate_consts(vector< t_const * > consts)
#define MKDIR(x)
Definition: platform.h:28
uint8_t type
Definition: load_balance.h:109
void generate_list_end_writer_to_buffer(ofstream &out)
void generate_deserialize_field_from_buffer(ofstream &out, t_field *tfield, string prefix, string suffix, int error_ret)
void generate_serialize_container(ofstream &out, t_type *ttype, string prefix, int error_ret)
string declare_field(t_field *tfield, bool init=false, bool pointer=false, bool constant=false, bool reference=false)
void generate_deserialize_u32_from_buffer(ofstream &out, string name, int error_ret)
virtual bool is_set() const
Definition: t_type.h:77
void generate_serialize_u64_to_buffer(ofstream &out, string name, int error_ret)
void generate_const_initializer(string name, t_type *type, t_const_value *value)
void generate_struct_end_writer_to_buffer(ofstream &out, bool is_sandesh)
void generate_write_buffer_memcpy(ofstream &out, string source, string length, bool ref)
void generate_serialize_byte_to_buffer(ofstream &out, string name, int error_ret)
void generate_sandesh_info()
void generate_object(t_struct *tstruct)
std::string get_uuid() const
virtual bool is_void() const
Definition: t_type.h:60
void generate_field_begin_reader_from_buffer(ofstream &out, string field_type, string field_id, int error_ret)
void generate_deserialize_list_element_from_buffer(ofstream &out, t_list *tlist, string prefix, string index, int error_ret)
t_type * get_elem_type() const
Definition: t_list.h:34
e_req get_req() const
Definition: t_field.h:113
int32_t get_key() const
Definition: t_field.h:99
void generate_field_begin_writer_to_buffer(ofstream &out, string key, string field_type, int error_ret)
t_c_generator(t_program *program, const map< string, string > &parsed_options, const string &option_string)
bool is_complex_type(t_type *ttype)
void generate_buffer_bounds_chk(ofstream &out, string length, int error_ret)
const std::string & get_symbolic() const
Definition: t_typedef.h:46
t_base get_base() const
Definition: t_base_type.h:81
void generate_struct_reader_from_buffer(ofstream &out, string name, const vector< t_field * > &fields, bool is_sandesh, bool is_function=true)
void generate_object_internal(string name, const vector< t_field * > &members, bool is_sandesh)
virtual const std::string & get_name() const
Definition: t_type.h:56
void generate_read_buffer_memcpy(ofstream &out, string dest, string length, bool ref)
ofstream f_types_
virtual bool is_list() const
Definition: t_type.h:76
void generate_xception(t_struct *tstruct)
void generate_deserialize_double_from_buffer(ofstream &out, string name, int error_ret)
void generate_serialize_string_to_buffer(ofstream &out, string name, int error_ret)
void generate_serialize_bool_to_buffer(ofstream &out, string name, int error_ret)
string initial_caps_to_underscores(string name)
const std::vector< t_enum_value * > & get_constants()
Definition: t_enum.h:43
void generate_serialize_field_to_buffer(ofstream &out, t_field *tfield, string prefix, string suffix, int error_ret)
void generate_deserialize_struct(ofstream &out, t_struct *tstruct, string prefix, int error_ret)
void generate_struct_deleter(ofstream &out, string name, const vector< t_field * > &fields, bool is_sandesh, bool is_function=true)
std::string get_string() const
Definition: t_const_value.h:63
double get_double() const
Definition: t_const_value.h:99
void init_generator()
virtual bool is_struct() const
Definition: t_type.h:73
string type_to_enum(t_type *type)
void generate_read_buffer_memcpy_incr_offset(ofstream &out, string dest, string length, bool ref)
void generate_deserialize_struct_from_buffer(ofstream &out, t_struct *tstruct, string prefix, int error_ret)
Definition: t_list.h:29
void generate_deserialize_i32_from_buffer(ofstream &out, string name, int error_ret)
void generate_serialize_i16_to_buffer(ofstream &out, string name, int error_ret)
void generate_serialize_u32_to_buffer(ofstream &out, string name, int error_ret)
void generate_struct_writer(ofstream &out, string name, const vector< t_field * > &fields, bool is_sandesh, bool is_function=true)
string type_name(t_type *ttype, bool in_typedef=false, bool is_const=false)
void generate_enum(t_enum *tenum)
void generate_deserialize_ipaddr_from_buffer(ofstream &out, string name, int error_ret)
void generate_deserialize_list_element(ofstream &out, t_list *tlist, string prefix, string index, int error_ret)
void generate_serialize_struct_to_buffer(ofstream &out, t_struct *tstruct, string prefix, int error_ret)
void generate_serialize_list_element(ofstream &out, t_list *tlist, string list, string index, int error_ret)
void generate_deserialize_byte_from_buffer(ofstream &out, string name, int error_ret)
void generate_typedef(t_typedef *ttypedef)
void generate_deserialize_i64_from_buffer(ofstream &out, string name, int error_ret)
void generate_sandesh(t_sandesh *tsandesh)
string to_upper_case(string name)
void generate_service_client(t_service *tservice)
string argument_list(t_struct *tstruct)
void generate_service_server(t_service *tservice)
bool is_binary() const
Definition: t_base_type.h:186
ofstream f_types_impl_
void generate_struct_writer_to_buffer(ofstream &out, string name, const vector< t_field * > &fields, bool is_sandesh, bool is_function=true)
void generate_deserialize_container_from_buffer(ofstream &out, t_type *ttype, string prefix, int error_ret)
void close_generator()
string constant_value(string name, t_type *type, t_const_value *value)
#define THRIFT_REGISTER_GENERATOR(language, long_name, doc)
void generate_serialize_u16_to_buffer(ofstream &out, string name, int error_ret)