/fbus/fbus_service_infos.c

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