fba7eb29bf65d3aac8229ef63fbc5fe285de8554
[sip-router] / data_lump.c
1 /* $Id$
2  *
3  */
4
5 #include "data_lump.h"
6 #include "dprint.h"
7 #include "mem/mem.h"
8
9 #include <stdlib.h>
10 #include <string.h>
11
12 #ifdef DEBUG_DMALLOC
13 #include <dmalloc.h>
14 #endif
15
16
17
18 /* adds a header to the end
19  * returns  pointer on success, 0 on error */
20 struct lump* append_new_lump(struct lump** list, char* new_hdr,
21                                                          int len, int type)
22 {
23         struct lump** t;
24         struct lump* tmp;
25         
26         for (t=list;*t;t=&((*t)->next));
27
28         tmp=pkg_malloc(sizeof(struct lump));
29         if (tmp==0){
30                 LOG(L_ERR, "ERROR: append_new_lump: out of memory\n");
31                 return 0;
32         }
33                 
34         memset(tmp,0,sizeof(struct lump));
35         tmp->type=type;
36         tmp->op=LUMP_ADD;
37         tmp->u.value=new_hdr;
38         tmp->len=len;
39         *t=tmp;
40         return tmp;
41 }
42
43
44
45 /* inserts a header to the beginning 
46  * returns pointer if success, 0 on error */
47 struct lump* insert_new_lump(struct lump** list, char* new_hdr,
48                                                                 int len, int type)
49 {
50         struct lump* tmp;
51
52         tmp=pkg_malloc(sizeof(struct lump));
53         if (tmp==0){
54                 LOG(L_ERR, "ERROR: insert_new_lump: out of memory\n");
55                 return 0;
56         }
57         memset(tmp,0,sizeof(struct lump));
58         tmp->next=*list;
59         tmp->type=type;
60         tmp->op=LUMP_ADD;
61         tmp->u.value=new_hdr;
62         tmp->len=len;
63         *list=tmp;
64         return tmp;
65 }
66
67
68
69 /* inserts a  header/data lump immediately after hdr 
70  * returns pointer on success, 0 on error */
71 struct lump* insert_new_lump_after( struct lump* after, char* new_hdr,
72                                                         int len, int type)
73 {
74         struct lump* tmp;
75
76         tmp=pkg_malloc(sizeof(struct lump));
77         if (tmp==0){
78                 LOG(L_ERR, "ERROR: insert_new_lump_after: out of memory\n");
79                 return 0;
80         }
81         memset(tmp,0,sizeof(struct lump));
82         tmp->after=after->after;
83         tmp->type=type;
84         tmp->op=LUMP_ADD;
85         tmp->u.value=new_hdr;
86         tmp->len=len;
87         after->after=tmp;
88         return tmp;
89 }
90
91
92
93 /* inserts a  header/data lump immediately before "before" 
94  * returns pointer on success, 0 on error */
95 struct lump* insert_new_lump_before( struct lump* before, char* new_hdr,
96                                                         int len, int type)
97 {
98         struct lump* tmp;
99
100         tmp=pkg_malloc(sizeof(struct lump));
101         if (tmp==0){
102                 LOG(L_ERR,"ERROR: insert_new_lump_before: out of memory\n");
103                 return 0;
104         }
105         memset(tmp,0,sizeof(struct lump));
106         tmp->before=before->before;
107         tmp->type=type;
108         tmp->op=LUMP_ADD;
109         tmp->u.value=new_hdr;
110         tmp->len=len;
111         before->before=tmp;
112         return tmp;
113 }
114
115
116
117 /* removes an already existing header/data lump */
118 struct lump* del_lump(struct lump** list, int offset, int len, int type)
119 {
120         struct lump* tmp;
121         struct lump* prev, *t;
122
123         tmp=pkg_malloc(sizeof(struct lump));
124         if (tmp==0){
125                 LOG(L_ERR, "ERROR: insert_new_lump_before: out of memory\n");
126                 return 0;
127         }
128         memset(tmp,0,sizeof(struct lump));
129         tmp->op=LUMP_DEL;
130         tmp->type=type;
131         tmp->u.offset=offset;
132         tmp->len=len;
133         prev=0;
134         for (t=*list;t; prev=t, t=t->next){
135                 /* insert it sorted after offset */
136                 if (((t->op==LUMP_DEL)||(t->op==LUMP_NOP))&&(t->u.offset>offset))
137                         break;
138         }
139         tmp->next=t;
140         if (prev) prev->next=tmp;
141         else *list=tmp;
142         return tmp;
143 }
144
145
146
147 /* add an anhor */
148 struct lump* anchor_lump(struct lump** list, int offset, int len, int type)
149 {
150         struct lump* tmp;
151         struct lump* prev, *t;
152
153         tmp=pkg_malloc(sizeof(struct lump));
154         if (tmp==0){
155                 LOG(L_ERR, "ERROR: insert_new_lump_before: out of memory\n");
156                 return 0;
157         }
158         memset(tmp,0,sizeof(struct lump));
159         tmp->op=LUMP_NOP;
160         tmp->type=type;
161         tmp->u.offset=offset;
162         tmp->len=len;
163         prev=0;
164         for (t=*list;t; prev=t, t=t->next){
165                 /* insert it sorted after offset */
166                 if (((t->op==LUMP_DEL)||(t->op==LUMP_NOP))&&(t->u.offset>offset))
167                         break;
168         }
169         tmp->next=t;
170         
171         if (prev) prev->next=tmp;
172         else *list=tmp;
173         return tmp;
174 }
175
176
177
178 void free_lump(struct lump* lmp)
179 {
180         if (lmp && (lmp->op==LUMP_ADD)){
181                 if (lmp->u.value) pkg_free(lmp->u.value);
182                 lmp->u.value=0;
183                 lmp->len=0;
184         }
185 }
186
187
188
189 void free_lump_list(struct lump* l)
190 {
191         struct lump* t, *r, *foo,*crt;
192         t=l;
193         while(t){
194                 crt=t;
195                 t=t->next;
196         /*
197                  dangerous recursive clean
198                 if (crt->before) free_lump_list(crt->before);
199                 if (crt->after)  free_lump_list(crt->after);
200         */
201                 /* no more recursion, clean after and before and that's it */
202                 r=crt->before;
203                 while(r){
204                         foo=r; r=r->before;
205                         free_lump(foo);
206                         pkg_free(foo);
207                 }
208                 r=crt->after;
209                 while(r){
210                         foo=r; r=r->after;
211                         free_lump(foo);
212                         pkg_free(foo);
213                 }
214                 
215                 /*clean current elem*/
216                 free_lump(crt);
217                 pkg_free(crt);
218         }
219 }