xavp.c 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457
  1. /*
  2. * $Id$
  3. *
  4. * Copyright (C) 2009 Daniel-Constantin Mierla (asipto.com)
  5. *
  6. * Permission to use, copy, modify, and distribute this software for any
  7. * purpose with or without fee is hereby granted, provided that the above
  8. * copyright notice and this permission notice appear in all copies.
  9. *
  10. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  11. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  12. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  13. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  14. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  15. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  16. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  17. */
  18. /*
  19. * History:
  20. * --------
  21. * 2009-05-20 created by daniel
  22. */
  23. #ifdef WITH_XAVP
  24. #include <stdio.h>
  25. #include <string.h>
  26. #include "mem/shm_mem.h"
  27. #include "dprint.h"
  28. #include "hashes.h"
  29. #include "xavp.h"
  30. /*! XAVP list head */
  31. static sr_xavp_t *_xavp_list_head = 0;
  32. /*! Pointer to XAVP current list */
  33. static sr_xavp_t **_xavp_list_crt = &_xavp_list_head;
  34. /*! Helper functions */
  35. static sr_xavp_t *xavp_get_internal(str *name, sr_xavp_t **list, int idx, sr_xavp_t **prv);
  36. static int xavp_rm_internal(str *name, sr_xavp_t **head, int idx);
  37. void xavp_shm_free(void *p)
  38. {
  39. shm_free(p);
  40. }
  41. void xavp_shm_free_unsafe(void *p)
  42. {
  43. shm_free_unsafe(p);
  44. }
  45. void xavp_free(sr_xavp_t *xa)
  46. {
  47. if(xa->val.type == SR_XTYPE_DATA) {
  48. if(xa->val.v.data!=NULL && xa->val.v.data->pfree!=NULL) {
  49. xa->val.v.data->pfree(xa->val.v.data->p, xavp_shm_free);
  50. shm_free(xa->val.v.data);
  51. }
  52. } else if(xa->val.type == SR_XTYPE_XAVP) {
  53. xavp_destroy_list(&xa->val.v.xavp);
  54. }
  55. shm_free(xa);
  56. }
  57. void xavp_free_unsafe(sr_xavp_t *xa)
  58. {
  59. if(xa->val.type == SR_XTYPE_DATA) {
  60. if(xa->val.v.data!=NULL && xa->val.v.data->pfree!=NULL) {
  61. xa->val.v.data->pfree(xa->val.v.data->p, xavp_shm_free_unsafe);
  62. shm_free_unsafe(xa->val.v.data);
  63. }
  64. } else if(xa->val.type == SR_XTYPE_XAVP) {
  65. xavp_destroy_list_unsafe(&xa->val.v.xavp);
  66. }
  67. shm_free_unsafe(xa);
  68. }
  69. static sr_xavp_t *xavp_new_value(str *name, sr_xval_t *val)
  70. {
  71. sr_xavp_t *avp;
  72. int size;
  73. unsigned int id;
  74. if(name==NULL || name->s==NULL || val==NULL)
  75. return NULL;
  76. id = get_hash1_raw(name->s, name->len);
  77. size = sizeof(sr_xavp_t) + name->len + 1;
  78. if(val->type == SR_XTYPE_STR)
  79. size += val->v.s.len + 1;
  80. avp = (sr_xavp_t*)shm_malloc(size);
  81. if(avp==NULL)
  82. return NULL;
  83. memset(avp, 0, size);
  84. avp->id = id;
  85. avp->name.s = (char*)avp + sizeof(sr_xavp_t);
  86. memcpy(avp->name.s, name->s, name->len);
  87. avp->name.s[name->len] = '\0';
  88. avp->name.len = name->len;
  89. memcpy(&avp->val, val, sizeof(sr_xval_t));
  90. if(val->type == SR_XTYPE_STR)
  91. {
  92. avp->val.v.s.s = avp->name.s + avp->name.len + 1;
  93. memcpy(avp->val.v.s.s, val->v.s.s, val->v.s.len);
  94. avp->val.v.s.s[val->v.s.len] = '\0';
  95. avp->val.v.s.len = val->v.s.len;
  96. }
  97. return avp;
  98. }
  99. sr_xavp_t *xavp_add_value(str *name, sr_xval_t *val, sr_xavp_t **list)
  100. {
  101. sr_xavp_t *avp=0;
  102. avp = xavp_new_value(name, val);
  103. if (avp==NULL)
  104. return NULL;
  105. /* Prepend new value to the list */
  106. if(list) {
  107. avp->next = *list;
  108. *list = avp;
  109. } else {
  110. avp->next = *_xavp_list_crt;
  111. *_xavp_list_crt = avp;
  112. }
  113. return avp;
  114. }
  115. sr_xavp_t *xavp_set_value(str *name, int idx, sr_xval_t *val, sr_xavp_t **list)
  116. {
  117. sr_xavp_t *avp;
  118. sr_xavp_t *cur;
  119. sr_xavp_t *prv=0;
  120. if(val==NULL)
  121. return NULL;
  122. /* Find the current value */
  123. cur = xavp_get_internal(name, list, idx, &prv);
  124. if(cur==NULL)
  125. return NULL;
  126. avp = xavp_new_value(name, val);
  127. if (avp==NULL)
  128. return NULL;
  129. /* Replace the current value with the new */
  130. avp->next = cur->next;
  131. if(prv)
  132. prv->next = avp;
  133. else if(list)
  134. *list = avp;
  135. else
  136. *_xavp_list_crt = avp;
  137. xavp_free(cur);
  138. return avp;
  139. }
  140. static sr_xavp_t *xavp_get_internal(str *name, sr_xavp_t **list, int idx, sr_xavp_t **prv)
  141. {
  142. sr_xavp_t *avp;
  143. unsigned int id;
  144. int n = 0;
  145. if(name==NULL || name->s==NULL)
  146. return NULL;
  147. id = get_hash1_raw(name->s, name->len);
  148. if(list && *list)
  149. avp = *list;
  150. else
  151. avp = *_xavp_list_crt;
  152. while(avp)
  153. {
  154. if(avp->id==id && avp->name.len==name->len
  155. && strncmp(avp->name.s, name->s, name->len)==0)
  156. {
  157. if(idx==n)
  158. return avp;
  159. n++;
  160. }
  161. if(prv)
  162. *prv = avp;
  163. avp = avp->next;
  164. }
  165. return NULL;
  166. }
  167. sr_xavp_t *xavp_get(str *name, sr_xavp_t *start)
  168. {
  169. return xavp_get_internal(name, (start)?&start:NULL, 0, NULL);
  170. }
  171. sr_xavp_t *xavp_get_by_index(str *name, int idx, sr_xavp_t **start)
  172. {
  173. return xavp_get_internal(name, start, idx, NULL);
  174. }
  175. sr_xavp_t *xavp_get_next(sr_xavp_t *start)
  176. {
  177. sr_xavp_t *avp;
  178. if(start==NULL)
  179. return NULL;
  180. avp = start->next;
  181. while(avp)
  182. {
  183. if(avp->id==start->id && avp->name.len==start->name.len
  184. && strncmp(avp->name.s, start->name.s, start->name.len)==0)
  185. return avp;
  186. avp=avp->next;
  187. }
  188. return NULL;
  189. }
  190. int xavp_rm(sr_xavp_t *xa, sr_xavp_t **head)
  191. {
  192. sr_xavp_t *avp;
  193. sr_xavp_t *prv=0;
  194. if(head!=NULL)
  195. avp = *head;
  196. else
  197. avp=*_xavp_list_crt;
  198. while(avp)
  199. {
  200. if(avp==xa)
  201. {
  202. if(prv)
  203. prv->next=avp->next;
  204. else if(head!=NULL)
  205. *head = avp->next;
  206. else
  207. *_xavp_list_crt = avp->next;
  208. xavp_free(avp);
  209. return 1;
  210. }
  211. prv=avp; avp=avp->next;
  212. }
  213. return 0;
  214. }
  215. /* Remove xavps
  216. * idx: <0 remove all xavps with the same name
  217. * >=0 remove only the specified index xavp
  218. * Returns number of xavps that were deleted
  219. */
  220. static int xavp_rm_internal(str *name, sr_xavp_t **head, int idx)
  221. {
  222. sr_xavp_t *avp;
  223. sr_xavp_t *foo;
  224. sr_xavp_t *prv=0;
  225. unsigned int id;
  226. int n=0;
  227. int count=0;
  228. if(name==NULL || name->s==NULL)
  229. return 0;
  230. id = get_hash1_raw(name->s, name->len);
  231. if(head!=NULL)
  232. avp = *head;
  233. else
  234. avp = *_xavp_list_crt;
  235. while(avp)
  236. {
  237. foo = avp;
  238. avp=avp->next;
  239. if(foo->id==id && foo->name.len==name->len
  240. && strncmp(foo->name.s, name->s, name->len)==0)
  241. {
  242. if(idx<0 || idx==n)
  243. {
  244. if(prv!=NULL)
  245. prv->next=foo->next;
  246. else if(head!=NULL)
  247. *head = foo->next;
  248. else
  249. *_xavp_list_crt = foo->next;
  250. xavp_free(foo);
  251. if(idx>=0)
  252. return 1;
  253. count++;
  254. }
  255. n++;
  256. } else {
  257. prv = foo;
  258. }
  259. }
  260. return count;
  261. }
  262. int xavp_rm_by_name(str *name, int all, sr_xavp_t **head)
  263. {
  264. return xavp_rm_internal(name, head, -1*all);
  265. }
  266. int xavp_rm_by_index(str *name, int idx, sr_xavp_t **head)
  267. {
  268. if (idx<0)
  269. return 0;
  270. return xavp_rm_internal(name, head, idx);
  271. }
  272. int xavp_count(str *name, sr_xavp_t **start)
  273. {
  274. sr_xavp_t *avp;
  275. unsigned int id;
  276. int n = 0;
  277. if(name==NULL || name->s==NULL)
  278. return -1;
  279. id = get_hash1_raw(name->s, name->len);
  280. if(start)
  281. avp = *start;
  282. else
  283. avp=*_xavp_list_crt;
  284. while(avp)
  285. {
  286. if(avp->id==id && avp->name.len==name->len
  287. && strncmp(avp->name.s, name->s, name->len)==0)
  288. {
  289. n++;
  290. }
  291. avp=avp->next;
  292. }
  293. return n;
  294. }
  295. void xavp_destroy_list_unsafe(sr_xavp_t **head)
  296. {
  297. sr_xavp_t *avp, *foo;
  298. avp = *head;
  299. while(avp)
  300. {
  301. foo = avp;
  302. avp = avp->next;
  303. xavp_free_unsafe(foo);
  304. }
  305. *head = 0;
  306. }
  307. void xavp_destroy_list(sr_xavp_t **head)
  308. {
  309. sr_xavp_t *avp, *foo;
  310. LM_DBG("destroying xavp list %p\n", *head);
  311. avp = *head;
  312. while(avp)
  313. {
  314. foo = avp;
  315. avp = avp->next;
  316. xavp_free(foo);
  317. }
  318. *head = 0;
  319. }
  320. void xavp_reset_list(void)
  321. {
  322. assert(_xavp_list_crt!=0 );
  323. if (_xavp_list_crt!=&_xavp_list_head)
  324. _xavp_list_crt=&_xavp_list_head;
  325. xavp_destroy_list(_xavp_list_crt);
  326. }
  327. sr_xavp_t **xavp_set_list(sr_xavp_t **head)
  328. {
  329. sr_xavp_t **avp;
  330. assert(_xavp_list_crt!=0);
  331. avp = _xavp_list_crt;
  332. _xavp_list_crt = head;
  333. return avp;
  334. }
  335. sr_xavp_t **xavp_get_crt_list(void)
  336. {
  337. assert(_xavp_list_crt!=0);
  338. return _xavp_list_crt;
  339. }
  340. void xavp_print_list_content(sr_xavp_t **head, int level)
  341. {
  342. sr_xavp_t *avp=0;
  343. sr_xavp_t *start=0;
  344. if(head!=NULL)
  345. start = *head;
  346. else
  347. start=*_xavp_list_crt;
  348. LM_INFO("+++++ start XAVP list: %p (level=%d)\n", start, level);
  349. avp = start;
  350. while(avp)
  351. {
  352. LM_INFO(" *** XAVP name: %s\n", avp->name.s);
  353. LM_INFO(" XAVP id: %u\n", avp->id);
  354. LM_INFO(" XAVP value type: %d\n", avp->val.type);
  355. switch(avp->val.type) {
  356. case SR_XTYPE_NULL:
  357. LM_INFO(" XAVP value: <null>\n");
  358. break;
  359. case SR_XTYPE_INT:
  360. LM_INFO(" XAVP value: %d\n", avp->val.v.i);
  361. break;
  362. case SR_XTYPE_STR:
  363. LM_INFO(" XAVP value: %s\n", avp->val.v.s.s);
  364. break;
  365. case SR_XTYPE_TIME:
  366. LM_INFO(" XAVP value: %lu\n",
  367. (long unsigned int)avp->val.v.t);
  368. break;
  369. case SR_XTYPE_LONG:
  370. LM_INFO(" XAVP value: %ld\n", avp->val.v.l);
  371. break;
  372. case SR_XTYPE_LLONG:
  373. LM_INFO(" XAVP value: %lld\n", avp->val.v.ll);
  374. break;
  375. case SR_XTYPE_XAVP:
  376. LM_INFO(" XAVP value: <xavp:%p>\n", avp->val.v.xavp);
  377. xavp_print_list_content(&avp->val.v.xavp, level+1);
  378. break;
  379. case SR_XTYPE_DATA:
  380. LM_INFO(" XAVP value: <data:%p>\n", avp->val.v.data);
  381. break;
  382. }
  383. avp = avp->next;
  384. }
  385. LM_INFO("----- end XAVP list: %p (level=%d)\n", start, level);
  386. }
  387. void xavp_print_list(sr_xavp_t **head)
  388. {
  389. xavp_print_list_content(head, 0);
  390. }
  391. #endif