PageRenderTime 46ms CodeModel.GetById 25ms app.highlight 18ms RepoModel.GetById 1ms app.codeStats 0ms

/services/fconf/fconf_service.c

http://ftk.googlecode.com/
C | 328 lines | 246 code | 53 blank | 29 comment | 63 complexity | 4a202b22bb7370f7ad3bf8d536dbf9e8 MD5 | raw file
  1/*
  2 * File: fconf_service.c
  3 * Author:  Li XianJing <xianjimli@hotmail.com>
  4 * Brief:   FConf Service.
  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-08-01 Li XianJing <xianjimli@hotmail.com> created
 29 *
 30 */
 31
 32#include "fconf.h"
 33#include "fconf_xml.h"
 34#include "fconf_share.h"
 35#include "ftk_globals.h"
 36#include "ftk_main_loop.h"
 37#include "fconf_service.h"
 38#include "ftk_source_timer.h"
 39
 40typedef struct _PrivInfo
 41{
 42	FConf* impl;
 43	int client_id;
 44	int peer_id; /*the port in client side*/
 45	FBusParcel* parcel;
 46	FtkSource* timer_save;
 47}PrivInfo;
 48
 49static Ret fconf_marshal_lock(FBusService* thiz, FBusParcel* req_resp)
 50{
 51	Ret ret = RET_FAIL;
 52	DECL_PRIV(thiz, priv);
 53	return_val_if_fail(priv != NULL && priv->impl != NULL && req_resp != NULL, RET_FAIL);
 54
 55	if((ret = fconf_lock(priv->impl)) == RET_OK)
 56	{
 57		fbus_parcel_reset(req_resp);
 58		fbus_parcel_write_int(req_resp, ret);
 59	}
 60
 61	return ret;
 62}
 63
 64static Ret fconf_marshal_unlock(FBusService* thiz, FBusParcel* req_resp)
 65{
 66	Ret ret = RET_FAIL;
 67	DECL_PRIV(thiz, priv);
 68	return_val_if_fail(priv != NULL && priv->impl != NULL && req_resp != NULL, RET_FAIL);
 69
 70	if((ret = fconf_unlock(priv->impl)) == RET_OK)
 71	{
 72		fbus_parcel_reset(req_resp);
 73		fbus_parcel_write_int(req_resp, ret);
 74	}
 75
 76	return ret;
 77}
 78
 79static Ret fconf_marshal_remove(FBusService* thiz, FBusParcel* req_resp)
 80{
 81	const char* xpath = {0};
 82
 83	Ret ret = RET_FAIL;
 84	DECL_PRIV(thiz, priv);
 85	return_val_if_fail(priv != NULL && priv->impl != NULL && req_resp != NULL, RET_FAIL);
 86
 87	xpath = fbus_parcel_get_string(req_resp);
 88
 89	if((ret = fconf_remove(priv->impl, xpath)) == RET_OK)
 90	{
 91		fbus_parcel_reset(req_resp);
 92		fbus_parcel_write_int(req_resp, ret);
 93	}
 94
 95	return ret;
 96}
 97
 98static Ret fconf_marshal_set(FBusService* thiz, FBusParcel* req_resp)
 99{
100	const char* xpath = {0};
101	const char* value = {0};
102
103	Ret ret = RET_FAIL;
104	DECL_PRIV(thiz, priv);
105	return_val_if_fail(priv != NULL && priv->impl != NULL && req_resp != NULL, RET_FAIL);
106
107	xpath = fbus_parcel_get_string(req_resp);
108	value = fbus_parcel_get_string(req_resp);
109
110	if((ret = fconf_set(priv->impl, xpath, value)) == RET_OK)
111	{
112		fbus_parcel_reset(req_resp);
113		fbus_parcel_write_int(req_resp, ret);
114	}
115
116	return ret;
117}
118
119static Ret fconf_marshal_get(FBusService* thiz, FBusParcel* req_resp)
120{
121	const char* xpath = {0};
122	char* value = {0};
123
124	Ret ret = RET_FAIL;
125	DECL_PRIV(thiz, priv);
126	return_val_if_fail(priv != NULL && priv->impl != NULL && req_resp != NULL, RET_FAIL);
127
128	xpath = fbus_parcel_get_string(req_resp);
129
130	if((ret = fconf_get(priv->impl, xpath, &value)) == RET_OK)
131	{
132		fbus_parcel_reset(req_resp);
133		fbus_parcel_write_int(req_resp, ret);
134		if(ret == RET_OK)
135		{
136			fbus_parcel_write_string(req_resp, value);
137		}
138	}
139
140	return ret;
141}
142
143static Ret fconf_marshal_get_child_count(FBusService* thiz, FBusParcel* req_resp)
144{
145	const char* xpath = {0};
146	int count = {0};
147
148	Ret ret = RET_FAIL;
149	DECL_PRIV(thiz, priv);
150	return_val_if_fail(priv != NULL && priv->impl != NULL && req_resp != NULL, RET_FAIL);
151
152	xpath = fbus_parcel_get_string(req_resp);
153
154	if((ret = fconf_get_child_count(priv->impl, xpath, &count)) == RET_OK)
155	{
156		fbus_parcel_reset(req_resp);
157		fbus_parcel_write_int(req_resp, ret);
158		if(ret == RET_OK)
159		{
160			fbus_parcel_write_int(req_resp, count);
161		}
162	}
163
164	return ret;
165}
166
167static Ret fconf_marshal_get_child(FBusService* thiz, FBusParcel* req_resp)
168{
169	const char* xpath = {0};
170	int index = {0};
171	char* child = {0};
172
173	Ret ret = RET_FAIL;
174	DECL_PRIV(thiz, priv);
175	return_val_if_fail(priv != NULL && priv->impl != NULL && req_resp != NULL, RET_FAIL);
176
177	xpath = fbus_parcel_get_string(req_resp);
178	index = fbus_parcel_get_int(req_resp);
179
180	if((ret = fconf_get_child(priv->impl, xpath, index, &child)) == RET_OK)
181	{
182		fbus_parcel_reset(req_resp);
183		fbus_parcel_write_int(req_resp, ret);
184		if(ret == RET_OK)
185		{
186			fbus_parcel_write_string(req_resp, child);
187		}
188	}
189
190	return ret;
191}
192
193static const char* fconf_service_get_name(FBusService* thiz)
194{
195	return FBUS_SERVICE_FCONF;
196}
197
198static Ret fconf_service_on_client_connect(FBusService* thiz, int client_id)
199{
200	return RET_OK;
201}
202
203static Ret fconf_service_on_client_disconnect(FBusService* thiz, int client_id)
204{
205	return RET_OK;
206}
207
208static Ret fconf_service_handle_request(FBusService* thiz, int client_id, FBusParcel* req_resp)
209{
210	DECL_PRIV(thiz, priv);
211	int req_code = fbus_parcel_get_int(req_resp);
212	
213	priv->client_id = client_id;
214	switch(req_code)
215	{
216		case FCONF_LOCK:
217		{
218			fconf_marshal_lock(thiz, req_resp);
219			break;
220		}
221		case FCONF_UNLOCK:
222		{
223			fconf_marshal_unlock(thiz, req_resp);
224			break;
225		}
226		case FCONF_REMOVE:
227		{
228			fconf_marshal_remove(thiz, req_resp);
229			break;
230		}
231		case FCONF_SET:
232		{
233			fconf_marshal_set(thiz, req_resp);
234			break;
235		}
236		case FCONF_GET:
237		{
238			fconf_marshal_get(thiz, req_resp);
239			break;
240		}
241		case FCONF_GET_CHILD_COUNT:
242		{
243			fconf_marshal_get_child_count(thiz, req_resp);
244			break;
245		}
246		case FCONF_GET_CHILD:
247		{
248			fconf_marshal_get_child(thiz, req_resp);
249			break;
250		}
251		default:break;
252	}
253
254	if(fconf_xml_is_dirty(priv->impl) && priv->timer_save->ref < 2)
255	{
256		ftk_logd("%s: timer save %d\n", __func__, priv->timer_save->ref);
257		ftk_source_ref(priv->timer_save);
258		ftk_main_loop_add_source(ftk_default_main_loop(), priv->timer_save);	
259	}
260
261	return RET_OK;
262}
263
264static void fconf_service_destroy(FBusService* thiz)
265{
266	if(thiz != NULL)
267	{
268		DECL_PRIV(thiz, priv);
269		ftk_source_disable(priv->timer_save);
270		ftk_source_unref(priv->timer_save);
271		fbus_parcel_destroy(priv->parcel);
272		fconf_destroy(priv->impl);
273		FTK_FREE(thiz);
274	}
275	return;
276}
277
278static Ret on_changed(void* ctx, int change_by_self, FConfChangeType type, const char* xpath, const char* value)
279{
280	FBusService* thiz = ctx;
281	DECL_PRIV(thiz, priv);
282
283	fbus_parcel_reset(priv->parcel);
284	fbus_parcel_write_int(priv->parcel, type);
285	fbus_parcel_write_string(priv->parcel, xpath);
286
287	if(value != NULL)
288	{
289		fbus_parcel_write_string(priv->parcel, value);
290	}
291	fbus_service_notify_all(thiz, priv->client_id, priv->parcel);
292	ftk_logd("%s: client_id=%d %d %d %s %s\n", __func__, priv->client_id, change_by_self, type, xpath, value);
293
294	return RET_OK;
295}
296
297static Ret timer_save_func(void* ctx)
298{
299	FBusService* thiz = ctx;
300	DECL_PRIV(thiz, priv);
301
302	fconf_xml_save(priv->impl);
303
304	return RET_REMOVE;
305}
306
307FBusService* fconf_service_create(void)
308{
309	FBusService* thiz = FTK_ZALLOC(sizeof(FBusService)+sizeof(PrivInfo));
310	if(thiz != NULL)
311	{
312		DECL_PRIV(thiz, priv);
313		priv->parcel = fbus_parcel_create(1024);
314		priv->timer_save = ftk_source_timer_create(10000, timer_save_func, thiz);
315		priv->impl = fconf_xml_create(DATA_DIR"/config");
316		thiz->get_name = fconf_service_get_name;
317		thiz->on_client_connect = fconf_service_on_client_connect;
318		thiz->on_client_disconnect = fconf_service_on_client_disconnect;
319		thiz->handle_request = fconf_service_handle_request;
320		thiz->destroy = fconf_service_destroy;
321		fbus_service_register(thiz);
322		fconf_reg_changed_notify(priv->impl, on_changed, thiz);
323	}
324
325	return thiz;
326}
327
328