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