PageRenderTime 305ms CodeModel.GetById 120ms app.highlight 76ms RepoModel.GetById 106ms app.codeStats 0ms

/fbus/fbus_service_infos.c

http://ftk.googlecode.com/
C | 341 lines | 256 code | 56 blank | 29 comment | 82 complexity | 2d05c3b4e14f4b2a089f908ec04cb9f1 MD5 | raw file
  1/*
  2 * File:    fbus_service_infos.c
  3 * Author:  Li XianJing <xianjimli@hotmail.com>
  4 * Brief:   FtkServiceInfo Manager.
  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-25 Li XianJing <xianjimli@hotmail.com> created
 29 *
 30 */
 31
 32#include "ftk_mmap.h"
 33#include "ftk_allocator.h"
 34#include "ftk_xml_parser.h"
 35#include "fbus_service_infos.h"
 36
 37#define FBUS_SERVICE_PORT_START FBUS_SERVICE_MANAGER_PORT + 1
 38
 39struct _FBusServiceInfos
 40{
 41	int port;
 42	size_t size;
 43	size_t capacity;
 44	FBusServiceInfo* service_infos;
 45};
 46
 47FBusServiceInfos* fbus_service_infos_create(int capacity)
 48{
 49	FBusServiceInfos* thiz = FTK_ZALLOC(sizeof(FBusServiceInfos));
 50	
 51	if(thiz != NULL)
 52	{
 53		capacity = capacity < 5 ? 5 : capacity;
 54		thiz->service_infos = FTK_ZALLOC(sizeof(FBusServiceInfo) * capacity);
 55		if(thiz->service_infos != NULL)
 56		{
 57			thiz->port = FBUS_SERVICE_PORT_START;
 58			thiz->capacity = capacity;
 59		}
 60		else
 61		{
 62			FTK_FREE(thiz);
 63		}
 64	}
 65
 66	return thiz;
 67}
 68
 69FBusServiceInfo*  fbus_service_infos_find(FBusServiceInfos* thiz, const char* name)
 70{
 71	size_t i = 0;
 72	return_val_if_fail(thiz != NULL && name != NULL, NULL);
 73
 74	for(i = 0; i < thiz->size; i++)
 75	{
 76		if(strcmp(name, thiz->service_infos[i].name) == 0)
 77		{
 78			return thiz->service_infos+i;
 79		}
 80	}
 81
 82	return NULL;
 83}
 84
 85Ret fbus_service_infos_get_nr(FBusServiceInfos* thiz)
 86{
 87	return_val_if_fail(thiz != NULL, 0);
 88
 89	return thiz->size;
 90}
 91
 92static Ret fbus_service_infos_extend(FBusServiceInfos* thiz, size_t capacity)
 93{
 94	return_val_if_fail(thiz != NULL && capacity > 0, RET_FAIL);
 95
 96	if(capacity > thiz->capacity)
 97	{
 98		capacity = capacity + (capacity >> 1);
 99		FBusServiceInfo* service_infos = FTK_REALLOC(thiz->service_infos, capacity*sizeof(FBusServiceInfo));
100		if(service_infos != NULL)
101		{
102			thiz->capacity = capacity;
103			thiz->service_infos = service_infos;
104			
105			return RET_OK;
106		}
107		else
108		{
109			return RET_FAIL;
110		}
111	}
112
113	return RET_OK;
114}
115
116Ret fbus_service_infos_add(FBusServiceInfos* thiz, FBusServiceInfo* service)
117{
118	return_val_if_fail(thiz != NULL && service != NULL, RET_FAIL);
119	return_val_if_fail(fbus_service_infos_extend(thiz, thiz->size+1) == RET_OK, RET_FAIL);
120
121	if(service->host[0] == '\0')
122	{
123		ftk_strncpy(service->host, FBUS_LOCALHOST, sizeof(service->host)-1);
124	}
125	service->port = thiz->port + thiz->size;
126	memcpy(thiz->service_infos+thiz->size, service, sizeof(FBusServiceInfo));
127	thiz->size++;
128
129	ftk_logd("add: port=%d name=%s exec=%s\n", service->port, service->name, service->exec);
130
131	return RET_OK;
132}
133
134FBusServiceInfo* fbus_service_infos_get(FBusServiceInfos* thiz, size_t index)
135{
136	return_val_if_fail(thiz != NULL && index < thiz->size, NULL);
137
138	return thiz->service_infos+index;
139}
140
141void fbus_service_infos_destroy(FBusServiceInfos* thiz)
142{
143	if(thiz != NULL)
144	{
145		FTK_FREE(thiz->service_infos);
146		FTK_FREE(thiz);
147	}
148}
149
150static int fbus_service_info_is_valid(FBusServiceInfo* service)
151{
152	return_val_if_fail(service != NULL, 0);
153
154	return (service->name[0] != '\0' && service->exec[0] != '\0');
155}
156
157typedef struct _BuilderInfo
158{
159	FBusServiceInfos* services;
160}BuilderInfo;
161
162static void fbus_service_info_builder_on_start(FtkXmlBuilder* thiz, const char* tag, const char** attrs)
163{
164	int i = 0;
165	FBusServiceInfo service = {0};
166	BuilderInfo* info = (BuilderInfo*)thiz->priv;
167	return_if_fail(thiz != NULL && tag != NULL && attrs != NULL);
168	
169	memset(&service, 0x00, sizeof(service));
170	for(i = 0; attrs[i] != NULL; i+=2)
171	{
172		const char* name = attrs[i];
173		const char* value = attrs[i+1];
174		if(strcmp(name, "name") == 0)
175		{
176			ftk_strncpy(service.name, value, sizeof(service.name)-1);
177		}
178		else if(strcmp(name, "exec") == 0)
179		{
180			ftk_strncpy(service.exec, value, sizeof(service.exec)-1);
181		}
182		else if(strcmp(name, "start_type") == 0)
183		{
184			if(strcmp(value, "on_load") == 0)
185			{
186				service.start_type = FBUS_SERVICE_START_ON_LOAD;
187			}
188			else if(strcmp(value, "on_request") == 0)
189			{
190				service.start_type = FBUS_SERVICE_START_ON_REQUEST;
191			}
192			else
193			{
194				service.start_type = FBUS_SERVICE_START_NONE;
195			}
196		}
197		else if(strcmp(name, "life_cycle") == 0)
198		{
199			if(strcmp(value, "once") == 0)
200			{
201				service.life_cycle = FBUS_SERVICE_RUN_ONCE;
202			}
203			else
204			{
205				service.life_cycle = FBUS_SERVICE_RUN_FOREVER;
206			}
207		}
208	}
209
210	return_if_fail(fbus_service_info_is_valid(&service));
211
212	fbus_service_infos_add(info->services, &service);
213
214	return;
215}
216
217static void fbus_service_info_builder_on_end(FtkXmlBuilder* thiz, const char* tag)
218{
219	return;
220}
221
222static void fbus_service_info_builder_on_text(FtkXmlBuilder* thiz, const char* text, size_t length)
223{
224	return;
225}
226
227static void fbus_service_info_builder_destroy(FtkXmlBuilder* thiz)
228{
229	if(thiz != NULL)
230	{
231		FTK_ZFREE(thiz, sizeof(FtkXmlBuilder) + sizeof(BuilderInfo));
232	}
233
234	return;
235}
236
237static FtkXmlBuilder* fbus_service_info_builder_create(FBusServiceInfos* services)
238{
239	FtkXmlBuilder* thiz = FTK_ZALLOC(sizeof(FtkXmlBuilder) + sizeof(BuilderInfo));
240
241	if(thiz != NULL)
242	{
243		BuilderInfo* priv      = (BuilderInfo* )thiz->priv;
244		priv->services		   = services;
245		thiz->on_start_element = fbus_service_info_builder_on_start;
246		thiz->on_end_element   = fbus_service_info_builder_on_end;
247		thiz->on_text		   = fbus_service_info_builder_on_text;
248		thiz->destroy		   = fbus_service_info_builder_destroy;
249	}
250
251	return thiz;
252}
253
254static Ret  fbus_service_info_parse(FBusServiceInfos* services, const char* xml, size_t length)
255{
256    FtkXmlParser* parser = NULL;
257    FtkXmlBuilder* builder = NULL;
258    return_val_if_fail(xml != NULL, RET_FAIL);
259
260    parser  = ftk_xml_parser_create();
261    return_val_if_fail(parser != NULL, RET_FAIL);
262
263    builder = fbus_service_info_builder_create(services);
264    if(builder != NULL)
265    {
266        ftk_xml_parser_set_builder(parser, builder);
267        ftk_xml_parser_parse(parser, xml, length);
268    }
269    ftk_xml_builder_destroy(builder);
270    ftk_xml_parser_destroy(parser);
271
272    return RET_OK;
273}
274
275Ret  fbus_service_infos_load_file(FBusServiceInfos* services, const char* filename)
276{
277    FtkMmap* m = NULL;
278    Ret ret = RET_FAIL;
279    return_val_if_fail(services != NULL && filename != NULL, RET_FAIL);
280
281    m = ftk_mmap_create(filename, 0, -1);
282    return_val_if_fail(m != NULL, RET_FAIL);
283
284    ret = fbus_service_info_parse(services, ftk_mmap_data(m), ftk_mmap_length(m));
285    ftk_mmap_destroy(m);
286
287    return ret;
288}
289
290Ret  fbus_service_infos_load_dir(FBusServiceInfos* services, const char* path)
291{
292    DIR* dir = NULL;
293    struct dirent* iter = NULL;
294    char filename[FTK_MAX_PATH+1] = {0};
295    return_val_if_fail(services != NULL && path != NULL, RET_FAIL);
296    
297	dir = opendir(path);
298    return_val_if_fail(dir != NULL, RET_FAIL);
299
300    while((iter = readdir(dir)) != NULL)
301    {
302        if(iter->d_name[0] == '.') continue;
303        if(strstr(iter->d_name, ".service") == NULL) continue;
304
305        ftk_snprintf(filename, sizeof(filename)-1, "%s/%s", path, iter->d_name);
306        fbus_service_infos_load_file(services, filename);
307    }
308    closedir(dir);
309
310    return RET_OK;
311}
312
313
314#ifdef FBUS_SERVICE_INFOS_TEST
315#include <assert.h>
316#include "ftk_allocator_default.h"
317
318int main(int argc, char* argv[])
319{
320	int i = 0;
321	FBusServiceInfo service = {0};
322	FBusServiceInfos* thiz = NULL;
323#ifndef USE_STD_MALLOC
324	ftk_set_allocator((ftk_allocator_default_create()));
325#endif
326	thiz = fbus_service_infos_create(0);
327	assert(fbus_service_infos_get_nr(thiz) == 0);
328
329	for(i = 0; i < 32; i++)
330	{
331		ftk_snprintf(service.name, sizeof(service.name)-1, "name%4d", i);
332		assert(fbus_service_infos_add(thiz, &service) == RET_OK);
333		assert(strcmp(fbus_service_infos_find(thiz, service.name)->name, service.name) == 0);
334		assert(strcmp(fbus_service_infos_get(thiz, i)->name, service.name) == 0);
335		assert(fbus_service_infos_get_nr(thiz) == (i+1));
336	}
337	fbus_service_infos_destroy(thiz);
338
339	return 0;
340}
341#endif