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 504
 {
455 505
 	xavp_print_list_content(head, 0);
456 506
 }
507
+
508
+/**
509
+ * clone the xavp without values that are custom data
510
+ * - only one list level is cloned, other sublists are ignored
511
+ */
512
+sr_xavp_t *xavp_clone_level_nodata(sr_xavp_t *xold)
513
+{
514
+	sr_xavp_t *xnew = NULL;
515
+	sr_xavp_t *navp = NULL;
516
+	sr_xavp_t *oavp = NULL;
517
+	sr_xavp_t *pavp = NULL;
518
+
519
+	if(xold == NULL)
520
+		return NULL;
521
+	if(xold->val.type==SR_XTYPE_DATA)
522
+	{
523
+		LM_INFO("xavp value type is 'data' - ignoring in clone\n");
524
+		return NULL;
525
+	}
526
+	xnew = xavp_new_value(&xold->name, &xold->val);
527
+	if(xnew==NULL)
528
+	{
529
+		LM_ERR("cannot create cloned root xavp\n");
530
+		return NULL;
531
+	}
532
+
533
+	if(xold->val.type!=SR_XTYPE_XAVP)
534
+		return xnew;
535
+
536
+	xnew->val.v.xavp = NULL;
537
+	oavp = xold->val.v.xavp;
538
+
539
+	while(oavp)
540
+	{
541
+		if(xold->val.type!=SR_XTYPE_DATA && xold->val.type!=SR_XTYPE_XAVP)
542
+		{
543
+			navp =  xavp_new_value(&oavp->name, &oavp->val);
544
+			if(navp==NULL)
545
+			{
546
+				if(xnew->val.v.xavp == NULL)
547
+				{
548
+					shm_free(xnew);
549
+					return NULL;
550
+				} else {
551
+					xavp_destroy_list(&navp);
552
+					return NULL;
553
+				}
554
+			}
555
+			if(xnew->val.v.xavp == NULL)
556
+			{
557
+				/* link to val in head xavp */
558
+				xnew->val.v.xavp = navp;
559
+				pavp = navp;
560
+			} else {
561
+				/* link to prev xavp in the list */
562
+				pavp->next = navp;
563
+			}
564
+		}
565
+		oavp = oavp->next;
566
+	}
567
+
568
+	if(xnew->val.v.xavp == NULL)
569
+	{
570
+		shm_free(xnew);
571
+		return NULL;
572
+	}
573
+
574
+	return xnew;
575
+}
576
+
577
+int xavp_insert(sr_xavp_t *xavp, int idx, sr_xavp_t **list)
578
+{
579
+	sr_xavp_t *crt = 0;
580
+	sr_xavp_t *fst = 0;
581
+	sr_xavp_t *lst = 0;
582
+	sr_xval_t val;
583
+	int n = 0;
584
+	int i = 0;
585
+
586
+	if(idx==0)
587
+		return xavp_add(xavp, list);
588
+
589
+	crt = xavp_get_internal(&xavp->name, list, 0, 0);
590
+	while(crt!=NULL && n<idx) {
591
+		lst = crt;
592
+		n++;
593
+		crt = xavp_get_next(lst);
594
+	}
595
+	memset(&val, 0, sizeof(sr_xval_t));
596
+	val.type = SR_XTYPE_NULL;
597
+	for(i=0; i<idx-n; i++) {
598
+		crt = xavp_add_value(&xavp->name, &val, list);
599
+		if(crt==NULL)
600
+			return -1;
601
+		if(fst==NULL)
602
+			fst = crt;
603
+		if(lst==NULL) {
604
+			if(xavp_add(crt, list)<0)
605
+				return -1;
606
+		} else {
607
+			crt->next = lst->next;
608
+			lst->next = crt;
609
+		}
610
+	}
611
+
612
+	if(fst==NULL) {
613
+		return xavp_add(xavp, list);
614
+	} else {
615
+		xavp->next = fst->next;
616
+		fst->next = xavp;
617
+	}
618
+
619
+	return 0;
620
+}
621
+
622
+sr_xavp_t *xavp_extract(str *name, sr_xavp_t **list)
623
+{
624
+	sr_xavp_t *avp = 0;
625
+	sr_xavp_t *foo;
626
+	sr_xavp_t *prv = 0;
627
+	unsigned int id;
628
+
629
+	if(name==NULL || name->s==NULL) {
630
+		if(list!=NULL) {
631
+			avp = *list;
632
+			if(avp!=NULL) {
633
+				*list = avp->next;
634
+				avp->next = NULL;
635
+			}
636
+		} else {
637
+			avp = *_xavp_list_crt;
638
+			if(avp!=NULL) {
639
+				*_xavp_list_crt = avp->next;
640
+				avp->next = NULL;
641
+			}
642
+		}
643
+		
644
+		return avp;
645
+	}
646
+
647
+	id = get_hash1_raw(name->s, name->len);
648
+	if(list!=NULL)
649
+		avp = *list;
650
+	else
651
+		avp = *_xavp_list_crt;
652
+	while(avp)
653
+	{
654
+		foo = avp;
655
+		avp=avp->next;
656
+		if(foo->id==id && foo->name.len==name->len
657
+				&& strncmp(foo->name.s, name->s, name->len)==0)
658
+		{
659
+			if(prv!=NULL)
660
+				prv->next=foo->next;
661
+			else if(list!=NULL)
662
+				*list = foo->next;
663
+			else
664
+				*_xavp_list_crt = foo->next;
665
+			foo->next = NULL;
666
+			return foo;
667
+		} else {
668
+			prv = foo;
669
+		}
670
+	}
671
+	return NULL;
672
+}
457 673
 #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 95
 sr_xavp_t **xavp_set_list(sr_xavp_t **head);
94 96
 sr_xavp_t **xavp_get_crt_list(void);
95 97
 
98
+int xavp_insert(sr_xavp_t *xavp, int idx, sr_xavp_t **list);
99
+sr_xavp_t *xavp_extract(str *name, sr_xavp_t **list);
100
+
96 101
 void xavp_print_list(sr_xavp_t **head);
102
+
103
+sr_xavp_t *xavp_clone_level_nodata(sr_xavp_t *xold);
97 104
 #endif
98 105
 
99 106
 #endif