PageRenderTime 82ms CodeModel.GetById 33ms app.highlight 44ms RepoModel.GetById 1ms app.codeStats 0ms

/tools/fbusgen/coder_service.c

http://ftk.googlecode.com/
C | 428 lines | 352 code | 47 blank | 29 comment | 50 complexity | 1c8b528c8137d9a6b13e17948e73b53d MD5 | raw file
  1/*
  2 * File:    
  3 * Author:  Li XianJing <xianjimli@hotmail.com>
  4 * Brief:   
  5 *
  6 * Copyright (c) 2009 - 2010  Li XianJing <xianjimli@hotmail.com>
  7 *
  8 * Licensed under the Academic Free License version 2.1
  9 *
 10 * This program is free software; you can redistribute it and/or modify
 11 * it under the terms of the GNU General Public License as published by
 12 * the Free Software Foundation; either version 2 of the License, or
 13 * (at your option) any later version.
 14 *
 15 * This program is distributed in the hope that it will be useful,
 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 18 * GNU General Public License for more details.
 19 *
 20 * You should have received a copy of the GNU General Public License
 21 * along with this program; if not, write to the Free Software
 22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 23 */
 24
 25/*
 26 * History:
 27 * ================================================================
 28 * 2010-07-31 Li XianJing <xianjimli@hotmail.com> created
 29 *
 30 */
 31
 32#include "coder_intf.h"
 33
 34#define STR_LENGTH 127
 35
 36typedef struct _PrivInfo
 37{
 38	char* name;
 39	char* lower_name;
 40	GString* func_create;
 41	GString* func_empty;
 42	GString* func_dispatch;
 43	gboolean  has_interface;
 44    char interface[STR_LENGTH+1];
 45    char interface_lower[STR_LENGTH+1];
 46    char interface_upper[STR_LENGTH+1];
 47}PrivInfo;
 48
 49static gboolean coder_service_gen_service(PrivInfo* priv, FILE* fp)
 50{
 51	fprintf(fp, "static const char* %s_service_get_name(FBusService* thiz)\n", priv->interface_lower);
 52	fprintf(fp, "{\n");
 53	fprintf(fp, "	return FBUS_SERVICE_%s;\n", priv->interface_upper);
 54	fprintf(fp, "}\n\n");
 55	fprintf(fp, "static Ret %s_service_on_client_connect(FBusService* thiz, int client_id)\n", 
 56		priv->interface_lower);
 57	fprintf(fp, "{\n");
 58	fprintf(fp, "\treturn RET_OK;\n");
 59	fprintf(fp, "}\n\n");
 60	fprintf(fp, "static Ret %s_service_on_client_disconnect(FBusService* thiz, int client_id)\n", 
 61		priv->interface_lower);
 62	fprintf(fp, "{\n");
 63	fprintf(fp, "\treturn RET_OK;\n");
 64	fprintf(fp, "}\n\n");
 65	fprintf(fp, "static Ret %s_service_handle_request(FBusService* thiz, int client_id, FBusParcel* req_resp)\n",
 66		priv->interface_lower);
 67	fprintf(fp, "{\n");
 68	fprintf(fp, "\tint req_code = fbus_parcel_get_int(req_resp);\n\n");
 69	fprintf(fp, "\tswitch(req_code)\n");
 70	fprintf(fp, "\t{\n");
 71	fprintf(fp, "%s", priv->func_dispatch->str);
 72	fprintf(fp, "\t\tdefault:break;\n");
 73	fprintf(fp, "\t}\n");
 74	fprintf(fp, "\treturn RET_OK;\n");
 75	fprintf(fp, "}\n\n");
 76	fprintf(fp, "static void %s_service_destroy(FBusService* thiz)\n", priv->interface_lower);
 77	fprintf(fp, "{\n");
 78	fprintf(fp, "\tif(thiz != NULL)\n");
 79	fprintf(fp, "\t{\n");
 80	fprintf(fp, "\t\tDECL_PRIV(thiz, priv);\n");
 81	fprintf(fp, "\t\t%s_destroy(priv->impl);\n", priv->interface_lower);
 82	fprintf(fp, "\t\tFTK_FREE(thiz);\n");
 83	fprintf(fp, "\t}\n");
 84	fprintf(fp, "\treturn;\n");
 85	fprintf(fp, "}\n\n");
 86	fprintf(fp, "FBusService* %s_service_create(void)\n", priv->interface_lower);
 87	fprintf(fp, "{\n");
 88	fprintf(fp, "\tFBusService* thiz = FTK_ZALLOC(sizeof(FBusService)+sizeof(PrivInfo));\n");
 89	fprintf(fp, "\tif(thiz != NULL)\n");
 90	fprintf(fp, "\t{\n");
 91	fprintf(fp, "\t\tDECL_PRIV(thiz, priv);\n");
 92	fprintf(fp, "\t\tpriv->impl = %s_impl_create();\n", priv->interface_lower);
 93	fprintf(fp, "\t\tthiz->get_name = %s_service_get_name;\n", priv->interface_lower);
 94	fprintf(fp, "\t\tthiz->on_client_connect = %s_service_on_client_connect;\n", priv->interface_lower);
 95	fprintf(fp, "\t\tthiz->on_client_disconnect = %s_service_on_client_disconnect;\n", priv->interface_lower);
 96	fprintf(fp, "\t\tthiz->handle_request = %s_service_handle_request;\n", priv->interface_lower);
 97	fprintf(fp, "\t\tthiz->destroy = %s_service_destroy;\n", priv->interface_lower);
 98	fprintf(fp, "\t\tfbus_service_register(thiz);\n");
 99	fprintf(fp, "\t}\n\n");
100	fprintf(fp, "\treturn thiz;\n");
101	fprintf(fp, "}\n\n");
102	fprintf(fp, "\n");
103
104	return TRUE;
105}
106
107static gboolean coder_service_end_interface(Coder* thiz)
108{
109	FILE* fp = NULL;
110	char h_filename[260] = {0};
111	char c_filename[260] = {0};
112	PrivInfo* priv = (PrivInfo*)thiz->priv;
113
114	if(!priv->has_interface)
115	{
116		return TRUE;
117	}
118	
119	mkdir(priv->interface, 0777);
120	
121	snprintf(h_filename, sizeof(h_filename) - 1, "%s/%s_service.h", priv->interface, priv->interface_lower);
122	fp = fopen(h_filename, "w+");
123	if(fp != NULL)
124	{
125		coder_write_header(fp);
126		fprintf(fp, "#ifndef %s_SERVICE_H\n", priv->interface_upper);
127		fprintf(fp, "#define %s_SERVICE_H\n\n", priv->interface_upper);
128		fprintf(fp, "#include \"fbus_service.h\"\n\n");
129		fprintf(fp, "FTK_BEGIN_DECLS\n\n");
130		fprintf(fp, "FBusService* %s_service_create(void);\n\n", priv->interface_lower);
131		fprintf(fp, "FTK_END_DECLS\n\n");
132		fprintf(fp, "#endif/*%s_SERVICE_H*/\n", priv->interface_upper);
133		fclose(fp);
134	}
135	
136	snprintf(c_filename, sizeof(c_filename) - 1, "%s/%s_service.c", priv->interface,  priv->interface_lower);
137	fp = fopen(c_filename, "w+");
138	if(fp != NULL)
139	{
140		coder_write_header(fp);
141		fprintf(fp, "#include \"%s.h\"\n", priv->interface_lower);
142		fprintf(fp, "#include \"%s_impl.h\"\n", priv->interface_lower);
143		fprintf(fp, "#include \"%s_share.h\"\n", priv->interface_lower);
144		fprintf(fp, "#include \"%s_service.h\"\n\n", priv->interface_lower);
145		fprintf(fp, "typedef struct _PrivInfo\n");
146		fprintf(fp, "{\n");
147		fprintf(fp, "	%s* impl;\n", priv->interface);
148		fprintf(fp, "}PrivInfo;\n\n");
149		fprintf(fp, "%s\n", priv->func_empty->str);
150		coder_service_gen_service(priv, fp);
151		fclose(fp);
152	}
153
154	g_string_free(priv->func_empty, 1);
155	g_string_free(priv->func_create, 1);
156	g_string_free(priv->func_dispatch, 1);
157
158	priv->has_interface = FALSE;
159
160	return TRUE;
161}
162
163static gboolean coder_service_on_interface(Coder* thiz, const char* name, const char* parent)
164{
165	PrivInfo* priv = (PrivInfo*)thiz->priv;
166
167	coder_service_end_interface(thiz);
168	
169	priv->has_interface = 1;
170	strncpy(priv->interface, name, STR_LENGTH);
171	coder_name_to_lower(name, priv->interface_lower);
172
173	strcpy(priv->interface_upper, priv->interface_lower);
174	coder_to_upper(priv->interface_upper);
175
176	priv->func_empty = g_string_sized_new(4096);
177	priv->func_create = g_string_sized_new(4096);
178	priv->func_dispatch = g_string_sized_new(4096);
179
180	return TRUE;
181}
182
183typedef struct _TypeInfo
184{
185	int attr;
186	gboolean is_binary;
187	char name[STR_LENGTH+1];
188	char org_name[STR_LENGTH+1];
189}TypeInfo;
190
191static gboolean coder_get_type_info(IDL_tree tree, int attr, TypeInfo* type)
192{
193	const char* name = "";
194	type->attr = attr;
195	if(attr == IDL_PARAM_INOUT)
196	{
197		assert(!"Not supported.");
198	}
199
200	memset(type, 0x00, sizeof(TypeInfo));
201	if(IDL_NODE_IS_TYPE(tree))
202	{
203		switch(IDL_NODE_TYPE(tree))
204		{
205			case IDLN_TYPE_INTEGER:
206			{
207				name = "int";
208				break;
209			}
210			case IDLN_TYPE_STRING:
211			{
212				name = "String";
213				break;
214			}
215			default:
216			{
217				assert(!"Not supported");
218				break;
219			}
220
221		}
222	}
223	else if(IDL_NODE_TYPE(tree) == IDLN_IDENT)
224	{
225		name = IDL_IDENT(tree).str;
226	}
227	
228	strcat(type->org_name, name);
229	if(strcmp(name, "int") == 0)
230	{
231		strcat(type->name, "int");
232	}
233	else if(strcmp(name, "String") == 0)
234	{
235		strcat(type->name, attr == IDL_PARAM_OUT ? "" : "const ");
236		strcat(type->name, "char*");
237	}
238	else if(strcmp(name, "FBusBinary") == 0)
239	{
240		type->is_binary = TRUE;
241	}
242	else
243	{
244		strcat(type->name, attr == IDL_PARAM_OUT ? "" : "const ");
245		strcat(type->name, name);
246		strcat(type->name, attr == IDL_PARAM_IN ? "*" : "");
247	}
248
249	return TRUE;
250}
251
252static gboolean coder_service_on_function(Coder* thiz, struct _IDL_OP_DCL f)
253{
254	int i = 0;
255	TypeInfo  type = {0};
256	const char* param_name = NULL;
257	struct _IDL_LIST iter = {0};
258	char lower_func_name[STR_LENGTH+1] = {0};
259	PrivInfo* priv = (PrivInfo*)thiz->priv;
260	char req_coder_name[STR_LENGTH+1];
261	const char* func_name = IDL_IDENT(f.ident).str;
262	GString* params_list = g_string_sized_new(1024);
263	GString* params_in = g_string_sized_new(1024);
264	GString* params_out = g_string_sized_new(1024);
265	GString* params_call = g_string_sized_new(1024);
266	GString* params_decls = g_string_sized_new(1024);
267	GString* params_free = g_string_sized_new(1024);
268
269	coder_name_to_lower(func_name, lower_func_name);
270	coder_get_type_info(f.op_type_spec, 0, &type);
271	
272	if(f.parameter_dcls != NULL)
273	{
274		for (i = 0, iter = IDL_LIST(f.parameter_dcls); iter.data != NULL; iter = IDL_LIST(iter.next))
275		{
276			int attr = IDL_PARAM_DCL(iter.data).attr;
277			param_name = IDL_IDENT(IDL_PARAM_DCL(iter.data).simple_declarator).str;
278			coder_get_type_info(IDL_PARAM_DCL(iter.data).param_type_spec, attr, &type);
279
280			g_string_append_printf(params_list, ", %s %s", type.name, param_name);
281			g_string_append_printf(params_decls, "\t%s %s = {0};\n", type.name, param_name);
282			g_string_append_printf(params_call, ", %s%s", attr == IDL_PARAM_OUT ? "&" : "", param_name);
283
284			if(attr == IDL_PARAM_OUT)
285			{
286				if(strcmp(type.org_name, "int") == 0)
287				{
288					g_string_append_printf(params_out, "\t\t\tfbus_parcel_write_int(req_resp, %s);\n", param_name);
289				}
290				else if(strcmp(type.org_name, "String") == 0)
291				{
292					g_string_append_printf(params_out, "\t\t\tfbus_parcel_write_string(req_resp, %s);\n", param_name);
293					g_string_append_printf(params_free, "\t\t\tFTK_FREE(%s);\n", param_name);
294				}
295				else
296				{
297					g_string_append_printf(params_out, "\t\t\tfbus_parcel_write_data(req_resp, &%s, sizeof(%s));\n", 
298						param_name, param_name);
299				}
300			}
301
302			if(attr == IDL_PARAM_IN)
303			{
304				if(strcmp(type.org_name, "int") == 0)
305				{
306					g_string_append_printf(params_in, "\t%s = fbus_parcel_get_int(req_resp);\n", param_name);
307				}
308				else if(strcmp(type.org_name, "String") == 0)
309				{
310					g_string_append_printf(params_in, "\t%s = fbus_parcel_get_string(req_resp);\n", param_name);
311				}
312				else
313				{
314					g_string_append_printf(params_in, "\t%s = (%s)fbus_parcel_get_data(req_resp, sizeof(%s));\n", 
315						param_name, type.name, param_name);
316				}
317			}
318
319			if(iter.next == NULL)
320			{
321				break;
322			}
323		}
324	}
325	coder_name_to_lower(func_name, lower_func_name);
326	snprintf(req_coder_name, sizeof(req_coder_name)-1, "%s_%s", priv->interface_lower, lower_func_name);
327	coder_to_upper(req_coder_name);
328	g_string_append_printf(priv->func_dispatch, "\t\tcase %s:\n", req_coder_name);
329	g_string_append_printf(priv->func_dispatch, "\t\t{\n");
330	g_string_append_printf(priv->func_dispatch, "\t\t\t%s_marshal_%s(thiz, req_resp);\n",
331		priv->interface_lower, lower_func_name);
332	g_string_append_printf(priv->func_dispatch, "\t\t\tbreak;\n");
333	g_string_append_printf(priv->func_dispatch, "\t\t}\n");
334	g_string_append_printf(priv->func_empty, "static Ret %s_marshal_%s(FBusService* thiz, FBusParcel* req_resp)\n{\n", 
335		priv->interface_lower, lower_func_name);
336	g_string_append_printf(priv->func_empty, "%s\n", params_decls->str);
337	g_string_append_printf(priv->func_empty, "\tRet ret = RET_FAIL;\n");
338	g_string_append_printf(priv->func_empty, "\tDECL_PRIV(thiz, priv);\n");
339	g_string_append_printf(priv->func_empty,  
340		"	return_val_if_fail(priv != NULL && priv->impl != NULL && req_resp != NULL, RET_FAIL);\n\n");
341	g_string_append_printf(priv->func_empty, "%s\n", params_in->str);
342	g_string_append_printf(priv->func_empty, "\tif((ret = %s_%s(priv->impl%s)) == RET_OK)\n",
343		priv->interface_lower, lower_func_name, params_call->str);
344	g_string_append_printf(priv->func_empty, "\t{\n");
345	g_string_append_printf(priv->func_empty, "\t\tfbus_parcel_reset(req_resp);\n");
346	g_string_append_printf(priv->func_empty, "\t\tfbus_parcel_write_int(req_resp, ret);\n");
347	if(params_out->str != NULL && strlen(params_out->str) > 0)
348	{
349		g_string_append_printf(priv->func_empty, "\t\tif(ret == RET_OK)\n");
350		g_string_append_printf(priv->func_empty, "\t\t{\n");
351		g_string_append_printf(priv->func_empty, "%s", params_out->str);
352		g_string_append_printf(priv->func_empty, "%s", params_free->str);
353		g_string_append_printf(priv->func_empty, "\t\t}\n");
354	}
355	g_string_append_printf(priv->func_empty, "\t}\n\n");
356	g_string_append_printf(priv->func_empty, "\treturn ret;\n");
357	g_string_append_printf(priv->func_empty, "}\n\n");
358	
359	g_string_append_printf(priv->func_create, "		thiz->%s = %s_marshal_%s;\n",
360		lower_func_name, priv->interface_lower, lower_func_name);
361
362	g_string_free(params_list, 1);
363	g_string_free(params_in, 1);
364	g_string_free(params_out, 1);
365	g_string_free(params_call, 1);
366	g_string_free(params_decls, 1);
367	g_string_free(params_free, 1);
368
369	return TRUE;
370}
371
372static gboolean coder_service_on_const(Coder* thiz, struct _IDL_CONST_DCL c)
373{
374	return TRUE;
375}
376
377static gboolean coder_service_on_struct(Coder* thiz, struct _IDL_TYPE_STRUCT s)
378{
379	return TRUE;
380}
381
382static gboolean coder_service_on_enum(Coder* thiz, struct _IDL_TYPE_ENUM e)
383{
384	return TRUE;
385}
386
387static gboolean coder_service_on_union(Coder* thiz, struct _IDL_TYPE_UNION u)
388{
389	return TRUE;
390}
391
392static void coder_service_destroy(Coder* thiz)
393{
394	if(thiz != NULL)
395	{
396		PrivInfo* priv = (PrivInfo*)thiz->priv;
397		
398		coder_service_end_interface(thiz);
399		g_free(priv->name);
400		g_free(priv->lower_name);
401		g_free(thiz);
402	}
403
404	return;
405}
406
407Coder* coder_service_create(const char* name)
408{
409	Coder* thiz = g_malloc0(sizeof(Coder) + sizeof(PrivInfo));
410
411	if(thiz != NULL)
412	{
413		PrivInfo* priv = (PrivInfo*)thiz->priv;
414		
415		priv->name = g_strdup(name);
416		priv->lower_name = g_strdup(name);
417		coder_to_lower(priv->lower_name);
418		thiz->on_interface = coder_service_on_interface;
419		thiz->on_function  = coder_service_on_function;
420		thiz->on_const     = coder_service_on_const;
421		thiz->on_enum      = coder_service_on_enum;
422		thiz->on_struct    = coder_service_on_struct;
423		thiz->on_union     = coder_service_on_union;
424		thiz->destroy      = coder_service_destroy;
425	}
426
427	return thiz;
428}