in compiler/cpp/src/thrift/generate/t_c_glib_generator.cc [1265:1830]
void t_c_glib_generator::generate_service_client(t_service* tservice) {
/* get some C friendly service names */
string service_name_lc = to_lower_case(initial_caps_to_underscores(service_name_));
string service_name_uc = to_upper_case(service_name_lc);
string parent_service_name;
string parent_service_name_lc;
string parent_service_name_uc;
string parent_class_name = "GObject";
string parent_type_name = "G_TYPE_OBJECT";
// The service this service extends, or nullptr if it extends no
// service
t_service* extends_service = tservice->get_extends();
if (extends_service) {
// The name of the parent service
parent_service_name = extends_service->get_name();
parent_service_name_lc = to_lower_case(initial_caps_to_underscores(parent_service_name));
parent_service_name_uc = to_upper_case(parent_service_name_lc);
// The names of the client class' parent class and type
parent_class_name = this->nspace + parent_service_name + "Client";
parent_type_name = this->nspace_uc + "TYPE_" + parent_service_name_uc + "_CLIENT";
}
// The base service (the topmost in the "extends" hierarchy), on
// whose client class the "input_protocol" and "output_protocol"
// properties are defined
t_service* base_service = tservice;
while (base_service->get_extends()) {
base_service = base_service->get_extends();
}
string base_service_name = base_service->get_name();
string base_service_name_lc = to_lower_case(initial_caps_to_underscores(base_service_name));
string base_service_name_uc = to_upper_case(base_service_name_lc);
// Generate the client interface dummy object in the header.
f_header_ << "/* " << service_name_ << " service interface */" << '\n' << "typedef struct _"
<< this->nspace << service_name_ << "If " << this->nspace << service_name_ << "If; "
<< " /* dummy object */" << '\n' << '\n';
// Generate the client interface object in the header.
f_header_ << "struct _" << this->nspace << service_name_ << "IfInterface" << '\n' << "{" << '\n'
<< " GTypeInterface parent;" << '\n' << '\n';
/* write out the functions for this interface */
indent_up();
vector<t_function*> functions = tservice->get_functions();
vector<t_function*>::const_iterator f_iter;
for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
/* make the function name C friendly */
string funname = initial_caps_to_underscores((*f_iter)->get_name());
t_type* ttype = (*f_iter)->get_returntype();
t_struct* arglist = (*f_iter)->get_arglist();
t_struct* xlist = (*f_iter)->get_xceptions();
bool has_return = !ttype->is_void();
bool has_args = arglist->get_members().size() == 0;
bool has_xceptions = xlist->get_members().size() == 0;
string params = "(" + this->nspace + service_name_ + "If *iface"
+ (has_return ? ", " + type_name(ttype) + "* _return" : "")
+ (has_args ? "" : (", " + argument_list(arglist)))
+ (has_xceptions ? "" : (", " + xception_list(xlist))) + ", GError **error)";
indent(f_header_) << "gboolean (*" << funname << ") " << params << ";" << '\n';
}
indent_down();
f_header_ << "};" << '\n' << "typedef struct _" << this->nspace << service_name_ << "IfInterface "
<< this->nspace << service_name_ << "IfInterface;" << '\n' << '\n';
// generate all the interface boilerplate
f_header_ << "GType " << this->nspace_lc << service_name_lc << "_if_get_type (void);" << '\n'
<< "#define " << this->nspace_uc << "TYPE_" << service_name_uc << "_IF "
<< "(" << this->nspace_lc << service_name_lc << "_if_get_type())" << '\n' << "#define "
<< this->nspace_uc << service_name_uc << "_IF(obj) "
<< "(G_TYPE_CHECK_INSTANCE_CAST ((obj), " << this->nspace_uc << "TYPE_"
<< service_name_uc << "_IF, " << this->nspace << service_name_ << "If))" << '\n'
<< "#define " << this->nspace_uc << "IS_" << service_name_uc << "_IF(obj) "
<< "(G_TYPE_CHECK_INSTANCE_TYPE ((obj), " << this->nspace_uc << "TYPE_"
<< service_name_uc << "_IF))" << '\n' << "#define " << this->nspace_uc
<< service_name_uc << "_IF_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), "
<< this->nspace_uc << "TYPE_" << service_name_uc << "_IF, " << this->nspace
<< service_name_ << "IfInterface))" << '\n' << '\n';
// write out all the interface function prototypes
for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
/* make the function name C friendly */
string funname = initial_caps_to_underscores((*f_iter)->get_name());
t_type* ttype = (*f_iter)->get_returntype();
t_struct* arglist = (*f_iter)->get_arglist();
t_struct* xlist = (*f_iter)->get_xceptions();
bool has_return = !ttype->is_void();
bool has_args = arglist->get_members().size() == 0;
bool has_xceptions = xlist->get_members().size() == 0;
string params = "(" + this->nspace + service_name_ + "If *iface"
+ (has_return ? ", " + type_name(ttype) + "* _return" : "")
+ (has_args ? "" : (", " + argument_list(arglist)))
+ (has_xceptions ? "" : (", " + xception_list(xlist))) + ", GError **error)";
f_header_ << "gboolean " << this->nspace_lc << service_name_lc << "_if_" << funname << " "
<< params << ";" << '\n';
}
f_header_ << '\n';
// Generate the client object instance definition in the header.
f_header_ << "/* " << service_name_ << " service client */" << '\n' << "struct _" << this->nspace
<< service_name_ << "Client" << '\n' << "{" << '\n' << " " << parent_class_name
<< " parent;" << '\n';
if (!extends_service) {
// Define "input_protocol" and "output_protocol" properties only
// for base services; child service-client classes will inherit
// these
f_header_ << '\n' << " ThriftProtocol *input_protocol;" << '\n'
<< " ThriftProtocol *output_protocol;" << '\n';
}
f_header_ << "};" << '\n' << "typedef struct _" << this->nspace << service_name_ << "Client "
<< this->nspace << service_name_ << "Client;" << '\n' << '\n';
// Generate the class definition in the header.
f_header_ << "struct _" << this->nspace << service_name_ << "ClientClass" << '\n' << "{" << '\n'
<< " " << parent_class_name << "Class parent;" << '\n' << "};" << '\n'
<< "typedef struct _" << this->nspace << service_name_ << "ClientClass " << this->nspace
<< service_name_ << "ClientClass;" << '\n' << '\n';
// Create all the GObject boilerplate
f_header_ << "GType " << this->nspace_lc << service_name_lc << "_client_get_type (void);" << '\n'
<< "#define " << this->nspace_uc << "TYPE_" << service_name_uc << "_CLIENT "
<< "(" << this->nspace_lc << service_name_lc << "_client_get_type())" << '\n'
<< "#define " << this->nspace_uc << service_name_uc << "_CLIENT(obj) "
<< "(G_TYPE_CHECK_INSTANCE_CAST ((obj), " << this->nspace_uc << "TYPE_"
<< service_name_uc << "_CLIENT, " << this->nspace << service_name_ << "Client))" << '\n'
<< "#define " << this->nspace_uc << service_name_uc << "_CLIENT_CLASS(c) "
<< "(G_TYPE_CHECK_CLASS_CAST ((c), " << this->nspace_uc << "TYPE_" << service_name_uc
<< "_CLIENT, " << this->nspace << service_name_ << "ClientClass))" << '\n' << "#define "
<< this->nspace_uc << service_name_uc << "_IS_CLIENT(obj) "
<< "(G_TYPE_CHECK_INSTANCE_TYPE ((obj), " << this->nspace_uc << "TYPE_"
<< service_name_uc << "_CLIENT))" << '\n' << "#define " << this->nspace_uc
<< service_name_uc << "_IS_CLIENT_CLASS(c) "
<< "(G_TYPE_CHECK_CLASS_TYPE ((c), " << this->nspace_uc << "TYPE_" << service_name_uc
<< "_CLIENT))" << '\n' << "#define " << this->nspace_uc << service_name_uc
<< "_CLIENT_GET_CLASS(obj) "
<< "(G_TYPE_INSTANCE_GET_CLASS ((obj), " << this->nspace_uc << "TYPE_"
<< service_name_uc << "_CLIENT, " << this->nspace << service_name_ << "ClientClass))"
<< '\n' << '\n';
/* write out the function prototypes */
for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
/* make the function name C friendly */
string funname = to_lower_case(initial_caps_to_underscores((*f_iter)->get_name()));
t_function service_function((*f_iter)->get_returntype(),
service_name_lc + string("_client_") + funname,
(*f_iter)->get_arglist(),
(*f_iter)->get_xceptions());
indent(f_header_) << function_signature(&service_function) << ";" << '\n';
t_function send_function(g_type_void,
service_name_lc + string("_client_send_") + funname,
(*f_iter)->get_arglist());
indent(f_header_) << function_signature(&send_function) << ";" << '\n';
// implement recv if not a oneway service
if (!(*f_iter)->is_oneway()) {
t_struct noargs(program_);
t_function recv_function((*f_iter)->get_returntype(),
service_name_lc + string("_client_recv_") + funname,
&noargs,
(*f_iter)->get_xceptions());
indent(f_header_) << function_signature(&recv_function) << ";" << '\n';
}
}
/* write out the get/set function prototypes */
f_header_ << "void " + service_name_lc + "_client_set_property (GObject *object, guint "
"property_id, const GValue *value, GParamSpec *pspec);"
<< '\n';
f_header_ << "void " + service_name_lc + "_client_get_property (GObject *object, guint "
"property_id, GValue *value, GParamSpec *pspec);"
<< '\n';
f_header_ << '\n';
// end of header code
// Generate interface method implementations
for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
/* make the function name C friendly */
string funname = initial_caps_to_underscores((*f_iter)->get_name());
t_type* ttype = (*f_iter)->get_returntype();
t_struct* arglist = (*f_iter)->get_arglist();
t_struct* xlist = (*f_iter)->get_xceptions();
bool has_return = !ttype->is_void();
bool has_args = arglist->get_members().size() == 0;
bool has_xceptions = xlist->get_members().size() == 0;
string params = "(" + this->nspace + service_name_ + "If *iface"
+ (has_return ? ", " + type_name(ttype) + "* _return" : "")
+ (has_args ? "" : (", " + argument_list(arglist)))
+ (has_xceptions ? "" : (", " + xception_list(xlist))) + ", GError **error)";
string params_without_type = string("iface, ") + (has_return ? "_return, " : "");
const vector<t_field*>& fields = arglist->get_members();
vector<t_field*>::const_iterator f_iter_field;
for (f_iter_field = fields.begin(); f_iter_field != fields.end(); ++f_iter_field) {
params_without_type += (*f_iter_field)->get_name();
params_without_type += ", ";
}
const vector<t_field*>& xceptions = xlist->get_members();
vector<t_field*>::const_iterator x_iter;
for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) {
params_without_type += (*x_iter)->get_name();
params_without_type += ", ";
}
f_service_ << "gboolean" << '\n' << this->nspace_lc << service_name_lc << "_if_" << funname
<< " " << params << '\n' << "{" << '\n' << " return " << this->nspace_uc
<< service_name_uc << "_IF_GET_INTERFACE (iface)->" << funname << " ("
<< params_without_type << "error);" << '\n' << "}" << '\n' << '\n';
}
// Generate interface boilerplate
f_service_ << "GType" << '\n' << this->nspace_lc << service_name_lc << "_if_get_type (void)"
<< '\n' << "{" << '\n' << " static GType type = 0;" << '\n' << " if (type == 0)"
<< '\n' << " {" << '\n' << " static const GTypeInfo type_info =" << '\n' << " {"
<< '\n' << " sizeof (" << this->nspace << service_name_ << "IfInterface)," << '\n'
<< " NULL, /* base_init */" << '\n' << " NULL, /* base_finalize */" << '\n'
<< " NULL, /* class_init */" << '\n' << " NULL, /* class_finalize */"
<< '\n' << " NULL, /* class_data */" << '\n'
<< " 0, /* instance_size */" << '\n' << " 0, /* n_preallocs */"
<< '\n' << " NULL, /* instance_init */" << '\n'
<< " NULL /* value_table */" << '\n' << " };" << '\n'
<< " type = g_type_register_static (G_TYPE_INTERFACE," << '\n'
<< " \"" << this->nspace << service_name_ << "If\","
<< '\n' << " &type_info, 0);" << '\n' << " }"
<< '\n' << " return type;" << '\n' << "}" << '\n' << '\n';
// Generate client boilerplate
f_service_ << "static void " << '\n' << this->nspace_lc << service_name_lc
<< "_if_interface_init (" << this->nspace << service_name_ << "IfInterface *iface);"
<< '\n' << '\n' << "G_DEFINE_TYPE_WITH_CODE (" << this->nspace << service_name_
<< "Client, " << this->nspace_lc << service_name_lc << "_client," << '\n'
<< " " << parent_type_name << ", " << '\n'
<< " G_IMPLEMENT_INTERFACE (" << this->nspace_uc << "TYPE_"
<< service_name_uc << "_IF," << '\n'
<< " " << this->nspace_lc
<< service_name_lc << "_if_interface_init))" << '\n' << '\n';
// Generate property-related code only for base services---child
// service-client classes have only properties inherited from their
// parent class
if (!extends_service) {
// Generate client properties
f_service_ << "enum _" << this->nspace << service_name_ << "ClientProperties" << '\n' << "{"
<< '\n' << " PROP_0," << '\n' << " PROP_" << this->nspace_uc << service_name_uc
<< "_CLIENT_INPUT_PROTOCOL," << '\n' << " PROP_" << this->nspace_uc
<< service_name_uc << "_CLIENT_OUTPUT_PROTOCOL" << '\n' << "};" << '\n' << '\n';
// generate property setter
f_service_ << "void" << '\n' << this->nspace_lc << service_name_lc << "_client_set_property ("
<< "GObject *object, guint property_id, const GValue *value, "
<< "GParamSpec *pspec)" << '\n' << "{" << '\n' << " " << this->nspace
<< service_name_ << "Client *client = " << this->nspace_uc << service_name_uc
<< "_CLIENT (object);" << '\n' << '\n' << " THRIFT_UNUSED_VAR (pspec);" << '\n'
<< '\n' << " switch (property_id)" << '\n' << " {" << '\n' << " case PROP_"
<< this->nspace_uc << service_name_uc << "_CLIENT_INPUT_PROTOCOL:" << '\n'
<< " client->input_protocol = g_value_get_object (value);" << '\n'
<< " break;" << '\n' << " case PROP_" << this->nspace_uc << service_name_uc
<< "_CLIENT_OUTPUT_PROTOCOL:" << '\n'
<< " client->output_protocol = g_value_get_object (value);" << '\n'
<< " break;" << '\n' << " }" << '\n' << "}" << '\n' << '\n';
// generate property getter
f_service_ << "void" << '\n' << this->nspace_lc << service_name_lc << "_client_get_property ("
<< "GObject *object, guint property_id, GValue *value, "
<< "GParamSpec *pspec)" << '\n' << "{" << '\n' << " " << this->nspace
<< service_name_ << "Client *client = " << this->nspace_uc << service_name_uc
<< "_CLIENT (object);" << '\n' << '\n' << " THRIFT_UNUSED_VAR (pspec);" << '\n'
<< '\n' << " switch (property_id)" << '\n' << " {" << '\n' << " case PROP_"
<< this->nspace_uc << service_name_uc << "_CLIENT_INPUT_PROTOCOL:" << '\n'
<< " g_value_set_object (value, client->input_protocol);" << '\n'
<< " break;" << '\n' << " case PROP_" << this->nspace_uc << service_name_uc
<< "_CLIENT_OUTPUT_PROTOCOL:" << '\n'
<< " g_value_set_object (value, client->output_protocol);" << '\n'
<< " break;" << '\n' << " }" << '\n' << "}" << '\n' << '\n';
}
// Generate client method implementations
for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
string name = (*f_iter)->get_name();
string funname = initial_caps_to_underscores(name);
// Get the struct of function call params and exceptions
t_struct* arg_struct = (*f_iter)->get_arglist();
// Function for sending
t_function send_function(g_type_void,
service_name_lc + string("_client_send_") + funname,
(*f_iter)->get_arglist());
// Open the send function
indent(f_service_) << function_signature(&send_function) << '\n';
scope_up(f_service_);
string reqType = (*f_iter)->is_oneway() ? "T_ONEWAY" : "T_CALL";
// Serialize the request
f_service_ << indent() << "gint32 cseqid = 0;" << '\n' << indent()
<< "ThriftProtocol * protocol = " << this->nspace_uc << base_service_name_uc
<< "_CLIENT (iface)->output_protocol;" << '\n' << '\n' << indent()
<< "if (thrift_protocol_write_message_begin (protocol, \"" << name << "\", "
<< reqType << ", cseqid, error) < 0)" << '\n' << indent() << " return FALSE;"
<< '\n' << '\n';
generate_struct_writer(f_service_, arg_struct, "", "", false);
f_service_ << indent() << "if (thrift_protocol_write_message_end (protocol, error) < 0)" << '\n'
<< indent() << " return FALSE;" << '\n' << indent()
<< "if (!thrift_transport_flush (protocol->transport, error))" << '\n' << indent()
<< " return FALSE;" << '\n' << indent()
<< "if (!thrift_transport_write_end (protocol->transport, error))" << '\n'
<< indent() << " return FALSE;" << '\n' << '\n' << indent() << "return TRUE;"
<< '\n';
scope_down(f_service_);
f_service_ << '\n';
// Generate recv function only if not an async function
if (!(*f_iter)->is_oneway()) {
t_struct noargs(program_);
t_function recv_function((*f_iter)->get_returntype(),
service_name_lc + string("_client_recv_") + funname,
&noargs,
(*f_iter)->get_xceptions());
// Open function
indent(f_service_) << function_signature(&recv_function) << '\n';
scope_up(f_service_);
f_service_ << indent() << "gint32 rseqid;" << '\n'
<< indent() << "gchar * fname = NULL;" << '\n'
<< indent() << "ThriftMessageType mtype;" << '\n'
<< indent() << "ThriftProtocol * protocol = "
<< this->nspace_uc << base_service_name_uc
<< "_CLIENT (iface)->input_protocol;" << '\n'
<< indent() << "ThriftApplicationException *xception;" << '\n'
<< '\n'
<< indent() << "if (thrift_protocol_read_message_begin "
"(protocol, &fname, &mtype, &rseqid, error) < 0) {" << '\n';
indent_up();
f_service_ << indent() << "if (fname) g_free (fname);" << '\n'
<< indent() << "return FALSE;" << '\n';
indent_down();
f_service_ << indent() << "}" << '\n'
<< '\n'
<< indent() << "if (mtype == T_EXCEPTION) {" << '\n';
indent_up();
f_service_ << indent() << "if (fname) g_free (fname);" << '\n'
<< indent() << "xception = g_object_new "
"(THRIFT_TYPE_APPLICATION_EXCEPTION, NULL);" << '\n'
<< indent() << "thrift_struct_read (THRIFT_STRUCT (xception), "
"protocol, NULL);" << '\n'
<< indent() << "thrift_protocol_read_message_end "
"(protocol, NULL);" << '\n'
<< indent() << "thrift_transport_read_end "
"(protocol->transport, NULL);" << '\n'
<< indent() << "g_set_error (error, "
"THRIFT_APPLICATION_EXCEPTION_ERROR,xception->type, "
"\"application error: %s\", xception->message);" << '\n'
<< indent() << "g_object_unref (xception);" << '\n'
<< indent() << "return FALSE;" << '\n';
indent_down();
f_service_ << indent() << "} else if (mtype != T_REPLY) {" << '\n';
indent_up();
f_service_ << indent() << "if (fname) g_free (fname);" << '\n'
<< indent() << "thrift_protocol_skip (protocol, T_STRUCT, "
"NULL);" << '\n'
<< indent() << "thrift_protocol_read_message_end (protocol, "
"NULL);" << '\n'
<< indent() << "thrift_transport_read_end ("
"protocol->transport, NULL);" << '\n'
<< indent() << "g_set_error (error, "
"THRIFT_APPLICATION_EXCEPTION_ERROR, "
"THRIFT_APPLICATION_EXCEPTION_ERROR_INVALID_MESSAGE_TYPE, "
"\"invalid message type %d, expected T_REPLY\", mtype);"
<< '\n'
<< indent() << "return FALSE;" << '\n';
indent_down();
f_service_ << indent() << "} else if (strncmp (fname, \"" << name
<< "\", " << name.length() << ") != 0) {" << '\n';
indent_up();
f_service_ << indent() << "thrift_protocol_skip (protocol, T_STRUCT, "
"NULL);" << '\n'
<< indent() << "thrift_protocol_read_message_end (protocol,"
"error);" << '\n'
<< indent() << "thrift_transport_read_end ("
"protocol->transport, error);" << '\n'
<< indent() << "g_set_error (error, "
"THRIFT_APPLICATION_EXCEPTION_ERROR, "
"THRIFT_APPLICATION_EXCEPTION_ERROR_WRONG_METHOD_NAME, "
"\"wrong method name %s, expected " << name
<< "\", fname);" << '\n'
<< indent() << "if (fname) g_free (fname);" << '\n'
<< indent() << "return FALSE;" << '\n';
indent_down();
f_service_ << indent() << "}" << '\n'
<< indent() << "if (fname) g_free (fname);" << '\n'
<< '\n';
t_struct* xs = (*f_iter)->get_xceptions();
const std::vector<t_field*>& xceptions = xs->get_members();
vector<t_field*>::const_iterator x_iter;
{
t_struct result(program_, tservice->get_name() + "_" + (*f_iter)->get_name() + "_result");
t_field success((*f_iter)->get_returntype(), "*_return", 0);
if (!(*f_iter)->get_returntype()->is_void()) {
result.append(&success);
}
// add readers for exceptions, dereferencing the pointer.
for (x_iter = xceptions.begin(); x_iter != xceptions.end(); x_iter++) {
t_field* xception = new t_field((*x_iter)->get_type(),
"*" + (*x_iter)->get_name(),
(*x_iter)->get_key());
result.append(xception);
}
generate_struct_reader(f_service_, &result, "", "", false);
}
f_service_ << indent() << "if (thrift_protocol_read_message_end (protocol, error) < 0)"
<< '\n' << indent() << " return FALSE;" << '\n' << '\n' << indent()
<< "if (!thrift_transport_read_end (protocol->transport, error))" << '\n'
<< indent() << " return FALSE;" << '\n' << '\n';
// copy over any throw exceptions and return failure
for (x_iter = xceptions.begin(); x_iter != xceptions.end(); x_iter++) {
f_service_ << indent() << "if (*" << (*x_iter)->get_name() << " != NULL)" << '\n'
<< indent() << "{" << '\n' << indent() << " g_set_error (error, "
<< this->nspace_uc
<< to_upper_case(initial_caps_to_underscores((*x_iter)->get_type()->get_name()))
<< "_ERROR, " << this->nspace_uc
<< to_upper_case(initial_caps_to_underscores((*x_iter)->get_type()->get_name()))
<< "_ERROR_CODE, \"" << (*x_iter)->get_type()->get_name() << "\");" << '\n'
<< indent() << " return FALSE;" << '\n' << indent() << "}" << '\n';
}
// Close function
indent(f_service_) << "return TRUE;" << '\n';
scope_down(f_service_);
f_service_ << '\n';
}
// Open function
t_function service_function((*f_iter)->get_returntype(),
service_name_lc + string("_client_") + funname,
(*f_iter)->get_arglist(),
(*f_iter)->get_xceptions());
indent(f_service_) << function_signature(&service_function) << '\n';
scope_up(f_service_);
// wrap each function
f_service_ << indent() << "if (!" << this->nspace_lc << service_name_lc << "_client_send_"
<< funname << " (iface";
// Declare the function arguments
const vector<t_field*>& fields = arg_struct->get_members();
vector<t_field*>::const_iterator fld_iter;
for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) {
f_service_ << ", " << (*fld_iter)->get_name();
}
f_service_ << ", error))" << '\n' << indent() << " return FALSE;" << '\n';
// if not oneway, implement recv
if (!(*f_iter)->is_oneway()) {
string ret = (*f_iter)->get_returntype()->is_void() ? "" : "_return, ";
const vector<t_field*>& xceptions = (*f_iter)->get_xceptions()->get_members();
vector<t_field*>::const_iterator x_iter;
for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) {
ret += (*x_iter)->get_name();
ret += ", ";
}
f_service_ << indent() << "if (!" << this->nspace_lc << service_name_lc << "_client_recv_"
<< funname << " (iface, " << ret << "error))" << '\n' << indent()
<< " return FALSE;" << '\n';
}
// return TRUE which means all functions were called OK
indent(f_service_) << "return TRUE;" << '\n';
scope_down(f_service_);
f_service_ << '\n';
}
// create the interface initializer
f_service_ << "static void" << '\n'
<< this->nspace_lc << service_name_lc << "_if_interface_init ("
<< this->nspace << service_name_ << "IfInterface *iface)" << '\n';
scope_up(f_service_);
if (functions.size() > 0) {
for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
/* make the function name C friendly */
string funname = initial_caps_to_underscores((*f_iter)->get_name());
f_service_ << indent() << "iface->" << funname << " = " << this->nspace_lc
<< service_name_lc << "_client_" << funname << ";" << '\n';
}
}
else {
f_service_ << indent() << "THRIFT_UNUSED_VAR (iface);" << '\n';
}
scope_down(f_service_);
f_service_ << '\n';
// create the client instance initializer
f_service_ << "static void" << '\n'
<< this->nspace_lc << service_name_lc << "_client_init ("
<< this->nspace << service_name_ << "Client *client)" << '\n';
scope_up(f_service_);
if (!extends_service) {
f_service_ << indent() << "client->input_protocol = NULL;" << '\n'
<< indent() << "client->output_protocol = NULL;" << '\n';
}
else {
f_service_ << indent() << "THRIFT_UNUSED_VAR (client);" << '\n';
}
scope_down(f_service_);
f_service_ << '\n';
// create the client class initializer
f_service_ << "static void" << '\n' << this->nspace_lc << service_name_lc
<< "_client_class_init (" << this->nspace << service_name_ << "ClientClass *cls)"
<< '\n' << "{" << '\n';
if (!extends_service) {
f_service_ << " GObjectClass *gobject_class = G_OBJECT_CLASS (cls);" << '\n'
<< " GParamSpec *param_spec;" << '\n' << '\n'
<< " gobject_class->set_property = " << this->nspace_lc << service_name_lc
<< "_client_set_property;" << '\n'
<< " gobject_class->get_property = " << this->nspace_lc << service_name_lc
<< "_client_get_property;" << '\n' << '\n'
<< " param_spec = g_param_spec_object (\"input_protocol\"," << '\n'
<< " \"input protocol (construct)\"," << '\n'
<< " \"Set the client input protocol\"," << '\n'
<< " THRIFT_TYPE_PROTOCOL," << '\n'
<< " G_PARAM_READWRITE);" << '\n'
<< " g_object_class_install_property (gobject_class," << '\n'
<< " PROP_" << this->nspace_uc << service_name_uc
<< "_CLIENT_INPUT_PROTOCOL, param_spec);" << '\n' << '\n'
<< " param_spec = g_param_spec_object (\"output_protocol\"," << '\n'
<< " \"output protocol (construct)\"," << '\n'
<< " \"Set the client output protocol\"," << '\n'
<< " THRIFT_TYPE_PROTOCOL," << '\n'
<< " G_PARAM_READWRITE);" << '\n'
<< " g_object_class_install_property (gobject_class," << '\n'
<< " PROP_" << this->nspace_uc << service_name_uc
<< "_CLIENT_OUTPUT_PROTOCOL, param_spec);" << '\n';
}
else {
f_service_ << " THRIFT_UNUSED_VAR (cls);" << '\n';
}
f_service_ << "}" << '\n' << '\n';
}