Browse code

core: extended xavp api

- functions to add an avp last in a list or inserted at a specific
position, to extract an avp from top of the list

Daniel-Constantin Mierla authored on 24/12/2012 09:02:01
Showing 2 changed files
... ...
@@ -113,6 +113,56 @@ static sr_xavp_t *xavp_new_value(str *name, sr_xval_t *val)
113 113
 	return avp;
114 114
 }
115 115
 
116
+int xavp_add(sr_xavp_t *xavp, sr_xavp_t **list)
117
+{
118
+	if (xavp==NULL)
119
+		return -1;
120
+	/* Prepend new xavp to the list */
121
+	if(list) {
122
+		xavp->next = *list;
123
+		*list = xavp;
124
+	} else {
125
+		xavp->next = *_xavp_list_crt;
126
+		*_xavp_list_crt = xavp;
127
+	}
128
+
129
+	return 0;
130
+}
131
+
132
+int xavp_add_last(sr_xavp_t *xavp, sr_xavp_t **list)
133
+{
134
+	sr_xavp_t *prev;
135
+	sr_xavp_t *crt;
136
+
137
+	if (xavp==NULL)
138
+		return -1;
139
+
140
+	crt = xavp_get_internal(&xavp->name, list, 0, 0);
141
+
142
+	prev = NULL;
143
+
144
+	while(crt) {
145
+		prev = crt;
146
+		crt = xavp_get_next(prev);
147
+	}
148
+
149
+	if(prev==NULL) {
150
+		/* Prepend new xavp to the list */
151
+		if(list) {
152
+			xavp->next = *list;
153
+			*list = xavp;
154
+		} else {
155
+			xavp->next = *_xavp_list_crt;
156
+			*_xavp_list_crt = xavp;
157
+		}
158
+	} else {
159
+		xavp->next = prev->next;
160
+		prev->next = xavp;
161
+	}
162
+
163
+	return 0;
164
+}
165
+
116 166
 sr_xavp_t *xavp_add_value(str *name, sr_xval_t *val, sr_xavp_t **list)
117 167
 {
118 168
 	sr_xavp_t *avp=0;
... ...
@@ -454,4 +504,170 @@ void xavp_print_list(sr_xavp_t **head)
454 454
 {
455 455
 	xavp_print_list_content(head, 0);
456 456
 }
457
+
458
+/**
459
+ * clone the xavp without values that are custom data
460
+ * - only one list level is cloned, other sublists are ignored
461
+ */
462
+sr_xavp_t *xavp_clone_level_nodata(sr_xavp_t *xold)
463
+{
464
+	sr_xavp_t *xnew = NULL;
465
+	sr_xavp_t *navp = NULL;
466
+	sr_xavp_t *oavp = NULL;
467
+	sr_xavp_t *pavp = NULL;
468
+
469
+	if(xold == NULL)
470
+		return NULL;
471
+	if(xold->val.type==SR_XTYPE_DATA)
472
+	{
473
+		LM_INFO("xavp value type is 'data' - ignoring in clone\n");
474
+		return NULL;
475
+	}
476
+	xnew = xavp_new_value(&xold->name, &xold->val);
477
+	if(xnew==NULL)
478
+	{
479
+		LM_ERR("cannot create cloned root xavp\n");
480
+		return NULL;
481
+	}
482
+
483
+	if(xold->val.type!=SR_XTYPE_XAVP)
484
+		return xnew;
485
+
486
+	xnew->val.v.xavp = NULL;
487
+	oavp = xold->val.v.xavp;
488
+
489
+	while(oavp)
490
+	{
491
+		if(xold->val.type!=SR_XTYPE_DATA && xold->val.type!=SR_XTYPE_XAVP)
492
+		{
493
+			navp =  xavp_new_value(&oavp->name, &oavp->val);
494
+			if(navp==NULL)
495
+			{
496
+				if(xnew->val.v.xavp == NULL)
497
+				{
498
+					shm_free(xnew);
499
+					return NULL;
500
+				} else {
501
+					xavp_destroy_list(&navp);
502
+					return NULL;
503
+				}
504
+			}
505
+			if(xnew->val.v.xavp == NULL)
506
+			{
507
+				/* link to val in head xavp */
508
+				xnew->val.v.xavp = navp;
509
+				pavp = navp;
510
+			} else {
511
+				/* link to prev xavp in the list */
512
+				pavp->next = navp;
513
+			}
514
+		}
515
+		oavp = oavp->next;
516
+	}
517
+
518
+	if(xnew->val.v.xavp == NULL)
519
+	{
520
+		shm_free(xnew);
521
+		return NULL;
522
+	}
523
+
524
+	return xnew;
525
+}
526
+
527
+int xavp_insert(sr_xavp_t *xavp, int idx, sr_xavp_t **list)
528
+{
529
+	sr_xavp_t *crt = 0;
530
+	sr_xavp_t *fst = 0;
531
+	sr_xavp_t *lst = 0;
532
+	sr_xval_t val;
533
+	int n = 0;
534
+	int i = 0;
535
+
536
+	if(idx==0)
537
+		return xavp_add(xavp, list);
538
+
539
+	crt = xavp_get_internal(&xavp->name, list, 0, 0);
540
+	while(crt!=NULL && n<idx) {
541
+		lst = crt;
542
+		n++;
543
+		crt = xavp_get_next(lst);
544
+	}
545
+	memset(&val, 0, sizeof(sr_xval_t));
546
+	val.type = SR_XTYPE_NULL;
547
+	for(i=0; i<idx-n; i++) {
548
+		crt = xavp_add_value(&xavp->name, &val, list);
549
+		if(crt==NULL)
550
+			return -1;
551
+		if(fst==NULL)
552
+			fst = crt;
553
+		if(lst==NULL) {
554
+			if(xavp_add(crt, list)<0)
555
+				return -1;
556
+		} else {
557
+			crt->next = lst->next;
558
+			lst->next = crt;
559
+		}
560
+	}
561
+
562
+	if(fst==NULL) {
563
+		return xavp_add(xavp, list);
564
+	} else {
565
+		xavp->next = fst->next;
566
+		fst->next = xavp;
567
+	}
568
+
569
+	return 0;
570
+}
571
+
572
+sr_xavp_t *xavp_extract(str *name, sr_xavp_t **list)
573
+{
574
+	sr_xavp_t *avp = 0;
575
+	sr_xavp_t *foo;
576
+	sr_xavp_t *prv = 0;
577
+	unsigned int id;
578
+
579
+	if(name==NULL || name->s==NULL) {
580
+		if(list!=NULL) {
581
+			avp = *list;
582
+			if(avp!=NULL) {
583
+				*list = avp->next;
584
+				avp->next = NULL;
585
+			}
586
+		} else {
587
+			avp = *_xavp_list_crt;
588
+			if(avp!=NULL) {
589
+				*_xavp_list_crt = avp->next;
590
+				avp->next = NULL;
591
+			}
592
+		}
593
+		
594
+		return avp;
595
+	}
596
+
597
+	id = get_hash1_raw(name->s, name->len);
598
+	if(list!=NULL)
599
+		avp = *list;
600
+	else
601
+		avp = *_xavp_list_crt;
602
+	while(avp)
603
+	{
604
+		foo = avp;
605
+		avp=avp->next;
606
+		if(foo->id==id && foo->name.len==name->len
607
+				&& strncmp(foo->name.s, name->s, name->len)==0)
608
+		{
609
+			if(prv!=NULL)
610
+				prv->next=foo->next;
611
+			else if(list!=NULL)
612
+				*list = foo->next;
613
+			else
614
+				*_xavp_list_crt = foo->next;
615
+			foo->next = NULL;
616
+			return foo;
617
+		} else {
618
+			prv = foo;
619
+		}
620
+	}
621
+	return NULL;
622
+}
457 623
 #endif
... ...
@@ -78,6 +78,8 @@ typedef struct _sr_xavp {
78 78
 int xavp_init_head(void);
79 79
 void avpx_free(sr_xavp_t *xa);
80 80
 
81
+int xavp_add(sr_xavp_t *xavp, sr_xavp_t **list);
82
+int xavp_add_last(sr_xavp_t *xavp, sr_xavp_t **list);
81 83
 sr_xavp_t *xavp_add_value(str *name, sr_xval_t *val, sr_xavp_t **list);
82 84
 sr_xavp_t *xavp_set_value(str *name, int idx, sr_xval_t *val, sr_xavp_t **list);
83 85
 sr_xavp_t *xavp_get(str *name, sr_xavp_t *start);
... ...
@@ -93,7 +95,12 @@ void xavp_reset_list(void);
93 93
 sr_xavp_t **xavp_set_list(sr_xavp_t **head);
94 94
 sr_xavp_t **xavp_get_crt_list(void);
95 95
 
96
+int xavp_insert(sr_xavp_t *xavp, int idx, sr_xavp_t **list);
97
+sr_xavp_t *xavp_extract(str *name, sr_xavp_t **list);
98
+
96 99
 void xavp_print_list(sr_xavp_t **head);
100
+
101
+sr_xavp_t *xavp_clone_level_nodata(sr_xavp_t *xold);
97 102
 #endif
98 103
 
99 104
 #endif