File: | libs/sofia-sip/libsofia-sip-ua/sdp/sdp.c |
Location: | line 1455, column 7 |
Description: | Access to field 'm_type' results in a dereference of a null pointer (loaded from variable 'a') |
1 | /* | |||
2 | * This file is part of the Sofia-SIP package | |||
3 | * | |||
4 | * Copyright (C) 2005 Nokia Corporation. | |||
5 | * | |||
6 | * Contact: Pekka Pessi <pekka.pessi@nokia.com> | |||
7 | * | |||
8 | * This library is free software; you can redistribute it and/or | |||
9 | * modify it under the terms of the GNU Lesser General Public License | |||
10 | * as published by the Free Software Foundation; either version 2.1 of | |||
11 | * the License, or (at your option) any later version. | |||
12 | * | |||
13 | * This library is distributed in the hope that it will be useful, but | |||
14 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
16 | * Lesser General Public License for more details. | |||
17 | * | |||
18 | * You should have received a copy of the GNU Lesser General Public | |||
19 | * License along with this library; if not, write to the Free Software | |||
20 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | |||
21 | * 02110-1301 USA | |||
22 | * | |||
23 | */ | |||
24 | ||||
25 | /**@CFILE sdp.c Simple SDP interface. | |||
26 | * | |||
27 | * @author Pekka Pessi <Pekka.Pessi@nokia.com> | |||
28 | * @author Kai Vehmanen <kai.vehmanen@nokia.com> | |||
29 | * | |||
30 | * @date Created: Fri Feb 18 10:25:08 2000 ppessi | |||
31 | */ | |||
32 | ||||
33 | #include "config.h" | |||
34 | ||||
35 | #include <stddef.h> | |||
36 | #include <stdlib.h> | |||
37 | #include <string.h> | |||
38 | #include <stdarg.h> | |||
39 | #include <stdio.h> | |||
40 | #include <assert.h> | |||
41 | ||||
42 | #include <sofia-sip/su_alloc.h> | |||
43 | #include <sofia-sip/su_types.h> | |||
44 | #include <sofia-sip/su_string.h> | |||
45 | ||||
46 | #include "sofia-sip/sdp.h" | |||
47 | ||||
48 | struct align { void *_a; char _b; }; | |||
49 | ||||
50 | #define ALIGN(v, n)((n - (intptr_t)(v)) & (n - 1)) ((n - (intptr_t)(v)) & (n - 1)) | |||
51 | #define STRUCT_ALIGN_(sizeof(struct align) - __builtin_offsetof(struct align, _b)) (sizeof(struct align) - offsetof(struct align, _b)__builtin_offsetof(struct align, _b)) | |||
52 | #define STRUCT_ALIGN(v)((sizeof(void *) - (intptr_t)(v)) & (sizeof(void *) - 1)) ALIGN(v, sizeof(void *))((sizeof(void *) - (intptr_t)(v)) & (sizeof(void *) - 1)) | |||
53 | #define ASSERT_STRUCT_ALIGN(p)(((sizeof(void *) - (intptr_t)(p)) & (sizeof(void *) - 1) ) ? (void)((!"STRUCT_ALIGNED(" "p" ")") ? (void) (0) : __assert_fail ("!\"STRUCT_ALIGNED(\" \"p\" \")\"", "sdp.c", 53, __PRETTY_FUNCTION__ )) : (void)0) \ | |||
54 | (STRUCT_ALIGN(p)((sizeof(void *) - (intptr_t)(p)) & (sizeof(void *) - 1)) ? (void)assert(!"STRUCT_ALIGNED(" #p ")")((!"STRUCT_ALIGNED(" #p ")") ? (void) (0) : __assert_fail ("!\"STRUCT_ALIGNED(\" #p \")\"" , "sdp.c", 54, __PRETTY_FUNCTION__)) : (void)0) | |||
55 | ||||
56 | const unsigned sdp_struct_align_ = sizeof(void *) - STRUCT_ALIGN_(sizeof(struct align) - __builtin_offsetof(struct align, _b)); | |||
57 | ||||
58 | #define STR_XTRA(rv, s)((s) ? rv += strlen((s)) + 1 : 0) ((s) ? rv += strlen((s)) + 1 : 0) | |||
59 | #define PTR_XTRA(rv, p, f)((p) ? (rv += ((sizeof(void *) - (intptr_t)(rv)) & (sizeof (void *) - 1)) + f(p)) : 0) \ | |||
60 | ((p) ? (rv += STRUCT_ALIGN(rv)((sizeof(void *) - (intptr_t)(rv)) & (sizeof(void *) - 1) ) + f(p)) : 0) | |||
61 | #define LST_XTRA(rv, l, f)((l) ? (rv += ((sizeof(void *) - (intptr_t)(rv)) & (sizeof (void *) - 1)) + list_xtra_all((xtra_f*)f, l)) : 0) \ | |||
62 | ((l) ? (rv += STRUCT_ALIGN(rv)((sizeof(void *) - (intptr_t)(rv)) & (sizeof(void *) - 1) ) + list_xtra_all((xtra_f*)f, l)) : 0) | |||
63 | ||||
64 | ||||
65 | #define STRUCT_DUP(p, dst, src)(((sizeof(void *) - (intptr_t)(p)) & (sizeof(void *) - 1) ) ? (void)((!"STRUCT_ALIGNED(" "p" ")") ? (void) (0) : __assert_fail ("!\"STRUCT_ALIGNED(\" \"p\" \")\"", "sdp.c", 65, __PRETTY_FUNCTION__ )) : (void)0); ((*(int*)(src) >= (int)sizeof(*src) ? (dst = memcpy((p), (src), sizeof(*src))) : (dst = memcpy((p), (src) , *(int*)(src))), memset((p)+*(int*)(src), 0, sizeof(*src) - * (int*)(src))), ((p) += sizeof(*src))) \ | |||
66 | ASSERT_STRUCT_ALIGN(p)(((sizeof(void *) - (intptr_t)(p)) & (sizeof(void *) - 1) ) ? (void)((!"STRUCT_ALIGNED(" "p" ")") ? (void) (0) : __assert_fail ("!\"STRUCT_ALIGNED(\" \"p\" \")\"", "sdp.c", 66, __PRETTY_FUNCTION__ )) : (void)0); \ | |||
67 | ((*(int*)(src) >= (int)sizeof(*src) \ | |||
68 | ? (dst = memcpy((p), (src), sizeof(*src))) \ | |||
69 | : (dst = memcpy((p), (src), *(int*)(src))), \ | |||
70 | memset((p)+*(int*)(src), 0, sizeof(*src) - *(int*)(src))), \ | |||
71 | ((p) += sizeof(*src))) | |||
72 | ||||
73 | #define STRUCT_DUP2(p, dst, src)(((sizeof(void *) - (intptr_t)(p)) & (sizeof(void *) - 1) ) ? (void)((!"STRUCT_ALIGNED(" "p" ")") ? (void) (0) : __assert_fail ("!\"STRUCT_ALIGNED(\" \"p\" \")\"", "sdp.c", 73, __PRETTY_FUNCTION__ )) : (void)0); ((*(int*)(src) >= (int)sizeof(*src)) ? (void ) (0) : __assert_fail ("*(int*)(src) >= (int)sizeof(*src)" , "sdp.c", 73, __PRETTY_FUNCTION__)); (dst = memcpy((p), (src ), *(int*)(src)), ((p) += *(int*)(src))) \ | |||
74 | ASSERT_STRUCT_ALIGN(p)(((sizeof(void *) - (intptr_t)(p)) & (sizeof(void *) - 1) ) ? (void)((!"STRUCT_ALIGNED(" "p" ")") ? (void) (0) : __assert_fail ("!\"STRUCT_ALIGNED(\" \"p\" \")\"", "sdp.c", 74, __PRETTY_FUNCTION__ )) : (void)0); assert(*(int*)(src) >= (int)sizeof(*src))((*(int*)(src) >= (int)sizeof(*src)) ? (void) (0) : __assert_fail ("*(int*)(src) >= (int)sizeof(*src)", "sdp.c", 74, __PRETTY_FUNCTION__ )); \ | |||
75 | (dst = memcpy((p), (src), *(int*)(src)), ((p) += *(int*)(src))) | |||
76 | ||||
77 | #define STR_DUP(p, dst, src, m)((src->m) ? ((dst->m) = strcpy((p), (src->m)), (p) += strlen((p)) + 1) : ((dst->m) = 0)) \ | |||
78 | ((src->m) ? ((dst->m) = strcpy((p), (src->m)), (p) += strlen((p)) + 1) \ | |||
79 | : ((dst->m) = 0)) | |||
80 | #define PTR_DUP(p, dst, src, m, dup)((dst->m) = (src->m)?((p += ((sizeof(void *) - (intptr_t )(p)) & (sizeof(void *) - 1))), ((dup)(&(p), (src-> m)))): 0) \ | |||
81 | ((dst->m) = (src->m)?((p += STRUCT_ALIGN(p)((sizeof(void *) - (intptr_t)(p)) & (sizeof(void *) - 1))), ((dup)(&(p), (src->m)))): 0) | |||
82 | #define LST_DUP(p, dst, src, m, dup)((dst->m) = (src->m)?((p += ((sizeof(void *) - (intptr_t )(p)) & (sizeof(void *) - 1))), list_dup_all((dup_f*)(dup ), &(p), src->m)) : 0) \ | |||
83 | ((dst->m) = (src->m)?((p += STRUCT_ALIGN(p)((sizeof(void *) - (intptr_t)(p)) & (sizeof(void *) - 1))),\ | |||
84 | list_dup_all((dup_f*)(dup), &(p), src->m)) : 0) | |||
85 | #define MED_XTRA_EX(rv, l, c)((l) ? (rv += ((sizeof(void *) - (intptr_t)(rv)) & (sizeof (void *) - 1)) + media_xtra_ex(l, c)) : 0) \ | |||
86 | ((l) ? (rv += STRUCT_ALIGN(rv)((sizeof(void *) - (intptr_t)(rv)) & (sizeof(void *) - 1) ) + media_xtra_ex(l, c)) : 0) | |||
87 | #define MED_DUP_EX(p, dst, src, m, dst_c, src_c)((dst->m) = (src->m)?((p += ((sizeof(void *) - (intptr_t )(p)) & (sizeof(void *) - 1))), media_dup_all(&(p), src ->m, dst, dst_c, src_c)) : 0) \ | |||
88 | ((dst->m) = (src->m)?((p += STRUCT_ALIGN(p)((sizeof(void *) - (intptr_t)(p)) & (sizeof(void *) - 1))),\ | |||
89 | media_dup_all(&(p), src->m, dst, dst_c, src_c)) : 0) | |||
90 | ||||
91 | #define MED_XTRA_ALL(rv, m)((m) ? (rv += ((sizeof(void *) - (intptr_t)(rv)) & (sizeof (void *) - 1)) + media_xtra_all(m)) : 0) \ | |||
92 | ((m) ? (rv += STRUCT_ALIGN(rv)((sizeof(void *) - (intptr_t)(rv)) & (sizeof(void *) - 1) ) + media_xtra_all(m)) : 0) | |||
93 | #define MED_DUP_ALL(p, dst, src, m)((dst->m) = (src->m)?((p += ((sizeof(void *) - (intptr_t )(p)) & (sizeof(void *) - 1))), media_dup_all(&(p), src ->m, dst)) : 0) \ | |||
94 | ((dst->m) = (src->m)?((p += STRUCT_ALIGN(p)((sizeof(void *) - (intptr_t)(p)) & (sizeof(void *) - 1))),\ | |||
95 | media_dup_all(&(p), src->m, dst)) : 0) | |||
96 | ||||
97 | typedef size_t xtra_f(void const *); | |||
98 | typedef void *dup_f(char **bb, void const *src); | |||
99 | ||||
100 | static size_t list_xtra_all(xtra_f *xtra, void const *v); | |||
101 | static void *list_dup_all(dup_f *dup, char **bb, void const *vsrc); | |||
102 | ||||
103 | static size_t session_xtra(sdp_session_t const *o); | |||
104 | static sdp_session_t *session_dup(char **pp, sdp_session_t const *o); | |||
105 | ||||
106 | static size_t origin_xtra(sdp_origin_t const *o); | |||
107 | static sdp_origin_t *origin_dup(char **pp, sdp_origin_t const *o); | |||
108 | ||||
109 | static size_t connection_xtra(sdp_connection_t const *o); | |||
110 | static sdp_connection_t *connection_dup(char **pp, sdp_connection_t const *o); | |||
111 | ||||
112 | static size_t bandwidth_xtra(sdp_bandwidth_t const *o); | |||
113 | static sdp_bandwidth_t *bandwidth_dup(char **pp, sdp_bandwidth_t const *o); | |||
114 | ||||
115 | static size_t time_xtra(sdp_time_t const *o); | |||
116 | static sdp_time_t *time_dup(char **pp, sdp_time_t const *o); | |||
117 | ||||
118 | static size_t repeat_xtra(sdp_repeat_t const *o); | |||
119 | static sdp_repeat_t *repeat_dup(char **pp, sdp_repeat_t const *o); | |||
120 | ||||
121 | static size_t zone_xtra(sdp_zone_t const *o); | |||
122 | static sdp_zone_t *zone_dup(char **pp, sdp_zone_t const *o); | |||
123 | ||||
124 | static size_t key_xtra(sdp_key_t const *o); | |||
125 | static sdp_key_t *key_dup(char **pp, sdp_key_t const *o); | |||
126 | ||||
127 | static size_t attribute_xtra(sdp_attribute_t const *o); | |||
128 | static sdp_attribute_t *attribute_dup(char **pp, sdp_attribute_t const *o); | |||
129 | ||||
130 | static size_t list_xtra(sdp_list_t const *o); | |||
131 | static sdp_list_t *list_dup(char **pp, sdp_list_t const *o); | |||
132 | ||||
133 | static size_t rtpmap_xtra(sdp_rtpmap_t const *o); | |||
134 | static sdp_rtpmap_t *rtpmap_dup(char **pp, sdp_rtpmap_t const *o); | |||
135 | ||||
136 | static size_t media_xtra(sdp_media_t const *o); | |||
137 | static sdp_media_t *media_dup(char **pp, | |||
138 | sdp_media_t const *o, | |||
139 | sdp_session_t *sdp); | |||
140 | #ifdef nomore | |||
141 | static size_t media_xtra_ex(sdp_media_t const *o, | |||
142 | sdp_connection_t const *c); | |||
143 | static sdp_media_t *media_dup_ex(char **pp, | |||
144 | sdp_media_t const *o, | |||
145 | sdp_session_t *sdp, | |||
146 | sdp_connection_t *dst_c, | |||
147 | sdp_connection_t const *src_c); | |||
148 | #endif | |||
149 | static size_t media_xtra_all(sdp_media_t const *o); | |||
150 | static sdp_media_t *media_dup_all(char **pp, | |||
151 | sdp_media_t const *o, | |||
152 | sdp_session_t *sdp); | |||
153 | ||||
154 | ||||
155 | /** Define a function body duplicating an SDP structure. */ | |||
156 | #define SDP_DUP(type, name)sdp_type_t *rv; size_t size; char *p, *end; if (!name) return ((void*)0); size = type_xtra(name); p = su_alloc(h, size); end = p + size; rv = type_dup(&p, name); ((p == end) ? (void ) (0) : __assert_fail ("p == end", "sdp.c", 156, __PRETTY_FUNCTION__ )); return rv; \ | |||
157 | sdp_##type##_t *rv; size_t size; char *p, *end; \ | |||
158 | if (!name) return NULL((void*)0); \ | |||
159 | size = type##_xtra(name); \ | |||
160 | p = su_alloc(h, size); end = p + size; \ | |||
161 | rv = type##_dup(&p, name); \ | |||
162 | assert(p == end)((p == end) ? (void) (0) : __assert_fail ("p == end", "sdp.c" , 162, __PRETTY_FUNCTION__)); \ | |||
163 | return rv; | |||
164 | ||||
165 | /** Define a function body duplicating a list of SDP structures. */ | |||
166 | #define SDP_LIST_DUP(type, name)sdp_type_t *rv; size_t size; char *p, *end; if (!name) return ((void*)0); size = list_xtra_all((xtra_f*)type_xtra, name); rv = su_alloc(h, size); p = (char *)rv; end = p + size; list_dup_all ((dup_f*)type_dup, &p, name); ((p == end) ? (void) (0) : __assert_fail ("p == end", "sdp.c", 166, __PRETTY_FUNCTION__)); return rv; \ | |||
167 | sdp_##type##_t *rv; size_t size; char *p, *end; \ | |||
168 | if (!name) return NULL((void*)0); \ | |||
169 | size = list_xtra_all((xtra_f*)type##_xtra, name); \ | |||
170 | rv = su_alloc(h, size); p = (char *)rv; end = p + size; \ | |||
171 | list_dup_all((dup_f*)type##_dup, &p, name); \ | |||
172 | assert(p == end)((p == end) ? (void) (0) : __assert_fail ("p == end", "sdp.c" , 172, __PRETTY_FUNCTION__)); \ | |||
173 | return rv; | |||
174 | ||||
175 | /**Duplicate an SDP origin description. | |||
176 | * | |||
177 | * The function sdp_origin_dup() duplicates (deeply copies) an SDP origin | |||
178 | * description @a o allocating memory using memory @a home. | |||
179 | * | |||
180 | * @param h Memory home | |||
181 | * @param o SDP origin description to be duplicated | |||
182 | * | |||
183 | * @note The duplicated structure is allocated using a single call to | |||
184 | * su_alloc() and it can be freed with su_free(). | |||
185 | * | |||
186 | * @return | |||
187 | * If successful, a pointer to newly allocated sdp_origin_t structure is | |||
188 | * returned, otherwise NULL is returned. | |||
189 | */ | |||
190 | sdp_origin_t *sdp_origin_dup(su_home_t *h, sdp_origin_t const *o) | |||
191 | { | |||
192 | SDP_DUP(origin, o)sdp_origin_t *rv; size_t size; char *p, *end; if (!o) return ( (void*)0); size = origin_xtra(o); p = su_alloc(h, size); end = p + size; rv = origin_dup(&p, o); ((p == end) ? (void) ( 0) : __assert_fail ("p == end", "sdp.c", 192, __PRETTY_FUNCTION__ )); return rv;; | |||
193 | } | |||
194 | ||||
195 | /**Duplicate an SDP connection description. | |||
196 | * | |||
197 | * The function sdp_connection_dup() duplicates (deeply copies) a list of | |||
198 | * SDP connection description @a c allocating memory using memory @a home. | |||
199 | * | |||
200 | * @param h Memory home | |||
201 | * @param c SDP connection description to be duplicated | |||
202 | * | |||
203 | * @note The duplicated list is allocated using a single call to | |||
204 | * su_alloc() and it can be freed with su_free(). | |||
205 | * | |||
206 | * @return | |||
207 | * If successful, a pointer to newly allocated sdp_connection_t structure is | |||
208 | * returned, otherwise NULL is returned. | |||
209 | */ | |||
210 | sdp_connection_t *sdp_connection_dup(su_home_t *h, sdp_connection_t const *c) | |||
211 | { | |||
212 | SDP_LIST_DUP(connection, c)sdp_connection_t *rv; size_t size; char *p, *end; if (!c) return ((void*)0); size = list_xtra_all((xtra_f*)connection_xtra, c ); rv = su_alloc(h, size); p = (char *)rv; end = p + size; list_dup_all ((dup_f*)connection_dup, &p, c); ((p == end) ? (void) (0) : __assert_fail ("p == end", "sdp.c", 212, __PRETTY_FUNCTION__ )); return rv;; | |||
213 | } | |||
214 | ||||
215 | /**Duplicate an SDP bandwidth description. | |||
216 | * | |||
217 | * The function sdp_bandwidth_dup() duplicates (deeply copies) a list of SDP | |||
218 | * bandwidth descriptions @a b allocating memory using memory @a home. | |||
219 | * | |||
220 | * @param h Memory home | |||
221 | * @param b SDP bandwidth description to be duplicated | |||
222 | * | |||
223 | * @note The duplicated list is allocated using a single call to | |||
224 | * su_alloc() and it can be freed with su_free(). | |||
225 | * | |||
226 | * @return | |||
227 | * If successful, a pointer to newly allocated sdp_bandwidth_t structure is | |||
228 | * returned, otherwise NULL is returned. | |||
229 | */ | |||
230 | sdp_bandwidth_t *sdp_bandwidth_dup(su_home_t *h, sdp_bandwidth_t const *b) | |||
231 | { | |||
232 | SDP_LIST_DUP(bandwidth, b)sdp_bandwidth_t *rv; size_t size; char *p, *end; if (!b) return ((void*)0); size = list_xtra_all((xtra_f*)bandwidth_xtra, b) ; rv = su_alloc(h, size); p = (char *)rv; end = p + size; list_dup_all ((dup_f*)bandwidth_dup, &p, b); ((p == end) ? (void) (0) : __assert_fail ("p == end", "sdp.c", 232, __PRETTY_FUNCTION__ )); return rv;; | |||
233 | } | |||
234 | ||||
235 | /**Duplicate an SDP time description. | |||
236 | * | |||
237 | * The function sdp_time_dup() duplicates (deeply copies) a list of SDP time | |||
238 | * descriptions @a t allocating memory using memory @a home. | |||
239 | * | |||
240 | * @param h Memory home | |||
241 | * @param t SDP time description to be duplicated | |||
242 | * | |||
243 | * @note The duplicated list is allocated using a single call to | |||
244 | * su_alloc() and it can be freed with su_free(). | |||
245 | * | |||
246 | * @return | |||
247 | * If successful, a pointer to newly allocated sdp_time_t structure is | |||
248 | * returned, otherwise NULL is returned. | |||
249 | */ | |||
250 | sdp_time_t *sdp_time_dup(su_home_t *h, sdp_time_t const *t) | |||
251 | { | |||
252 | SDP_LIST_DUP(time, t)sdp_time_t *rv; size_t size; char *p, *end; if (!t) return (( void*)0); size = list_xtra_all((xtra_f*)time_xtra, t); rv = su_alloc (h, size); p = (char *)rv; end = p + size; list_dup_all((dup_f *)time_dup, &p, t); ((p == end) ? (void) (0) : __assert_fail ("p == end", "sdp.c", 252, __PRETTY_FUNCTION__)); return rv;; | |||
253 | } | |||
254 | ||||
255 | /**Duplicate an SDP repeat description. | |||
256 | * | |||
257 | * The function sdp_repeat_dup() duplicates (deeply copies) an SDP repeat | |||
258 | * description @a r allocating memory using memory @a home. | |||
259 | * | |||
260 | * @param h Memory home | |||
261 | * @param r SDP repeat description to be duplicated | |||
262 | * | |||
263 | * @note The duplicated structure is allocated using a single call to | |||
264 | * su_alloc() and it can be freed with su_free(). | |||
265 | * | |||
266 | * @return | |||
267 | * If successful, a pointer to newly allocated sdp_repeat_t structure is | |||
268 | * returned, otherwise NULL is returned. | |||
269 | */ | |||
270 | sdp_repeat_t *sdp_repeat_dup(su_home_t *h, sdp_repeat_t const *r) | |||
271 | { | |||
272 | SDP_DUP(repeat, r)sdp_repeat_t *rv; size_t size; char *p, *end; if (!r) return ( (void*)0); size = repeat_xtra(r); p = su_alloc(h, size); end = p + size; rv = repeat_dup(&p, r); ((p == end) ? (void) ( 0) : __assert_fail ("p == end", "sdp.c", 272, __PRETTY_FUNCTION__ )); return rv;; | |||
273 | } | |||
274 | ||||
275 | /**Duplicate an SDP zone description. | |||
276 | * | |||
277 | * The function sdp_zone_dup() duplicates (deeply copies) an SDP zone | |||
278 | * description @a z allocating memory using memory @a home. | |||
279 | * | |||
280 | * @param h Memory home | |||
281 | * @param z SDP zone description to be duplicated | |||
282 | * | |||
283 | * @note The duplicated structure is allocated using a single call to | |||
284 | * su_alloc() and it can be freed with su_free(). | |||
285 | * | |||
286 | * @return | |||
287 | * If successful, a pointer to newly allocated sdp_zone_t structure is | |||
288 | * returned, otherwise NULL is returned. | |||
289 | */ | |||
290 | sdp_zone_t *sdp_zone_dup(su_home_t *h, sdp_zone_t const *z) | |||
291 | { | |||
292 | SDP_DUP(zone, z)sdp_zone_t *rv; size_t size; char *p, *end; if (!z) return (( void*)0); size = zone_xtra(z); p = su_alloc(h, size); end = p + size; rv = zone_dup(&p, z); ((p == end) ? (void) (0) : __assert_fail ("p == end", "sdp.c", 292, __PRETTY_FUNCTION__ )); return rv;; | |||
293 | } | |||
294 | ||||
295 | /**Duplicate an SDP key description. | |||
296 | * | |||
297 | * The function sdp_key_dup() duplicates (deeply copies) an SDP key | |||
298 | * description @a k allocating memory using memory @a home. | |||
299 | * | |||
300 | * @param h Memory home | |||
301 | * @param k SDP key description to be duplicated | |||
302 | * | |||
303 | * @note The duplicated structure is allocated using a single call to | |||
304 | * su_alloc() and it can be freed with su_free(). | |||
305 | * | |||
306 | * @return | |||
307 | * If successful, a pointer to newly allocated sdp_key_t structure is | |||
308 | * returned, otherwise NULL is returned. | |||
309 | */ | |||
310 | sdp_key_t *sdp_key_dup(su_home_t *h, sdp_key_t const *k) | |||
311 | { | |||
312 | SDP_DUP(key, k)sdp_key_t *rv; size_t size; char *p, *end; if (!k) return ((void *)0); size = key_xtra(k); p = su_alloc(h, size); end = p + size ; rv = key_dup(&p, k); ((p == end) ? (void) (0) : __assert_fail ("p == end", "sdp.c", 312, __PRETTY_FUNCTION__)); return rv;; | |||
313 | } | |||
314 | ||||
315 | /**Duplicate an SDP attribute list. | |||
316 | * | |||
317 | * The function sdp_attribute_dup() duplicates (deeply copies) an SDP | |||
318 | * attribute list @a a allocating memory using memory @a home. | |||
319 | * | |||
320 | * @param h Memory home | |||
321 | * @param a SDP attribute description to be duplicated | |||
322 | * | |||
323 | * @note The duplicated structure is allocated using a single call to | |||
324 | * su_alloc() and it can be freed with su_free(). | |||
325 | * | |||
326 | * @return | |||
327 | * If successful, a pointer to newly allocated sdp_attribute_t structure is | |||
328 | * returned, otherwise NULL is returned. | |||
329 | */ | |||
330 | sdp_attribute_t *sdp_attribute_dup(su_home_t *h, sdp_attribute_t const *a) | |||
331 | { | |||
332 | SDP_LIST_DUP(attribute, a)sdp_attribute_t *rv; size_t size; char *p, *end; if (!a) return ((void*)0); size = list_xtra_all((xtra_f*)attribute_xtra, a) ; rv = su_alloc(h, size); p = (char *)rv; end = p + size; list_dup_all ((dup_f*)attribute_dup, &p, a); ((p == end) ? (void) (0) : __assert_fail ("p == end", "sdp.c", 332, __PRETTY_FUNCTION__ )); return rv;; | |||
333 | } | |||
334 | ||||
335 | /**Duplicate an SDP list of text. | |||
336 | * | |||
337 | * The function sdp_list_dup() duplicates (deeply copies) an SDP text | |||
338 | * list @a l allocating memory using memory @a home. | |||
339 | * | |||
340 | * @param h Memory home | |||
341 | * @param l SDP list description to be duplicated | |||
342 | * | |||
343 | * @note The duplicated structure is allocated using a single call to | |||
344 | * su_alloc() and it can be freed with su_free(). | |||
345 | * | |||
346 | * @return | |||
347 | * If successful, a pointer to newly allocated sdp_list_t structure is | |||
348 | * returned, otherwise NULL is returned. | |||
349 | */ | |||
350 | sdp_list_t *sdp_list_dup(su_home_t *h, sdp_list_t const *l) | |||
351 | { | |||
352 | SDP_LIST_DUP(list, l)sdp_list_t *rv; size_t size; char *p, *end; if (!l) return (( void*)0); size = list_xtra_all((xtra_f*)list_xtra, l); rv = su_alloc (h, size); p = (char *)rv; end = p + size; list_dup_all((dup_f *)list_dup, &p, l); ((p == end) ? (void) (0) : __assert_fail ("p == end", "sdp.c", 352, __PRETTY_FUNCTION__)); return rv;; | |||
353 | } | |||
354 | ||||
355 | /**Duplicate an SDP rtpmap list. | |||
356 | * | |||
357 | * The function sdp_rtpmap_dup() duplicates (deeply copies) an SDP rtpmap | |||
358 | * list @a rm allocating memory using memory @a home. | |||
359 | * | |||
360 | * @param h Memory home | |||
361 | * @param rm SDP rtpmap description to be duplicated | |||
362 | * | |||
363 | * @note The duplicated structure is allocated using a single call to | |||
364 | * su_alloc() and it can be freed with su_free(). | |||
365 | * | |||
366 | * @return | |||
367 | * If successful, a pointer to newly allocated sdp_rtpmap_t structure is | |||
368 | * returned, otherwise NULL is returned. | |||
369 | */ | |||
370 | sdp_rtpmap_t *sdp_rtpmap_dup(su_home_t *h, sdp_rtpmap_t const *rm) | |||
371 | { | |||
372 | SDP_LIST_DUP(rtpmap, rm)sdp_rtpmap_t *rv; size_t size; char *p, *end; if (!rm) return ((void*)0); size = list_xtra_all((xtra_f*)rtpmap_xtra, rm); rv = su_alloc(h, size); p = (char *)rv; end = p + size; list_dup_all ((dup_f*)rtpmap_dup, &p, rm); ((p == end) ? (void) (0) : __assert_fail ("p == end", "sdp.c", 372, __PRETTY_FUNCTION__)); return rv;; | |||
373 | } | |||
374 | ||||
375 | /**Duplicate an SDP media description. | |||
376 | * | |||
377 | * The function sdp_media_dup() duplicates (deeply copies) an SDP media | |||
378 | * description @a m allocating memory using memory @a home. | |||
379 | * | |||
380 | * @param h Memory home | |||
381 | * @param m SDP media description to be duplicated | |||
382 | * @param sdp SDP session description to which the newly allocated | |||
383 | * media description is linked | |||
384 | * | |||
385 | * @note The duplicated structure is allocated using a single call to | |||
386 | * su_alloc() and it can be freed with su_free(). | |||
387 | * | |||
388 | * @return | |||
389 | * If successful, a pointer to newly allocated sdp_media_t structure is | |||
390 | * returned, otherwise NULL is returned. | |||
391 | */ | |||
392 | sdp_media_t *sdp_media_dup(su_home_t *h, sdp_media_t const *m, | |||
393 | sdp_session_t *sdp) | |||
394 | { | |||
395 | sdp_media_t *rv; size_t size; char *p, *end; | |||
396 | size = media_xtra(m); | |||
397 | p = su_alloc(h, size); end = p + size; | |||
398 | rv = media_dup(&p, m, sdp); | |||
399 | assert(p == end)((p == end) ? (void) (0) : __assert_fail ("p == end", "sdp.c" , 399, __PRETTY_FUNCTION__)); | |||
400 | return rv; | |||
401 | } | |||
402 | ||||
403 | /**Duplicate an SDP media description. | |||
404 | * | |||
405 | * The function sdp_media_dup_all() duplicates (deeply copies) a list of SDP | |||
406 | * media descriptions @a m allocating memory using memory @a home. | |||
407 | * | |||
408 | * @param h Memory home | |||
409 | * @param m list of SDP media descriptions to be duplicated | |||
410 | * @param sdp SDP session description to which the newly allocated | |||
411 | * media descriptions are linked | |||
412 | * | |||
413 | * @note The duplicated list is allocated using a single call to | |||
414 | * su_alloc() and it can be freed with su_free(). | |||
415 | * | |||
416 | * @return | |||
417 | * If successful, a pointer to a newly allocated list of sdp_media_t | |||
418 | * structures is returned, otherwise NULL is returned. | |||
419 | */ | |||
420 | sdp_media_t *sdp_media_dup_all(su_home_t *h, sdp_media_t const *m, | |||
421 | sdp_session_t *sdp) | |||
422 | { | |||
423 | sdp_media_t *rv; size_t size; char *p, *end; | |||
424 | size = media_xtra_all(m); | |||
425 | p = su_alloc(h, size); end = p + size; | |||
426 | rv = media_dup_all(&p, m, sdp); | |||
427 | assert(p == end)((p == end) ? (void) (0) : __assert_fail ("p == end", "sdp.c" , 427, __PRETTY_FUNCTION__)); | |||
428 | return rv; | |||
429 | } | |||
430 | ||||
431 | #ifdef nomore /* really deprecated */ | |||
432 | /**Duplicate media description with common address. | |||
433 | * | |||
434 | * This function is provided in order to avoid duplicate @c c= lines. If | |||
435 | * the @c c= line in media description equals to @a src_c, it is not | |||
436 | * duplicated but replaced with @a dst_c instead. | |||
437 | * | |||
438 | * @param home Memory home | |||
439 | * @param src SDP media description to be duplicated | |||
440 | * @param sdp SDP session description to which the newly allocated | |||
441 | * media description is linked | |||
442 | * @param dst_c Connection description used instead of duplicate of @a src_c. | |||
443 | * @param src_c Connection description not to be duplicated | |||
444 | ||||
445 | * @return | |||
446 | * If successful, a pointer to newly allocated sdp_media_t structure is | |||
447 | * returned, otherwise NULL is returned. | |||
448 | * | |||
449 | * @deprecated | |||
450 | * This function is deprecated. Use sdp_media_dup() instead. | |||
451 | */ | |||
452 | sdp_media_t *sdp_media_dup_ex(su_home_t *home, | |||
453 | sdp_media_t const *src, | |||
454 | sdp_session_t *sdp, | |||
455 | sdp_connection_t *dst_c, | |||
456 | sdp_connection_t const *src_c) | |||
457 | { | |||
458 | sdp_media_t *rv; size_t size; char *p, *end; | |||
459 | size = media_xtra_all(src, src_c); | |||
460 | p = su_alloc(home, size); end = p + size; | |||
461 | rv = media_dup_all(&p, src, sdp, dst_c, src_c); | |||
462 | assert(p == end)((p == end) ? (void) (0) : __assert_fail ("p == end", "sdp.c" , 462, __PRETTY_FUNCTION__)); | |||
463 | return rv; | |||
464 | } | |||
465 | #endif | |||
466 | ||||
467 | /* ---------------------------------------------------------------------- */ | |||
468 | ||||
469 | static size_t origin_xtra(sdp_origin_t const *o) | |||
470 | { | |||
471 | size_t rv = sizeof(*o); | |||
472 | STR_XTRA(rv, o->o_username)((o->o_username) ? rv += strlen((o->o_username)) + 1 : 0 ); | |||
473 | PTR_XTRA(rv, o->o_address, connection_xtra)((o->o_address) ? (rv += ((sizeof(void *) - (intptr_t)(rv) ) & (sizeof(void *) - 1)) + connection_xtra(o->o_address )) : 0); | |||
474 | return rv; | |||
475 | } | |||
476 | ||||
477 | static | |||
478 | sdp_origin_t *origin_dup(char **pp, sdp_origin_t const *src) | |||
479 | { | |||
480 | char *p; | |||
481 | sdp_origin_t *o; | |||
482 | ||||
483 | p = *pp; | |||
484 | STRUCT_DUP(p, o, src)(((sizeof(void *) - (intptr_t)(p)) & (sizeof(void *) - 1) ) ? (void)((!"STRUCT_ALIGNED(" "p" ")") ? (void) (0) : __assert_fail ("!\"STRUCT_ALIGNED(\" \"p\" \")\"", "sdp.c", 484, __PRETTY_FUNCTION__ )) : (void)0); ((*(int*)(src) >= (int)sizeof(*src) ? (o = memcpy ((p), (src), sizeof(*src))) : (o = memcpy((p), (src), *(int*) (src))), memset((p)+*(int*)(src), 0, sizeof(*src) - *(int*)(src ))), ((p) += sizeof(*src))); | |||
485 | STR_DUP(p, o, src, o_username)((src->o_username) ? ((o->o_username) = strcpy((p), (src ->o_username)), (p) += strlen((p)) + 1) : ((o->o_username ) = 0)); | |||
486 | PTR_DUP(p, o, src, o_address, connection_dup)((o->o_address) = (src->o_address)?((p += ((sizeof(void *) - (intptr_t)(p)) & (sizeof(void *) - 1))), ((connection_dup )(&(p), (src->o_address)))): 0); | |||
487 | ||||
488 | assert((size_t)(p - *pp) == origin_xtra(src))(((size_t)(p - *pp) == origin_xtra(src)) ? (void) (0) : __assert_fail ("(size_t)(p - *pp) == origin_xtra(src)", "sdp.c", 488, __PRETTY_FUNCTION__ )); | |||
489 | *pp = p; | |||
490 | return o; | |||
491 | } | |||
492 | ||||
493 | static size_t connection_xtra(sdp_connection_t const *c) | |||
494 | { | |||
495 | size_t rv = sizeof(*c); | |||
496 | STR_XTRA(rv, c->c_address)((c->c_address) ? rv += strlen((c->c_address)) + 1 : 0); | |||
497 | return rv; | |||
498 | } | |||
499 | ||||
500 | static | |||
501 | sdp_connection_t *connection_dup(char **pp, sdp_connection_t const *src) | |||
502 | { | |||
503 | char *p; | |||
504 | sdp_connection_t *c; | |||
505 | ||||
506 | p = *pp; | |||
507 | STRUCT_DUP(p, c, src)(((sizeof(void *) - (intptr_t)(p)) & (sizeof(void *) - 1) ) ? (void)((!"STRUCT_ALIGNED(" "p" ")") ? (void) (0) : __assert_fail ("!\"STRUCT_ALIGNED(\" \"p\" \")\"", "sdp.c", 507, __PRETTY_FUNCTION__ )) : (void)0); ((*(int*)(src) >= (int)sizeof(*src) ? (c = memcpy ((p), (src), sizeof(*src))) : (c = memcpy((p), (src), *(int*) (src))), memset((p)+*(int*)(src), 0, sizeof(*src) - *(int*)(src ))), ((p) += sizeof(*src))); | |||
508 | c->c_next = NULL((void*)0); | |||
509 | STR_DUP(p, c, src, c_address)((src->c_address) ? ((c->c_address) = strcpy((p), (src-> c_address)), (p) += strlen((p)) + 1) : ((c->c_address) = 0 )); | |||
510 | ||||
511 | assert((size_t)(p - *pp) == connection_xtra(src))(((size_t)(p - *pp) == connection_xtra(src)) ? (void) (0) : __assert_fail ("(size_t)(p - *pp) == connection_xtra(src)", "sdp.c", 511, __PRETTY_FUNCTION__ )); | |||
512 | *pp = p; | |||
513 | return c; | |||
514 | } | |||
515 | ||||
516 | static size_t bandwidth_xtra(sdp_bandwidth_t const *b) | |||
517 | { | |||
518 | size_t rv = sizeof(*b); | |||
519 | STR_XTRA(rv, b->b_modifier_name)((b->b_modifier_name) ? rv += strlen((b->b_modifier_name )) + 1 : 0); | |||
520 | return rv; | |||
521 | } | |||
522 | ||||
523 | static | |||
524 | sdp_bandwidth_t *bandwidth_dup(char **pp, sdp_bandwidth_t const *src) | |||
525 | { | |||
526 | char *p; | |||
527 | sdp_bandwidth_t *b; | |||
528 | ||||
529 | p = *pp; | |||
530 | STRUCT_DUP(p, b, src)(((sizeof(void *) - (intptr_t)(p)) & (sizeof(void *) - 1) ) ? (void)((!"STRUCT_ALIGNED(" "p" ")") ? (void) (0) : __assert_fail ("!\"STRUCT_ALIGNED(\" \"p\" \")\"", "sdp.c", 530, __PRETTY_FUNCTION__ )) : (void)0); ((*(int*)(src) >= (int)sizeof(*src) ? (b = memcpy ((p), (src), sizeof(*src))) : (b = memcpy((p), (src), *(int*) (src))), memset((p)+*(int*)(src), 0, sizeof(*src) - *(int*)(src ))), ((p) += sizeof(*src))); | |||
531 | b->b_next = NULL((void*)0); | |||
532 | STR_DUP(p, b, src, b_modifier_name)((src->b_modifier_name) ? ((b->b_modifier_name) = strcpy ((p), (src->b_modifier_name)), (p) += strlen((p)) + 1) : ( (b->b_modifier_name) = 0)); | |||
533 | ||||
534 | assert((size_t)(p - *pp) == bandwidth_xtra(src))(((size_t)(p - *pp) == bandwidth_xtra(src)) ? (void) (0) : __assert_fail ("(size_t)(p - *pp) == bandwidth_xtra(src)", "sdp.c", 534, __PRETTY_FUNCTION__ )); | |||
535 | *pp = p; | |||
536 | return b; | |||
537 | } | |||
538 | ||||
539 | ||||
540 | static size_t time_xtra(sdp_time_t const *t) | |||
541 | { | |||
542 | size_t rv = sizeof(*t); | |||
543 | PTR_XTRA(rv, t->t_repeat, repeat_xtra)((t->t_repeat) ? (rv += ((sizeof(void *) - (intptr_t)(rv)) & (sizeof(void *) - 1)) + repeat_xtra(t->t_repeat)) : 0); | |||
544 | PTR_XTRA(rv, t->t_zone, zone_xtra)((t->t_zone) ? (rv += ((sizeof(void *) - (intptr_t)(rv)) & (sizeof(void *) - 1)) + zone_xtra(t->t_zone)) : 0); | |||
545 | return rv; | |||
546 | } | |||
547 | ||||
548 | static | |||
549 | sdp_time_t *time_dup(char **pp, sdp_time_t const *src) | |||
550 | { | |||
551 | char *p; | |||
552 | sdp_time_t *t; | |||
553 | ||||
554 | p = *pp; | |||
555 | STRUCT_DUP(p, t, src)(((sizeof(void *) - (intptr_t)(p)) & (sizeof(void *) - 1) ) ? (void)((!"STRUCT_ALIGNED(" "p" ")") ? (void) (0) : __assert_fail ("!\"STRUCT_ALIGNED(\" \"p\" \")\"", "sdp.c", 555, __PRETTY_FUNCTION__ )) : (void)0); ((*(int*)(src) >= (int)sizeof(*src) ? (t = memcpy ((p), (src), sizeof(*src))) : (t = memcpy((p), (src), *(int*) (src))), memset((p)+*(int*)(src), 0, sizeof(*src) - *(int*)(src ))), ((p) += sizeof(*src))); | |||
556 | t->t_next = NULL((void*)0); | |||
557 | PTR_DUP(p, t, src, t_repeat, repeat_dup)((t->t_repeat) = (src->t_repeat)?((p += ((sizeof(void * ) - (intptr_t)(p)) & (sizeof(void *) - 1))), ((repeat_dup )(&(p), (src->t_repeat)))): 0); | |||
558 | PTR_DUP(p, t, src, t_zone, zone_dup)((t->t_zone) = (src->t_zone)?((p += ((sizeof(void *) - ( intptr_t)(p)) & (sizeof(void *) - 1))), ((zone_dup)(& (p), (src->t_zone)))): 0); | |||
559 | ||||
560 | assert((size_t)(p - *pp) == time_xtra(src))(((size_t)(p - *pp) == time_xtra(src)) ? (void) (0) : __assert_fail ("(size_t)(p - *pp) == time_xtra(src)", "sdp.c", 560, __PRETTY_FUNCTION__ )); | |||
561 | *pp = p; | |||
562 | return t; | |||
563 | } | |||
564 | ||||
565 | ||||
566 | static size_t repeat_xtra(sdp_repeat_t const *r) | |||
567 | { | |||
568 | return (size_t)r->r_size; | |||
569 | } | |||
570 | ||||
571 | static | |||
572 | sdp_repeat_t *repeat_dup(char **pp, sdp_repeat_t const *src) | |||
573 | { | |||
574 | char *p; | |||
575 | sdp_repeat_t *r; | |||
576 | ||||
577 | p = *pp; | |||
578 | STRUCT_DUP2(p, r, src)(((sizeof(void *) - (intptr_t)(p)) & (sizeof(void *) - 1) ) ? (void)((!"STRUCT_ALIGNED(" "p" ")") ? (void) (0) : __assert_fail ("!\"STRUCT_ALIGNED(\" \"p\" \")\"", "sdp.c", 578, __PRETTY_FUNCTION__ )) : (void)0); ((*(int*)(src) >= (int)sizeof(*src)) ? (void ) (0) : __assert_fail ("*(int*)(src) >= (int)sizeof(*src)" , "sdp.c", 578, __PRETTY_FUNCTION__)); (r = memcpy((p), (src) , *(int*)(src)), ((p) += *(int*)(src))); | |||
579 | ||||
580 | assert((size_t)(p - *pp) == repeat_xtra(src))(((size_t)(p - *pp) == repeat_xtra(src)) ? (void) (0) : __assert_fail ("(size_t)(p - *pp) == repeat_xtra(src)", "sdp.c", 580, __PRETTY_FUNCTION__ )); | |||
581 | *pp = p; | |||
582 | return r; | |||
583 | } | |||
584 | ||||
585 | ||||
586 | static size_t zone_xtra(sdp_zone_t const *z) | |||
587 | { | |||
588 | return z->z_size; | |||
589 | } | |||
590 | ||||
591 | static | |||
592 | sdp_zone_t *zone_dup(char **pp, sdp_zone_t const *src) | |||
593 | { | |||
594 | char *p; | |||
595 | sdp_zone_t *z; | |||
596 | ||||
597 | p = *pp; | |||
598 | STRUCT_DUP2(p, z, src)(((sizeof(void *) - (intptr_t)(p)) & (sizeof(void *) - 1) ) ? (void)((!"STRUCT_ALIGNED(" "p" ")") ? (void) (0) : __assert_fail ("!\"STRUCT_ALIGNED(\" \"p\" \")\"", "sdp.c", 598, __PRETTY_FUNCTION__ )) : (void)0); ((*(int*)(src) >= (int)sizeof(*src)) ? (void ) (0) : __assert_fail ("*(int*)(src) >= (int)sizeof(*src)" , "sdp.c", 598, __PRETTY_FUNCTION__)); (z = memcpy((p), (src) , *(int*)(src)), ((p) += *(int*)(src))); | |||
599 | ||||
600 | assert((size_t)(p - *pp) == zone_xtra(src))(((size_t)(p - *pp) == zone_xtra(src)) ? (void) (0) : __assert_fail ("(size_t)(p - *pp) == zone_xtra(src)", "sdp.c", 600, __PRETTY_FUNCTION__ )); | |||
601 | *pp = p; | |||
602 | return z; | |||
603 | } | |||
604 | ||||
605 | ||||
606 | static size_t key_xtra(sdp_key_t const *k) | |||
607 | { | |||
608 | size_t rv = sizeof(*k); | |||
609 | STR_XTRA(rv, k->k_method_name)((k->k_method_name) ? rv += strlen((k->k_method_name)) + 1 : 0); | |||
610 | STR_XTRA(rv, k->k_material)((k->k_material) ? rv += strlen((k->k_material)) + 1 : 0 ); | |||
611 | return rv; | |||
612 | } | |||
613 | ||||
614 | static | |||
615 | sdp_key_t *key_dup(char **pp, sdp_key_t const *src) | |||
616 | { | |||
617 | char *p; | |||
618 | sdp_key_t *k; | |||
619 | ||||
620 | p = *pp; | |||
621 | STRUCT_DUP(p, k, src)(((sizeof(void *) - (intptr_t)(p)) & (sizeof(void *) - 1) ) ? (void)((!"STRUCT_ALIGNED(" "p" ")") ? (void) (0) : __assert_fail ("!\"STRUCT_ALIGNED(\" \"p\" \")\"", "sdp.c", 621, __PRETTY_FUNCTION__ )) : (void)0); ((*(int*)(src) >= (int)sizeof(*src) ? (k = memcpy ((p), (src), sizeof(*src))) : (k = memcpy((p), (src), *(int*) (src))), memset((p)+*(int*)(src), 0, sizeof(*src) - *(int*)(src ))), ((p) += sizeof(*src))); | |||
622 | STR_DUP(p, k, src, k_method_name)((src->k_method_name) ? ((k->k_method_name) = strcpy((p ), (src->k_method_name)), (p) += strlen((p)) + 1) : ((k-> k_method_name) = 0)); | |||
623 | STR_DUP(p, k, src, k_material)((src->k_material) ? ((k->k_material) = strcpy((p), (src ->k_material)), (p) += strlen((p)) + 1) : ((k->k_material ) = 0)); | |||
624 | ||||
625 | assert((size_t)(p - *pp) == key_xtra(src))(((size_t)(p - *pp) == key_xtra(src)) ? (void) (0) : __assert_fail ("(size_t)(p - *pp) == key_xtra(src)", "sdp.c", 625, __PRETTY_FUNCTION__ )); | |||
626 | *pp = p; | |||
627 | return k; | |||
628 | } | |||
629 | ||||
630 | ||||
631 | static size_t attribute_xtra(sdp_attribute_t const *a) | |||
632 | { | |||
633 | size_t rv = sizeof(*a); | |||
634 | STR_XTRA(rv, a->a_name)((a->a_name) ? rv += strlen((a->a_name)) + 1 : 0); | |||
635 | STR_XTRA(rv, a->a_value)((a->a_value) ? rv += strlen((a->a_value)) + 1 : 0); | |||
636 | return rv; | |||
637 | } | |||
638 | ||||
639 | static | |||
640 | sdp_attribute_t *attribute_dup(char **pp, sdp_attribute_t const *src) | |||
641 | { | |||
642 | char *p; | |||
643 | sdp_attribute_t *a; | |||
644 | ||||
645 | p = *pp; | |||
646 | STRUCT_DUP(p, a, src)(((sizeof(void *) - (intptr_t)(p)) & (sizeof(void *) - 1) ) ? (void)((!"STRUCT_ALIGNED(" "p" ")") ? (void) (0) : __assert_fail ("!\"STRUCT_ALIGNED(\" \"p\" \")\"", "sdp.c", 646, __PRETTY_FUNCTION__ )) : (void)0); ((*(int*)(src) >= (int)sizeof(*src) ? (a = memcpy ((p), (src), sizeof(*src))) : (a = memcpy((p), (src), *(int*) (src))), memset((p)+*(int*)(src), 0, sizeof(*src) - *(int*)(src ))), ((p) += sizeof(*src))); | |||
647 | a->a_next = NULL((void*)0); | |||
648 | STR_DUP(p, a, src, a_name)((src->a_name) ? ((a->a_name) = strcpy((p), (src->a_name )), (p) += strlen((p)) + 1) : ((a->a_name) = 0)); | |||
649 | STR_DUP(p, a, src, a_value)((src->a_value) ? ((a->a_value) = strcpy((p), (src-> a_value)), (p) += strlen((p)) + 1) : ((a->a_value) = 0)); | |||
650 | ||||
651 | assert((size_t)(p - *pp) == attribute_xtra(src))(((size_t)(p - *pp) == attribute_xtra(src)) ? (void) (0) : __assert_fail ("(size_t)(p - *pp) == attribute_xtra(src)", "sdp.c", 651, __PRETTY_FUNCTION__ )); | |||
652 | *pp = p; | |||
653 | return a; | |||
654 | } | |||
655 | ||||
656 | ||||
657 | static size_t media_xtra(sdp_media_t const *m) | |||
658 | { | |||
659 | size_t rv = sizeof(*m); | |||
660 | ||||
661 | STR_XTRA(rv, m->m_type_name)((m->m_type_name) ? rv += strlen((m->m_type_name)) + 1 : 0); | |||
662 | STR_XTRA(rv, m->m_proto_name)((m->m_proto_name) ? rv += strlen((m->m_proto_name)) + 1 : 0); | |||
663 | LST_XTRA(rv, m->m_format, list_xtra)((m->m_format) ? (rv += ((sizeof(void *) - (intptr_t)(rv)) & (sizeof(void *) - 1)) + list_xtra_all((xtra_f*)list_xtra , m->m_format)) : 0); | |||
664 | LST_XTRA(rv, m->m_rtpmaps, rtpmap_xtra)((m->m_rtpmaps) ? (rv += ((sizeof(void *) - (intptr_t)(rv) ) & (sizeof(void *) - 1)) + list_xtra_all((xtra_f*)rtpmap_xtra , m->m_rtpmaps)) : 0); | |||
665 | STR_XTRA(rv, m->m_information)((m->m_information) ? rv += strlen((m->m_information)) + 1 : 0); | |||
666 | LST_XTRA(rv, m->m_connections, connection_xtra)((m->m_connections) ? (rv += ((sizeof(void *) - (intptr_t) (rv)) & (sizeof(void *) - 1)) + list_xtra_all((xtra_f*)connection_xtra , m->m_connections)) : 0); | |||
667 | LST_XTRA(rv, m->m_bandwidths, bandwidth_xtra)((m->m_bandwidths) ? (rv += ((sizeof(void *) - (intptr_t)( rv)) & (sizeof(void *) - 1)) + list_xtra_all((xtra_f*)bandwidth_xtra , m->m_bandwidths)) : 0); | |||
668 | PTR_XTRA(rv, m->m_key, key_xtra)((m->m_key) ? (rv += ((sizeof(void *) - (intptr_t)(rv)) & (sizeof(void *) - 1)) + key_xtra(m->m_key)) : 0); | |||
669 | LST_XTRA(rv, m->m_attributes, attribute_xtra)((m->m_attributes) ? (rv += ((sizeof(void *) - (intptr_t)( rv)) & (sizeof(void *) - 1)) + list_xtra_all((xtra_f*)attribute_xtra , m->m_attributes)) : 0); | |||
670 | ||||
671 | return rv; | |||
672 | } | |||
673 | ||||
674 | static | |||
675 | sdp_media_t *media_dup(char **pp, | |||
676 | sdp_media_t const *src, | |||
677 | sdp_session_t *sdp) | |||
678 | { | |||
679 | char *p; | |||
680 | sdp_media_t *m; | |||
681 | ||||
682 | p = *pp; | |||
683 | STRUCT_DUP(p, m, src)(((sizeof(void *) - (intptr_t)(p)) & (sizeof(void *) - 1) ) ? (void)((!"STRUCT_ALIGNED(" "p" ")") ? (void) (0) : __assert_fail ("!\"STRUCT_ALIGNED(\" \"p\" \")\"", "sdp.c", 683, __PRETTY_FUNCTION__ )) : (void)0); ((*(int*)(src) >= (int)sizeof(*src) ? (m = memcpy ((p), (src), sizeof(*src))) : (m = memcpy((p), (src), *(int*) (src))), memset((p)+*(int*)(src), 0, sizeof(*src) - *(int*)(src ))), ((p) += sizeof(*src))); | |||
684 | m->m_next = NULL((void*)0); | |||
685 | ||||
686 | STR_DUP(p, m, src, m_type_name)((src->m_type_name) ? ((m->m_type_name) = strcpy((p), ( src->m_type_name)), (p) += strlen((p)) + 1) : ((m->m_type_name ) = 0)); | |||
687 | STR_DUP(p, m, src, m_proto_name)((src->m_proto_name) ? ((m->m_proto_name) = strcpy((p), (src->m_proto_name)), (p) += strlen((p)) + 1) : ((m->m_proto_name ) = 0)); | |||
688 | LST_DUP(p, m, src, m_format, list_dup)((m->m_format) = (src->m_format)?((p += ((sizeof(void * ) - (intptr_t)(p)) & (sizeof(void *) - 1))), list_dup_all ((dup_f*)(list_dup), &(p), src->m_format)) : 0); | |||
689 | LST_DUP(p, m, src, m_rtpmaps, rtpmap_dup)((m->m_rtpmaps) = (src->m_rtpmaps)?((p += ((sizeof(void *) - (intptr_t)(p)) & (sizeof(void *) - 1))), list_dup_all ((dup_f*)(rtpmap_dup), &(p), src->m_rtpmaps)) : 0); | |||
690 | STR_DUP(p, m, src, m_information)((src->m_information) ? ((m->m_information) = strcpy((p ), (src->m_information)), (p) += strlen((p)) + 1) : ((m-> m_information) = 0)); | |||
691 | LST_DUP(p, m, src, m_connections, connection_dup)((m->m_connections) = (src->m_connections)?((p += ((sizeof (void *) - (intptr_t)(p)) & (sizeof(void *) - 1))), list_dup_all ((dup_f*)(connection_dup), &(p), src->m_connections)) : 0); | |||
692 | LST_DUP(p, m, src, m_bandwidths, bandwidth_dup)((m->m_bandwidths) = (src->m_bandwidths)?((p += ((sizeof (void *) - (intptr_t)(p)) & (sizeof(void *) - 1))), list_dup_all ((dup_f*)(bandwidth_dup), &(p), src->m_bandwidths)) : 0 ); | |||
693 | PTR_DUP(p, m, src, m_key, key_dup)((m->m_key) = (src->m_key)?((p += ((sizeof(void *) - (intptr_t )(p)) & (sizeof(void *) - 1))), ((key_dup)(&(p), (src ->m_key)))): 0); | |||
694 | LST_DUP(p, m, src, m_attributes, attribute_dup)((m->m_attributes) = (src->m_attributes)?((p += ((sizeof (void *) - (intptr_t)(p)) & (sizeof(void *) - 1))), list_dup_all ((dup_f*)(attribute_dup), &(p), src->m_attributes)) : 0 ); | |||
695 | ||||
696 | /* note! we must not implicitly use 'src->m_session' as it | |||
697 | might point to a temporary session */ | |||
698 | m->m_session = sdp; | |||
699 | ||||
700 | m->m_rejected = src->m_rejected; | |||
701 | m->m_mode = src->m_mode; | |||
702 | ||||
703 | assert((size_t)(p - *pp) == media_xtra(src))(((size_t)(p - *pp) == media_xtra(src)) ? (void) (0) : __assert_fail ("(size_t)(p - *pp) == media_xtra(src)", "sdp.c", 703, __PRETTY_FUNCTION__ )); | |||
704 | *pp = p; | |||
705 | return m; | |||
706 | } | |||
707 | ||||
708 | #ifdef nomore | |||
709 | static | |||
710 | int media_xtra_ex(sdp_media_t const *m, sdp_connection_t const *c) | |||
711 | { | |||
712 | int rv = 0; | |||
713 | ||||
714 | for (; m; m = m->m_next) { | |||
715 | rv += STRUCT_ALIGN(rv)((sizeof(void *) - (intptr_t)(rv)) & (sizeof(void *) - 1) ); | |||
716 | rv += sizeof(*m); | |||
717 | ||||
718 | STR_XTRA(rv, m->m_type_name)((m->m_type_name) ? rv += strlen((m->m_type_name)) + 1 : 0); | |||
719 | STR_XTRA(rv, m->m_proto_name)((m->m_proto_name) ? rv += strlen((m->m_proto_name)) + 1 : 0); | |||
720 | LST_XTRA(rv, m->m_format, list_xtra)((m->m_format) ? (rv += ((sizeof(void *) - (intptr_t)(rv)) & (sizeof(void *) - 1)) + list_xtra_all((xtra_f*)list_xtra , m->m_format)) : 0); | |||
721 | LST_XTRA(rv, m->m_rtpmaps, rtpmap_xtra)((m->m_rtpmaps) ? (rv += ((sizeof(void *) - (intptr_t)(rv) ) & (sizeof(void *) - 1)) + list_xtra_all((xtra_f*)rtpmap_xtra , m->m_rtpmaps)) : 0); | |||
722 | STR_XTRA(rv, m->m_information)((m->m_information) ? rv += strlen((m->m_information)) + 1 : 0); | |||
723 | if (c != m->m_connections) | |||
724 | LST_XTRA(rv, m->m_connections, connection_xtra)((m->m_connections) ? (rv += ((sizeof(void *) - (intptr_t) (rv)) & (sizeof(void *) - 1)) + list_xtra_all((xtra_f*)connection_xtra , m->m_connections)) : 0); | |||
725 | LST_XTRA(rv, m->m_bandwidths, bandwidth_xtra)((m->m_bandwidths) ? (rv += ((sizeof(void *) - (intptr_t)( rv)) & (sizeof(void *) - 1)) + list_xtra_all((xtra_f*)bandwidth_xtra , m->m_bandwidths)) : 0); | |||
726 | PTR_XTRA(rv, m->m_key, key_xtra)((m->m_key) ? (rv += ((sizeof(void *) - (intptr_t)(rv)) & (sizeof(void *) - 1)) + key_xtra(m->m_key)) : 0); | |||
727 | LST_XTRA(rv, m->m_attributes, attribute_xtra)((m->m_attributes) ? (rv += ((sizeof(void *) - (intptr_t)( rv)) & (sizeof(void *) - 1)) + list_xtra_all((xtra_f*)attribute_xtra , m->m_attributes)) : 0); | |||
728 | } | |||
729 | ||||
730 | return rv; | |||
731 | } | |||
732 | ||||
733 | static | |||
734 | sdp_media_t *media_dup_ex(char **pp, | |||
735 | sdp_media_t const *src, | |||
736 | sdp_session_t *sdp, | |||
737 | sdp_connection_t *dst_c, | |||
738 | sdp_connection_t const *src_c) | |||
739 | { | |||
740 | char *p; | |||
741 | sdp_media_t *retval = NULL((void*)0), *m, **mm = &retval; | |||
742 | int xtra = media_xtra_ex(src, src_c); | |||
743 | ||||
744 | p = *pp; | |||
745 | ||||
746 | for (; src; src = src->m_next) { | |||
747 | p += STRUCT_ALIGN(p)((sizeof(void *) - (intptr_t)(p)) & (sizeof(void *) - 1)); | |||
748 | STRUCT_DUP(p, m, src)(((sizeof(void *) - (intptr_t)(p)) & (sizeof(void *) - 1) ) ? (void)((!"STRUCT_ALIGNED(" "p" ")") ? (void) (0) : __assert_fail ("!\"STRUCT_ALIGNED(\" \"p\" \")\"", "sdp.c", 748, __PRETTY_FUNCTION__ )) : (void)0); ((*(int*)(src) >= (int)sizeof(*src) ? (m = memcpy ((p), (src), sizeof(*src))) : (m = memcpy((p), (src), *(int*) (src))), memset((p)+*(int*)(src), 0, sizeof(*src) - *(int*)(src ))), ((p) += sizeof(*src))); | |||
749 | m->m_next = NULL((void*)0); | |||
750 | ||||
751 | STR_DUP(p, m, src, m_type_name)((src->m_type_name) ? ((m->m_type_name) = strcpy((p), ( src->m_type_name)), (p) += strlen((p)) + 1) : ((m->m_type_name ) = 0)); | |||
752 | STR_DUP(p, m, src, m_proto_name)((src->m_proto_name) ? ((m->m_proto_name) = strcpy((p), (src->m_proto_name)), (p) += strlen((p)) + 1) : ((m->m_proto_name ) = 0)); | |||
753 | LST_DUP(p, m, src, m_format, list_dup)((m->m_format) = (src->m_format)?((p += ((sizeof(void * ) - (intptr_t)(p)) & (sizeof(void *) - 1))), list_dup_all ((dup_f*)(list_dup), &(p), src->m_format)) : 0); | |||
754 | LST_DUP(p, m, src, m_rtpmaps, rtpmap_dup)((m->m_rtpmaps) = (src->m_rtpmaps)?((p += ((sizeof(void *) - (intptr_t)(p)) & (sizeof(void *) - 1))), list_dup_all ((dup_f*)(rtpmap_dup), &(p), src->m_rtpmaps)) : 0); | |||
755 | STR_DUP(p, m, src, m_information)((src->m_information) ? ((m->m_information) = strcpy((p ), (src->m_information)), (p) += strlen((p)) + 1) : ((m-> m_information) = 0)); | |||
756 | if (src_c != src->m_connections) | |||
757 | LST_DUP(p, m, src, m_connections, connection_dup)((m->m_connections) = (src->m_connections)?((p += ((sizeof (void *) - (intptr_t)(p)) & (sizeof(void *) - 1))), list_dup_all ((dup_f*)(connection_dup), &(p), src->m_connections)) : 0); | |||
758 | else | |||
759 | m->m_connections = dst_c; | |||
760 | LST_DUP(p, m, src, m_bandwidths, bandwidth_dup)((m->m_bandwidths) = (src->m_bandwidths)?((p += ((sizeof (void *) - (intptr_t)(p)) & (sizeof(void *) - 1))), list_dup_all ((dup_f*)(bandwidth_dup), &(p), src->m_bandwidths)) : 0 ); | |||
761 | PTR_DUP(p, m, src, m_key, key_dup)((m->m_key) = (src->m_key)?((p += ((sizeof(void *) - (intptr_t )(p)) & (sizeof(void *) - 1))), ((key_dup)(&(p), (src ->m_key)))): 0); | |||
762 | LST_DUP(p, m, src, m_attributes, attribute_dup)((m->m_attributes) = (src->m_attributes)?((p += ((sizeof (void *) - (intptr_t)(p)) & (sizeof(void *) - 1))), list_dup_all ((dup_f*)(attribute_dup), &(p), src->m_attributes)) : 0 ); | |||
763 | ||||
764 | /* note! we must not implicitly use 'src->m_session' as it | |||
765 | might point to a temporary session */ | |||
766 | m->m_session = sdp; | |||
767 | ||||
768 | m->m_rejected = src->m_rejected; | |||
769 | m->m_mode = src->m_mode; | |||
770 | ||||
771 | assert(m)((m) ? (void) (0) : __assert_fail ("m", "sdp.c", 771, __PRETTY_FUNCTION__ )); | |||
772 | *mm = m; mm = &m->m_next; | |||
773 | } | |||
774 | ||||
775 | assert(p - *pp == xtra)((p - *pp == xtra) ? (void) (0) : __assert_fail ("p - *pp == xtra" , "sdp.c", 775, __PRETTY_FUNCTION__)); | |||
776 | ||||
777 | ||||
778 | *pp = p; | |||
779 | ||||
780 | return retval; | |||
781 | } | |||
782 | #endif | |||
783 | ||||
784 | static size_t media_xtra_all(sdp_media_t const *m) | |||
785 | { | |||
786 | size_t rv = 0; | |||
787 | ||||
788 | for (; m; m = m->m_next) { | |||
789 | rv += STRUCT_ALIGN(rv)((sizeof(void *) - (intptr_t)(rv)) & (sizeof(void *) - 1) ); | |||
790 | rv += media_xtra(m); | |||
791 | } | |||
792 | ||||
793 | return rv; | |||
794 | } | |||
795 | ||||
796 | static | |||
797 | sdp_media_t *media_dup_all(char **pp, | |||
798 | sdp_media_t const *src, | |||
799 | sdp_session_t *sdp) | |||
800 | { | |||
801 | char *p; | |||
802 | sdp_media_t *retval = NULL((void*)0), *m, **mm = &retval; | |||
803 | ||||
804 | p = *pp; | |||
805 | ||||
806 | for (; src; src = src->m_next) { | |||
807 | p += STRUCT_ALIGN(p)((sizeof(void *) - (intptr_t)(p)) & (sizeof(void *) - 1)); | |||
808 | m = media_dup(&p, src, sdp); | |||
809 | assert(m)((m) ? (void) (0) : __assert_fail ("m", "sdp.c", 809, __PRETTY_FUNCTION__ )); | |||
810 | *mm = m; mm = &m->m_next; | |||
811 | } | |||
812 | ||||
813 | *pp = p; | |||
814 | ||||
815 | return retval; | |||
816 | } | |||
817 | ||||
818 | static size_t list_xtra(sdp_list_t const *l) | |||
819 | { | |||
820 | size_t rv = sizeof(*l); | |||
821 | rv += strlen(l->l_text) + 1; | |||
822 | return rv; | |||
823 | } | |||
824 | ||||
825 | static | |||
826 | sdp_list_t *list_dup(char **pp, sdp_list_t const *src) | |||
827 | { | |||
828 | char *p; | |||
829 | sdp_list_t *l; | |||
830 | ||||
831 | p = *pp; | |||
832 | STRUCT_DUP(p, l, src)(((sizeof(void *) - (intptr_t)(p)) & (sizeof(void *) - 1) ) ? (void)((!"STRUCT_ALIGNED(" "p" ")") ? (void) (0) : __assert_fail ("!\"STRUCT_ALIGNED(\" \"p\" \")\"", "sdp.c", 832, __PRETTY_FUNCTION__ )) : (void)0); ((*(int*)(src) >= (int)sizeof(*src) ? (l = memcpy ((p), (src), sizeof(*src))) : (l = memcpy((p), (src), *(int*) (src))), memset((p)+*(int*)(src), 0, sizeof(*src) - *(int*)(src ))), ((p) += sizeof(*src))); | |||
833 | l->l_next = NULL((void*)0); | |||
834 | STR_DUP(p, l, src, l_text)((src->l_text) ? ((l->l_text) = strcpy((p), (src->l_text )), (p) += strlen((p)) + 1) : ((l->l_text) = 0)); | |||
835 | ||||
836 | assert((size_t)(p - *pp) == list_xtra(src))(((size_t)(p - *pp) == list_xtra(src)) ? (void) (0) : __assert_fail ("(size_t)(p - *pp) == list_xtra(src)", "sdp.c", 836, __PRETTY_FUNCTION__ )); | |||
837 | *pp = p; | |||
838 | return l; | |||
839 | } | |||
840 | ||||
841 | ||||
842 | static size_t rtpmap_xtra(sdp_rtpmap_t const *rm) | |||
843 | { | |||
844 | size_t rv = sizeof(*rm); | |||
845 | STR_XTRA(rv, rm->rm_encoding)((rm->rm_encoding) ? rv += strlen((rm->rm_encoding)) + 1 : 0); | |||
846 | STR_XTRA(rv, rm->rm_params)((rm->rm_params) ? rv += strlen((rm->rm_params)) + 1 : 0 ); | |||
847 | STR_XTRA(rv, rm->rm_fmtp)((rm->rm_fmtp) ? rv += strlen((rm->rm_fmtp)) + 1 : 0); | |||
848 | return rv; | |||
849 | } | |||
850 | ||||
851 | static | |||
852 | sdp_rtpmap_t *rtpmap_dup(char **pp, sdp_rtpmap_t const *src) | |||
853 | { | |||
854 | char *p; | |||
855 | sdp_rtpmap_t *rm; | |||
856 | ||||
857 | p = *pp; | |||
858 | STRUCT_DUP(p, rm, src)(((sizeof(void *) - (intptr_t)(p)) & (sizeof(void *) - 1) ) ? (void)((!"STRUCT_ALIGNED(" "p" ")") ? (void) (0) : __assert_fail ("!\"STRUCT_ALIGNED(\" \"p\" \")\"", "sdp.c", 858, __PRETTY_FUNCTION__ )) : (void)0); ((*(int*)(src) >= (int)sizeof(*src) ? (rm = memcpy((p), (src), sizeof(*src))) : (rm = memcpy((p), (src), *(int*)(src))), memset((p)+*(int*)(src), 0, sizeof(*src) - * (int*)(src))), ((p) += sizeof(*src))); | |||
859 | rm->rm_next = NULL((void*)0); | |||
860 | STR_DUP(p, rm, src, rm_encoding)((src->rm_encoding) ? ((rm->rm_encoding) = strcpy((p), ( src->rm_encoding)), (p) += strlen((p)) + 1) : ((rm->rm_encoding ) = 0)); | |||
861 | STR_DUP(p, rm, src, rm_params)((src->rm_params) ? ((rm->rm_params) = strcpy((p), (src ->rm_params)), (p) += strlen((p)) + 1) : ((rm->rm_params ) = 0)); | |||
862 | STR_DUP(p, rm, src, rm_fmtp)((src->rm_fmtp) ? ((rm->rm_fmtp) = strcpy((p), (src-> rm_fmtp)), (p) += strlen((p)) + 1) : ((rm->rm_fmtp) = 0)); | |||
863 | ||||
864 | assert((size_t)(p - *pp) == rtpmap_xtra(src))(((size_t)(p - *pp) == rtpmap_xtra(src)) ? (void) (0) : __assert_fail ("(size_t)(p - *pp) == rtpmap_xtra(src)", "sdp.c", 864, __PRETTY_FUNCTION__ )); | |||
865 | *pp = p; | |||
866 | return rm; | |||
867 | } | |||
868 | ||||
869 | /** Return total size of a list, including size of all nodes */ | |||
870 | static size_t list_xtra_all(xtra_f *xtra, void const *v) | |||
871 | { | |||
872 | size_t rv = 0; | |||
873 | sdp_list_t const *l; | |||
874 | ||||
875 | for (l = v; l; l = l->l_next) { | |||
876 | rv += STRUCT_ALIGN(rv)((sizeof(void *) - (intptr_t)(rv)) & (sizeof(void *) - 1) ); | |||
877 | rv += xtra(l); | |||
878 | } | |||
879 | ||||
880 | return rv; | |||
881 | } | |||
882 | ||||
883 | static | |||
884 | void *list_dup_all(dup_f *dup, char **pp, void const *vsrc) | |||
885 | { | |||
886 | char *p; | |||
887 | sdp_list_t const *src; | |||
888 | sdp_list_t *retval = NULL((void*)0), *l, **ll = &retval; | |||
889 | ||||
890 | p = *pp; | |||
891 | ||||
892 | for (src = vsrc; src; src = src->l_next) { | |||
893 | p += STRUCT_ALIGN(p)((sizeof(void *) - (intptr_t)(p)) & (sizeof(void *) - 1)); | |||
894 | l = dup(&p, src); | |||
895 | assert(l)((l) ? (void) (0) : __assert_fail ("l", "sdp.c", 895, __PRETTY_FUNCTION__ )); | |||
896 | *ll = l; ll = &l->l_next; | |||
897 | } | |||
898 | ||||
899 | *pp = p; | |||
900 | ||||
901 | return retval; | |||
902 | } | |||
903 | ||||
904 | #if 0 | |||
905 | static size_t XXX_xtra(sdp_XXX_t const *YYY) | |||
906 | { | |||
907 | size_t rv = sizeof(*YYY); | |||
908 | rv += strlen(YYY->YYY_encoding) + 1; | |||
909 | if (YYY->YYY_params); | |||
910 | rv += strlen(YYY->YYY_params) + 1; | |||
911 | return rv; | |||
912 | } | |||
913 | ||||
914 | static | |||
915 | sdp_XXX_t *XXX_dup(char **pp, sdp_XXX_t const *src) | |||
916 | { | |||
917 | char *p; | |||
918 | sdp_XXX_t *YYY; | |||
919 | ||||
920 | p = *pp; ASSERT_STRUCT_ALIGN(p)(((sizeof(void *) - (intptr_t)(p)) & (sizeof(void *) - 1) ) ? (void)((!"STRUCT_ALIGNED(" "p" ")") ? (void) (0) : __assert_fail ("!\"STRUCT_ALIGNED(\" \"p\" \")\"", "sdp.c", 920, __PRETTY_FUNCTION__ )) : (void)0); | |||
921 | YYY = memcpy(p, src, src->YYY_size); | |||
922 | p += src->YYY_size; | |||
923 | YYY->YYY_next = NULL((void*)0); | |||
924 | ZZZ | |||
925 | *pp = p; | |||
926 | return YYY; | |||
927 | } | |||
928 | ||||
929 | #endif | |||
930 | ||||
931 | static size_t session_xtra(sdp_session_t const *sdp) | |||
932 | { | |||
933 | size_t rv = sizeof(*sdp); | |||
934 | ||||
935 | PTR_XTRA(rv, sdp->sdp_origin, origin_xtra)((sdp->sdp_origin) ? (rv += ((sizeof(void *) - (intptr_t)( rv)) & (sizeof(void *) - 1)) + origin_xtra(sdp->sdp_origin )) : 0); | |||
936 | STR_XTRA(rv, sdp->sdp_subject)((sdp->sdp_subject) ? rv += strlen((sdp->sdp_subject)) + 1 : 0); | |||
937 | STR_XTRA(rv, sdp->sdp_information)((sdp->sdp_information) ? rv += strlen((sdp->sdp_information )) + 1 : 0); | |||
938 | STR_XTRA(rv, sdp->sdp_uri)((sdp->sdp_uri) ? rv += strlen((sdp->sdp_uri)) + 1 : 0); | |||
939 | LST_XTRA(rv, sdp->sdp_emails, list_xtra)((sdp->sdp_emails) ? (rv += ((sizeof(void *) - (intptr_t)( rv)) & (sizeof(void *) - 1)) + list_xtra_all((xtra_f*)list_xtra , sdp->sdp_emails)) : 0); | |||
940 | LST_XTRA(rv, sdp->sdp_phones, list_xtra)((sdp->sdp_phones) ? (rv += ((sizeof(void *) - (intptr_t)( rv)) & (sizeof(void *) - 1)) + list_xtra_all((xtra_f*)list_xtra , sdp->sdp_phones)) : 0); | |||
941 | LST_XTRA(rv, sdp->sdp_connection, connection_xtra)((sdp->sdp_connection) ? (rv += ((sizeof(void *) - (intptr_t )(rv)) & (sizeof(void *) - 1)) + list_xtra_all((xtra_f*)connection_xtra , sdp->sdp_connection)) : 0); | |||
942 | LST_XTRA(rv, sdp->sdp_bandwidths, bandwidth_xtra)((sdp->sdp_bandwidths) ? (rv += ((sizeof(void *) - (intptr_t )(rv)) & (sizeof(void *) - 1)) + list_xtra_all((xtra_f*)bandwidth_xtra , sdp->sdp_bandwidths)) : 0); | |||
943 | LST_XTRA(rv, sdp->sdp_time, time_xtra)((sdp->sdp_time) ? (rv += ((sizeof(void *) - (intptr_t)(rv )) & (sizeof(void *) - 1)) + list_xtra_all((xtra_f*)time_xtra , sdp->sdp_time)) : 0); | |||
944 | PTR_XTRA(rv, sdp->sdp_key, key_xtra)((sdp->sdp_key) ? (rv += ((sizeof(void *) - (intptr_t)(rv) ) & (sizeof(void *) - 1)) + key_xtra(sdp->sdp_key)) : 0 ); | |||
945 | LST_XTRA(rv, sdp->sdp_attributes, attribute_xtra)((sdp->sdp_attributes) ? (rv += ((sizeof(void *) - (intptr_t )(rv)) & (sizeof(void *) - 1)) + list_xtra_all((xtra_f*)attribute_xtra , sdp->sdp_attributes)) : 0); | |||
946 | STR_XTRA(rv, sdp->sdp_charset)((sdp->sdp_charset) ? rv += strlen((sdp->sdp_charset)) + 1 : 0); | |||
947 | MED_XTRA_ALL(rv, sdp->sdp_media)((sdp->sdp_media) ? (rv += ((sizeof(void *) - (intptr_t)(rv )) & (sizeof(void *) - 1)) + media_xtra_all(sdp->sdp_media )) : 0); | |||
948 | ||||
949 | return rv; | |||
950 | } | |||
951 | ||||
952 | static | |||
953 | sdp_session_t *session_dup(char **pp, sdp_session_t const *src) | |||
954 | { | |||
955 | char *p; | |||
956 | sdp_session_t *sdp; | |||
957 | ||||
958 | p = *pp; | |||
959 | STRUCT_DUP(p, sdp, src)(((sizeof(void *) - (intptr_t)(p)) & (sizeof(void *) - 1) ) ? (void)((!"STRUCT_ALIGNED(" "p" ")") ? (void) (0) : __assert_fail ("!\"STRUCT_ALIGNED(\" \"p\" \")\"", "sdp.c", 959, __PRETTY_FUNCTION__ )) : (void)0); ((*(int*)(src) >= (int)sizeof(*src) ? (sdp = memcpy((p), (src), sizeof(*src))) : (sdp = memcpy((p), (src) , *(int*)(src))), memset((p)+*(int*)(src), 0, sizeof(*src) - * (int*)(src))), ((p) += sizeof(*src))); | |||
960 | sdp->sdp_next = NULL((void*)0); | |||
961 | ||||
962 | PTR_DUP(p, sdp, src, sdp_origin, origin_dup)((sdp->sdp_origin) = (src->sdp_origin)?((p += ((sizeof( void *) - (intptr_t)(p)) & (sizeof(void *) - 1))), ((origin_dup )(&(p), (src->sdp_origin)))): 0); | |||
963 | STR_DUP(p, sdp, src, sdp_subject)((src->sdp_subject) ? ((sdp->sdp_subject) = strcpy((p), (src->sdp_subject)), (p) += strlen((p)) + 1) : ((sdp-> sdp_subject) = 0)); | |||
964 | STR_DUP(p, sdp, src, sdp_information)((src->sdp_information) ? ((sdp->sdp_information) = strcpy ((p), (src->sdp_information)), (p) += strlen((p)) + 1) : ( (sdp->sdp_information) = 0)); | |||
965 | STR_DUP(p, sdp, src, sdp_uri)((src->sdp_uri) ? ((sdp->sdp_uri) = strcpy((p), (src-> sdp_uri)), (p) += strlen((p)) + 1) : ((sdp->sdp_uri) = 0)); | |||
966 | LST_DUP(p, sdp, src, sdp_emails, list_dup)((sdp->sdp_emails) = (src->sdp_emails)?((p += ((sizeof( void *) - (intptr_t)(p)) & (sizeof(void *) - 1))), list_dup_all ((dup_f*)(list_dup), &(p), src->sdp_emails)) : 0); | |||
967 | LST_DUP(p, sdp, src, sdp_phones, list_dup)((sdp->sdp_phones) = (src->sdp_phones)?((p += ((sizeof( void *) - (intptr_t)(p)) & (sizeof(void *) - 1))), list_dup_all ((dup_f*)(list_dup), &(p), src->sdp_phones)) : 0); | |||
968 | LST_DUP(p, sdp, src, sdp_connection, connection_dup)((sdp->sdp_connection) = (src->sdp_connection)?((p += ( (sizeof(void *) - (intptr_t)(p)) & (sizeof(void *) - 1))) , list_dup_all((dup_f*)(connection_dup), &(p), src->sdp_connection )) : 0); | |||
969 | LST_DUP(p, sdp, src, sdp_bandwidths, bandwidth_dup)((sdp->sdp_bandwidths) = (src->sdp_bandwidths)?((p += ( (sizeof(void *) - (intptr_t)(p)) & (sizeof(void *) - 1))) , list_dup_all((dup_f*)(bandwidth_dup), &(p), src->sdp_bandwidths )) : 0); | |||
970 | LST_DUP(p, sdp, src, sdp_time, time_dup)((sdp->sdp_time) = (src->sdp_time)?((p += ((sizeof(void *) - (intptr_t)(p)) & (sizeof(void *) - 1))), list_dup_all ((dup_f*)(time_dup), &(p), src->sdp_time)) : 0); | |||
971 | PTR_DUP(p, sdp, src, sdp_key, key_dup)((sdp->sdp_key) = (src->sdp_key)?((p += ((sizeof(void * ) - (intptr_t)(p)) & (sizeof(void *) - 1))), ((key_dup)(& (p), (src->sdp_key)))): 0); | |||
972 | LST_DUP(p, sdp, src, sdp_attributes, attribute_dup)((sdp->sdp_attributes) = (src->sdp_attributes)?((p += ( (sizeof(void *) - (intptr_t)(p)) & (sizeof(void *) - 1))) , list_dup_all((dup_f*)(attribute_dup), &(p), src->sdp_attributes )) : 0); | |||
973 | STR_DUP(p, sdp, src, sdp_charset)((src->sdp_charset) ? ((sdp->sdp_charset) = strcpy((p), (src->sdp_charset)), (p) += strlen((p)) + 1) : ((sdp-> sdp_charset) = 0)); | |||
974 | MED_DUP_ALL(p, sdp, src, sdp_media)((sdp->sdp_media) = (src->sdp_media)?((p += ((sizeof(void *) - (intptr_t)(p)) & (sizeof(void *) - 1))), media_dup_all (&(p), src->sdp_media, sdp)) : 0); | |||
975 | ||||
976 | assert((size_t)(p - *pp) == session_xtra(src))(((size_t)(p - *pp) == session_xtra(src)) ? (void) (0) : __assert_fail ("(size_t)(p - *pp) == session_xtra(src)", "sdp.c", 976, __PRETTY_FUNCTION__ )); | |||
977 | *pp = p; | |||
978 | return sdp; | |||
979 | } | |||
980 | ||||
981 | /**Duplicate an SDP session description. | |||
982 | * | |||
983 | * The function sdp_session_dup() duplicates (deeply copies) an SDP | |||
984 | * session description @a sdp allocating memory using memory @a home. | |||
985 | * | |||
986 | * @param h Memory home | |||
987 | * @param sdp SDP session description to be duplicated | |||
988 | * | |||
989 | * @note The duplicated structure is allocated using a single call to | |||
990 | * su_alloc() and it can be freed with su_free(). | |||
991 | * | |||
992 | * @return | |||
993 | * If successful, a pointer to newly allocated sdp_session_t structure is | |||
994 | * returned, otherwise NULL is returned. | |||
995 | */ | |||
996 | ||||
997 | sdp_session_t *sdp_session_dup(su_home_t *h, sdp_session_t const *sdp) | |||
998 | { | |||
999 | SDP_DUP(session, sdp)sdp_session_t *rv; size_t size; char *p, *end; if (!sdp) return ((void*)0); size = session_xtra(sdp); p = su_alloc(h, size); end = p + size; rv = session_dup(&p, sdp); ((p == end) ? (void) (0) : __assert_fail ("p == end", "sdp.c", 999, __PRETTY_FUNCTION__ )); return rv;; | |||
1000 | } | |||
1001 | ||||
1002 | /* ---------------------------------------------------------------------- */ | |||
1003 | ||||
1004 | static size_t session_without_media_xtra(sdp_session_t const *sdp) | |||
1005 | { | |||
1006 | size_t rv = sizeof(*sdp); | |||
1007 | ||||
1008 | PTR_XTRA(rv, sdp->sdp_origin, origin_xtra)((sdp->sdp_origin) ? (rv += ((sizeof(void *) - (intptr_t)( rv)) & (sizeof(void *) - 1)) + origin_xtra(sdp->sdp_origin )) : 0); | |||
1009 | STR_XTRA(rv, sdp->sdp_subject)((sdp->sdp_subject) ? rv += strlen((sdp->sdp_subject)) + 1 : 0); | |||
1010 | STR_XTRA(rv, sdp->sdp_information)((sdp->sdp_information) ? rv += strlen((sdp->sdp_information )) + 1 : 0); | |||
1011 | STR_XTRA(rv, sdp->sdp_uri)((sdp->sdp_uri) ? rv += strlen((sdp->sdp_uri)) + 1 : 0); | |||
1012 | LST_XTRA(rv, sdp->sdp_emails, list_xtra)((sdp->sdp_emails) ? (rv += ((sizeof(void *) - (intptr_t)( rv)) & (sizeof(void *) - 1)) + list_xtra_all((xtra_f*)list_xtra , sdp->sdp_emails)) : 0); | |||
1013 | LST_XTRA(rv, sdp->sdp_phones, list_xtra)((sdp->sdp_phones) ? (rv += ((sizeof(void *) - (intptr_t)( rv)) & (sizeof(void *) - 1)) + list_xtra_all((xtra_f*)list_xtra , sdp->sdp_phones)) : 0); | |||
1014 | LST_XTRA(rv, sdp->sdp_connection, connection_xtra)((sdp->sdp_connection) ? (rv += ((sizeof(void *) - (intptr_t )(rv)) & (sizeof(void *) - 1)) + list_xtra_all((xtra_f*)connection_xtra , sdp->sdp_connection)) : 0); | |||
1015 | LST_XTRA(rv, sdp->sdp_bandwidths, bandwidth_xtra)((sdp->sdp_bandwidths) ? (rv += ((sizeof(void *) - (intptr_t )(rv)) & (sizeof(void *) - 1)) + list_xtra_all((xtra_f*)bandwidth_xtra , sdp->sdp_bandwidths)) : 0); | |||
1016 | LST_XTRA(rv, sdp->sdp_time, time_xtra)((sdp->sdp_time) ? (rv += ((sizeof(void *) - (intptr_t)(rv )) & (sizeof(void *) - 1)) + list_xtra_all((xtra_f*)time_xtra , sdp->sdp_time)) : 0); | |||
1017 | PTR_XTRA(rv, sdp->sdp_key, key_xtra)((sdp->sdp_key) ? (rv += ((sizeof(void *) - (intptr_t)(rv) ) & (sizeof(void *) - 1)) + key_xtra(sdp->sdp_key)) : 0 ); | |||
1018 | LST_XTRA(rv, sdp->sdp_attributes, attribute_xtra)((sdp->sdp_attributes) ? (rv += ((sizeof(void *) - (intptr_t )(rv)) & (sizeof(void *) - 1)) + list_xtra_all((xtra_f*)attribute_xtra , sdp->sdp_attributes)) : 0); | |||
1019 | STR_XTRA(rv, sdp->sdp_charset)((sdp->sdp_charset) ? rv += strlen((sdp->sdp_charset)) + 1 : 0); | |||
1020 | ||||
1021 | return rv; | |||
1022 | } | |||
1023 | ||||
1024 | static | |||
1025 | sdp_session_t *session_without_media_dup(char **pp, sdp_session_t const *src) | |||
1026 | { | |||
1027 | char *p; | |||
1028 | sdp_session_t *sdp; | |||
1029 | ||||
1030 | p = *pp; | |||
1031 | STRUCT_DUP(p, sdp, src)(((sizeof(void *) - (intptr_t)(p)) & (sizeof(void *) - 1) ) ? (void)((!"STRUCT_ALIGNED(" "p" ")") ? (void) (0) : __assert_fail ("!\"STRUCT_ALIGNED(\" \"p\" \")\"", "sdp.c", 1031, __PRETTY_FUNCTION__ )) : (void)0); ((*(int*)(src) >= (int)sizeof(*src) ? (sdp = memcpy((p), (src), sizeof(*src))) : (sdp = memcpy((p), (src) , *(int*)(src))), memset((p)+*(int*)(src), 0, sizeof(*src) - * (int*)(src))), ((p) += sizeof(*src))); | |||
1032 | sdp->sdp_next = NULL((void*)0); | |||
1033 | ||||
1034 | PTR_DUP(p, sdp, src, sdp_origin, origin_dup)((sdp->sdp_origin) = (src->sdp_origin)?((p += ((sizeof( void *) - (intptr_t)(p)) & (sizeof(void *) - 1))), ((origin_dup )(&(p), (src->sdp_origin)))): 0); | |||
1035 | STR_DUP(p, sdp, src, sdp_subject)((src->sdp_subject) ? ((sdp->sdp_subject) = strcpy((p), (src->sdp_subject)), (p) += strlen((p)) + 1) : ((sdp-> sdp_subject) = 0)); | |||
1036 | STR_DUP(p, sdp, src, sdp_information)((src->sdp_information) ? ((sdp->sdp_information) = strcpy ((p), (src->sdp_information)), (p) += strlen((p)) + 1) : ( (sdp->sdp_information) = 0)); | |||
1037 | STR_DUP(p, sdp, src, sdp_uri)((src->sdp_uri) ? ((sdp->sdp_uri) = strcpy((p), (src-> sdp_uri)), (p) += strlen((p)) + 1) : ((sdp->sdp_uri) = 0)); | |||
1038 | LST_DUP(p, sdp, src, sdp_emails, list_dup)((sdp->sdp_emails) = (src->sdp_emails)?((p += ((sizeof( void *) - (intptr_t)(p)) & (sizeof(void *) - 1))), list_dup_all ((dup_f*)(list_dup), &(p), src->sdp_emails)) : 0); | |||
1039 | LST_DUP(p, sdp, src, sdp_phones, list_dup)((sdp->sdp_phones) = (src->sdp_phones)?((p += ((sizeof( void *) - (intptr_t)(p)) & (sizeof(void *) - 1))), list_dup_all ((dup_f*)(list_dup), &(p), src->sdp_phones)) : 0); | |||
1040 | LST_DUP(p, sdp, src, sdp_connection, connection_dup)((sdp->sdp_connection) = (src->sdp_connection)?((p += ( (sizeof(void *) - (intptr_t)(p)) & (sizeof(void *) - 1))) , list_dup_all((dup_f*)(connection_dup), &(p), src->sdp_connection )) : 0); | |||
1041 | LST_DUP(p, sdp, src, sdp_bandwidths, bandwidth_dup)((sdp->sdp_bandwidths) = (src->sdp_bandwidths)?((p += ( (sizeof(void *) - (intptr_t)(p)) & (sizeof(void *) - 1))) , list_dup_all((dup_f*)(bandwidth_dup), &(p), src->sdp_bandwidths )) : 0); | |||
1042 | LST_DUP(p, sdp, src, sdp_time, time_dup)((sdp->sdp_time) = (src->sdp_time)?((p += ((sizeof(void *) - (intptr_t)(p)) & (sizeof(void *) - 1))), list_dup_all ((dup_f*)(time_dup), &(p), src->sdp_time)) : 0); | |||
1043 | PTR_DUP(p, sdp, src, sdp_key, key_dup)((sdp->sdp_key) = (src->sdp_key)?((p += ((sizeof(void * ) - (intptr_t)(p)) & (sizeof(void *) - 1))), ((key_dup)(& (p), (src->sdp_key)))): 0); | |||
1044 | LST_DUP(p, sdp, src, sdp_attributes, attribute_dup)((sdp->sdp_attributes) = (src->sdp_attributes)?((p += ( (sizeof(void *) - (intptr_t)(p)) & (sizeof(void *) - 1))) , list_dup_all((dup_f*)(attribute_dup), &(p), src->sdp_attributes )) : 0); | |||
1045 | STR_DUP(p, sdp, src, sdp_charset)((src->sdp_charset) ? ((sdp->sdp_charset) = strcpy((p), (src->sdp_charset)), (p) += strlen((p)) + 1) : ((sdp-> sdp_charset) = 0)); | |||
1046 | ||||
1047 | sdp->sdp_media = NULL((void*)0); | |||
1048 | ||||
1049 | assert((size_t)(p - *pp) == session_without_media_xtra(src))(((size_t)(p - *pp) == session_without_media_xtra(src)) ? (void ) (0) : __assert_fail ("(size_t)(p - *pp) == session_without_media_xtra(src)" , "sdp.c", 1049, __PRETTY_FUNCTION__)); | |||
1050 | *pp = p; | |||
1051 | return sdp; | |||
1052 | } | |||
1053 | ||||
1054 | /* SDP_DUP macro requires this */ | |||
1055 | typedef sdp_session_t sdp_session_without_media_t; | |||
1056 | ||||
1057 | /**Duplicate an SDP session description without media descriptions. | |||
1058 | * | |||
1059 | * The function sdp_session_dup() duplicates (deeply copies) an SDP session | |||
1060 | * description @a sdp allocating memory using memory @a home. It does not | |||
1061 | * copy the media descriptions, however. | |||
1062 | * | |||
1063 | * @param h memory h | |||
1064 | * @param sdp SDP session description to be duplicated | |||
1065 | * | |||
1066 | * @note The duplicated structure is allocated using a single call to | |||
1067 | * su_alloc() and it can be freed with su_free(). | |||
1068 | * | |||
1069 | * @return | |||
1070 | * If successful, a pointer to newly allocated sdp_session_t structure is | |||
1071 | * returned, otherwise NULL is returned. | |||
1072 | */ | |||
1073 | ||||
1074 | sdp_session_t *sdp_session_dup_without_media(su_home_t *h, | |||
1075 | sdp_session_t const *sdp) | |||
1076 | { | |||
1077 | SDP_DUP(session_without_media, sdp)sdp_session_without_media_t *rv; size_t size; char *p, *end; if (!sdp) return ((void*)0); size = session_without_media_xtra( sdp); p = su_alloc(h, size); end = p + size; rv = session_without_media_dup (&p, sdp); ((p == end) ? (void) (0) : __assert_fail ("p == end" , "sdp.c", 1077, __PRETTY_FUNCTION__)); return rv;; | |||
1078 | } | |||
1079 | ||||
1080 | /* ---------------------------------------------------------------------- */ | |||
1081 | /* SDP Tag classes */ | |||
1082 | ||||
1083 | #include <sofia-sip/su_tag_class.h> | |||
1084 | ||||
1085 | size_t sdptag_session_xtra(tagi_t const *t, size_t offset) | |||
1086 | { | |||
1087 | sdp_session_t const *sdp = (sdp_session_t *)t->t_value; | |||
1088 | ||||
1089 | if (sdp) | |||
1090 | return STRUCT_ALIGN(offset)((sizeof(void *) - (intptr_t)(offset)) & (sizeof(void *) - 1)) + session_xtra(sdp); | |||
1091 | else | |||
1092 | return 0; | |||
1093 | } | |||
1094 | ||||
1095 | tagi_t *sdptag_session_dup(tagi_t *dst, tagi_t const *src, void **bb) | |||
1096 | { | |||
1097 | sdp_session_t *sdp; | |||
1098 | sdp_session_t const *srcsdp; | |||
1099 | char *b; | |||
1100 | ||||
1101 | assert(src)((src) ? (void) (0) : __assert_fail ("src", "sdp.c", 1101, __PRETTY_FUNCTION__ )); assert(*bb)((*bb) ? (void) (0) : __assert_fail ("*bb", "sdp.c", 1101, __PRETTY_FUNCTION__ )); | |||
1102 | ||||
1103 | b = *bb; | |||
1104 | b += STRUCT_ALIGN(b)((sizeof(void *) - (intptr_t)(b)) & (sizeof(void *) - 1)); | |||
1105 | srcsdp = (sdp_session_t *)src->t_value; | |||
1106 | ||||
1107 | sdp = srcsdp ? session_dup(&b, srcsdp) : NULL((void*)0); | |||
1108 | ||||
1109 | dst->t_tag = src->t_tag; | |||
1110 | dst->t_value = (tag_value_t)sdp; | |||
1111 | ||||
1112 | *bb = b; | |||
1113 | ||||
1114 | return dst + 1; | |||
1115 | } | |||
1116 | ||||
1117 | int sdptag_session_snprintf(tagi_t const *t, char b[], size_t size) | |||
1118 | { | |||
1119 | sdp_session_t const *sdp; | |||
1120 | sdp_printer_t *print; | |||
1121 | size_t retval; | |||
1122 | ||||
1123 | assert(t)((t) ? (void) (0) : __assert_fail ("t", "sdp.c", 1123, __PRETTY_FUNCTION__ )); | |||
1124 | ||||
1125 | if (!t || !t->t_value) { | |||
1126 | if (size && b) b[0] = 0; | |||
1127 | return 0; | |||
1128 | } | |||
1129 | ||||
1130 | sdp = (sdp_session_t const *)t->t_value; | |||
1131 | ||||
1132 | print = sdp_print(NULL((void*)0), sdp, b, size, 0); | |||
1133 | ||||
1134 | retval = sdp_message_size(print); | |||
1135 | ||||
1136 | sdp_printer_free(print); | |||
1137 | ||||
1138 | return (int)retval; | |||
1139 | } | |||
1140 | ||||
1141 | /** Tag class for SDP tags. @HIDE */ | |||
1142 | tag_class_t sdptag_session_class[1] = | |||
1143 | {{ | |||
1144 | sizeof(sdptag_session_class), | |||
1145 | /* tc_next */ NULL((void*)0), | |||
1146 | /* tc_len */ NULL((void*)0), | |||
1147 | /* tc_move */ NULL((void*)0), | |||
1148 | /* tc_xtra */ sdptag_session_xtra, | |||
1149 | /* tc_dup */ sdptag_session_dup, | |||
1150 | /* tc_free */ NULL((void*)0), | |||
1151 | /* tc_find */ NULL((void*)0), | |||
1152 | /* tc_snprintf */ sdptag_session_snprintf, | |||
1153 | /* tc_filter */ NULL((void*)0) /* msgtag_str_filter */, | |||
1154 | /* tc_ref_set */ t_ptr_ref_set, | |||
1155 | }}; | |||
1156 | ||||
1157 | ||||
1158 | /* ---------------------------------------------------------------------- */ | |||
1159 | ||||
1160 | /** Compare two session descriptions | |||
1161 | */ | |||
1162 | int sdp_session_cmp(sdp_session_t const *a, sdp_session_t const *b) | |||
1163 | { | |||
1164 | int rv; | |||
1165 | sdp_bandwidth_t const *ab, *bb; | |||
1166 | sdp_attribute_t const *aa, *ba; | |||
1167 | sdp_media_t const *am, *bm; | |||
1168 | ||||
1169 | if ((rv = (a != NULL((void*)0)) - (b != NULL((void*)0)))) | |||
1170 | return rv; | |||
1171 | if (a == b) | |||
1172 | return 0; | |||
1173 | if ((rv = (a->sdp_version[0] - b->sdp_version[0]))) | |||
1174 | return rv; | |||
1175 | if ((rv = sdp_origin_cmp(a->sdp_origin, b->sdp_origin))) | |||
1176 | return rv; | |||
1177 | if ((rv = su_strcmp(a->sdp_subject, b->sdp_subject))) | |||
1178 | return rv; | |||
1179 | if ((rv = su_strcmp(a->sdp_information, b->sdp_information))) | |||
1180 | return rv; | |||
1181 | if ((rv = su_strcmp(a->sdp_uri, b->sdp_uri))) | |||
1182 | return rv; | |||
1183 | if ((rv = sdp_list_cmp(a->sdp_emails, b->sdp_emails))) | |||
1184 | return rv; | |||
1185 | if ((rv = sdp_list_cmp(a->sdp_phones, b->sdp_phones))) | |||
1186 | return rv; | |||
1187 | if ((rv = sdp_connection_cmp(a->sdp_connection, b->sdp_connection))) | |||
1188 | return rv; | |||
1189 | ||||
1190 | for (ab = a->sdp_bandwidths, bb = b->sdp_bandwidths; | |||
1191 | ab || bb; | |||
1192 | ab = ab->b_next, bb = bb->b_next) | |||
1193 | if ((rv = sdp_bandwidth_cmp(a->sdp_bandwidths, b->sdp_bandwidths))) | |||
1194 | return rv; | |||
1195 | ||||
1196 | if ((rv = sdp_time_cmp(a->sdp_time, b->sdp_time))) | |||
1197 | return rv; | |||
1198 | if ((rv = sdp_key_cmp(a->sdp_key, b->sdp_key))) | |||
1199 | return rv; | |||
1200 | ||||
1201 | for (aa = a->sdp_attributes, ba = b->sdp_attributes; | |||
1202 | aa || bb; | |||
1203 | aa = aa->a_next, ba = ba->a_next) | |||
1204 | if ((rv = sdp_attribute_cmp(aa, ba))) | |||
1205 | return rv; | |||
1206 | ||||
1207 | for (am = a->sdp_media, bm = b->sdp_media; | |||
1208 | am || bm; | |||
1209 | am = am->m_next, bm = bm->m_next) | |||
1210 | if ((rv = sdp_media_cmp(am, bm))) | |||
1211 | return rv; | |||
1212 | ||||
1213 | return 0; | |||
1214 | } | |||
1215 | ||||
1216 | /** Compare two origin fields | |||
1217 | */ | |||
1218 | int sdp_origin_cmp(sdp_origin_t const *a, sdp_origin_t const *b) | |||
1219 | { | |||
1220 | int rv; | |||
1221 | ||||
1222 | if ((rv = (a != NULL((void*)0)) - (b != NULL((void*)0)))) | |||
1223 | return rv; | |||
1224 | if (a == b) | |||
1225 | return 0; | |||
1226 | if (a->o_version != b->o_version) | |||
1227 | return a->o_version < b->o_version ? -1 : 1; | |||
1228 | if (a->o_id != b->o_id) | |||
1229 | return a->o_id < b->o_id ? -1 : 1; | |||
1230 | if ((rv = su_strcasecmp(a->o_username, b->o_username))) | |||
1231 | return rv; | |||
1232 | if ((rv = su_strcasecmp(a->o_address->c_address, b->o_address->c_address))) | |||
1233 | return rv; | |||
1234 | ||||
1235 | return 0; | |||
1236 | } | |||
1237 | ||||
1238 | /** Compare two connection fields | |||
1239 | */ | |||
1240 | int sdp_connection_cmp(sdp_connection_t const *a, sdp_connection_t const *b) | |||
1241 | { | |||
1242 | if (a == b) | |||
1243 | return 0; | |||
1244 | if ((a != NULL((void*)0)) != (b != NULL((void*)0))) | |||
1245 | return (a != NULL((void*)0)) < (b != NULL((void*)0)) ? -1 : 1; | |||
1246 | ||||
1247 | if (a->c_nettype != b->c_nettype) | |||
1248 | return a->c_nettype < b->c_nettype ? -1 : 1; | |||
1249 | if (a->c_addrtype != b->c_addrtype) | |||
1250 | return a->c_addrtype < b->c_addrtype ? -1 : 1; | |||
1251 | if (a->c_ttl != b->c_ttl) | |||
1252 | return a->c_ttl < b->c_ttl ? -1 : 1; | |||
1253 | if (a->c_groups != b->c_groups) | |||
1254 | return a->c_groups < b->c_groups ? -1 : 1; | |||
1255 | ||||
1256 | return strcmp(a->c_address, b->c_address)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (a->c_address) && __builtin_constant_p (b->c_address ) && (__s1_len = __builtin_strlen (a->c_address), __s2_len = __builtin_strlen (b->c_address), (!((size_t)(const void *)((a->c_address) + 1) - (size_t)(const void *)(a->c_address ) == 1) || __s1_len >= 4) && (!((size_t)(const void *)((b->c_address) + 1) - (size_t)(const void *)(b->c_address ) == 1) || __s2_len >= 4)) ? __builtin_strcmp (a->c_address , b->c_address) : (__builtin_constant_p (a->c_address) && ((size_t)(const void *)((a->c_address) + 1) - (size_t)(const void *)(a->c_address) == 1) && (__s1_len = __builtin_strlen (a->c_address), __s1_len < 4) ? (__builtin_constant_p ( b->c_address) && ((size_t)(const void *)((b->c_address ) + 1) - (size_t)(const void *)(b->c_address) == 1) ? __builtin_strcmp (a->c_address, b->c_address) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (b->c_address); int __result = (((const unsigned char *) ( const char *) (a->c_address))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (a->c_address))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (a->c_address))[2] - __s2[2]); if ( __s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (a->c_address))[3] - __s2 [3]); } } __result; }))) : (__builtin_constant_p (b->c_address ) && ((size_t)(const void *)((b->c_address) + 1) - (size_t)(const void *)(b->c_address) == 1) && (__s2_len = __builtin_strlen (b->c_address), __s2_len < 4) ? (__builtin_constant_p (a->c_address) && ((size_t)(const void *)((a-> c_address) + 1) - (size_t)(const void *)(a->c_address) == 1 ) ? __builtin_strcmp (a->c_address, b->c_address) : (- ( __extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (a->c_address); int __result = (((const unsigned char *) (const char *) (b->c_address))[0] - __s2 [0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (b->c_address) )[1] - __s2[1]); if (__s2_len > 1 && __result == 0 ) { __result = (((const unsigned char *) (const char *) (b-> c_address))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (b ->c_address))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (a->c_address, b->c_address)))); }); | |||
1257 | } | |||
1258 | ||||
1259 | /** Compare two bandwidth (b=) fields */ | |||
1260 | int sdp_bandwidth_cmp(sdp_bandwidth_t const *a, sdp_bandwidth_t const *b) | |||
1261 | { | |||
1262 | int rv; | |||
1263 | ||||
1264 | if (a == b) | |||
1265 | return 0; | |||
1266 | if ((a != NULL((void*)0)) != (b != NULL((void*)0))) | |||
1267 | return (a != NULL((void*)0)) < (b != NULL((void*)0)) ? -1 : 1; | |||
1268 | ||||
1269 | if (a->b_modifier != b->b_modifier) | |||
1270 | return a->b_modifier < b->b_modifier ? -1 : 1; | |||
1271 | if (a->b_modifier == sdp_bw_x && | |||
1272 | (rv = strcmp(a->b_modifier_name, b->b_modifier_name)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (a->b_modifier_name) && __builtin_constant_p (b-> b_modifier_name) && (__s1_len = __builtin_strlen (a-> b_modifier_name), __s2_len = __builtin_strlen (b->b_modifier_name ), (!((size_t)(const void *)((a->b_modifier_name) + 1) - ( size_t)(const void *)(a->b_modifier_name) == 1) || __s1_len >= 4) && (!((size_t)(const void *)((b->b_modifier_name ) + 1) - (size_t)(const void *)(b->b_modifier_name) == 1) || __s2_len >= 4)) ? __builtin_strcmp (a->b_modifier_name , b->b_modifier_name) : (__builtin_constant_p (a->b_modifier_name ) && ((size_t)(const void *)((a->b_modifier_name) + 1) - (size_t)(const void *)(a->b_modifier_name) == 1) && (__s1_len = __builtin_strlen (a->b_modifier_name), __s1_len < 4) ? (__builtin_constant_p (b->b_modifier_name) && ((size_t)(const void *)((b->b_modifier_name) + 1) - (size_t )(const void *)(b->b_modifier_name) == 1) ? __builtin_strcmp (a->b_modifier_name, b->b_modifier_name) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (b->b_modifier_name); int __result = (((const unsigned char *) (const char *) (a->b_modifier_name))[0] - __s2[0] ); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (a->b_modifier_name ))[1] - __s2[1]); if (__s1_len > 1 && __result == 0 ) { __result = (((const unsigned char *) (const char *) (a-> b_modifier_name))[2] - __s2[2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (a->b_modifier_name))[3] - __s2[3]); } } __result; })) ) : (__builtin_constant_p (b->b_modifier_name) && ( (size_t)(const void *)((b->b_modifier_name) + 1) - (size_t )(const void *)(b->b_modifier_name) == 1) && (__s2_len = __builtin_strlen (b->b_modifier_name), __s2_len < 4) ? (__builtin_constant_p (a->b_modifier_name) && ( (size_t)(const void *)((a->b_modifier_name) + 1) - (size_t )(const void *)(a->b_modifier_name) == 1) ? __builtin_strcmp (a->b_modifier_name, b->b_modifier_name) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (a->b_modifier_name); int __result = (((const unsigned char *) (const char *) (b->b_modifier_name))[0] - __s2[0] ); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (b->b_modifier_name ))[1] - __s2[1]); if (__s2_len > 1 && __result == 0 ) { __result = (((const unsigned char *) (const char *) (b-> b_modifier_name))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (b->b_modifier_name))[3] - __s2[3]); } } __result; })) )) : __builtin_strcmp (a->b_modifier_name, b->b_modifier_name )))); }))) | |||
1273 | return rv; | |||
1274 | ||||
1275 | if (a->b_value != b->b_value) | |||
1276 | return a->b_value < b->b_value ? -1 : 1; | |||
1277 | ||||
1278 | return 0; | |||
1279 | } | |||
1280 | ||||
1281 | /** Compare two time fields */ | |||
1282 | int sdp_time_cmp(sdp_time_t const *a, sdp_time_t const *b) | |||
1283 | { | |||
1284 | int rv; | |||
1285 | ||||
1286 | if ((rv = (a != NULL((void*)0)) - (b != NULL((void*)0)))) | |||
1287 | return rv; | |||
1288 | if (a == b) | |||
1289 | return 0; | |||
1290 | if (a->t_start != b->t_start) | |||
1291 | return a->t_start < b->t_start ? -1 : 1; | |||
1292 | if (a->t_stop != b->t_stop) | |||
1293 | return a->t_stop < b->t_stop ? -1 : 1; | |||
1294 | if ((rv = sdp_zone_cmp(a->t_zone, b->t_zone))) | |||
1295 | return rv; | |||
1296 | if ((rv = sdp_repeat_cmp(a->t_repeat, b->t_repeat))) | |||
1297 | return rv; | |||
1298 | return 0; | |||
1299 | } | |||
1300 | ||||
1301 | /** Compare two repeat (r=) fields */ | |||
1302 | int sdp_repeat_cmp(sdp_repeat_t const *a, sdp_repeat_t const *b) | |||
1303 | { | |||
1304 | int i, n; | |||
1305 | ||||
1306 | if (a == b) | |||
1307 | return 0; | |||
1308 | if ((a != NULL((void*)0)) != (b != NULL((void*)0))) | |||
1309 | return (a != NULL((void*)0)) < (b != NULL((void*)0)) ? -1 : 1; | |||
1310 | ||||
1311 | if (a->r_interval != b->r_interval) | |||
1312 | return a->r_interval < b->r_interval ? -1 : 1; | |||
1313 | if (a->r_duration != b->r_duration) | |||
1314 | return a->r_duration < b->r_duration ? -1 : 1; | |||
1315 | n = a->r_number_of_offsets < b->r_number_of_offsets | |||
1316 | ? a->r_number_of_offsets : b->r_number_of_offsets; | |||
1317 | for (i = 0; i < n; i++) | |||
1318 | if (a->r_offsets[i] != b->r_offsets[i]) | |||
1319 | return a->r_offsets[i] < b->r_offsets[i] ? -1 : 1; | |||
1320 | ||||
1321 | if (a->r_number_of_offsets != b->r_number_of_offsets) | |||
1322 | return a->r_number_of_offsets < b->r_number_of_offsets ? -1 : 1; | |||
1323 | ||||
1324 | return 0; | |||
1325 | } | |||
1326 | ||||
1327 | /** Compare two zone (z=) fields */ | |||
1328 | int sdp_zone_cmp(sdp_zone_t const *a, sdp_zone_t const *b) | |||
1329 | { | |||
1330 | int i, n; | |||
1331 | ||||
1332 | if (a == b) | |||
1333 | return 0; | |||
1334 | if ((a != NULL((void*)0)) != (b != NULL((void*)0))) | |||
1335 | return (a != NULL((void*)0)) < (b != NULL((void*)0)) ? -1 : 1; | |||
1336 | ||||
1337 | n = a->z_number_of_adjustments < b->z_number_of_adjustments | |||
1338 | ? a->z_number_of_adjustments : b->z_number_of_adjustments; | |||
1339 | for (i = 0; i < n; i++) { | |||
1340 | if (a->z_adjustments[i].z_at != b->z_adjustments[i].z_at) | |||
1341 | return a->z_adjustments[i].z_at < b->z_adjustments[i].z_at ? -1 : 1; | |||
1342 | if (a->z_adjustments[i].z_offset != b->z_adjustments[i].z_offset) | |||
1343 | return a->z_adjustments[i].z_offset < b->z_adjustments[i].z_offset | |||
1344 | ? -1 : 1; | |||
1345 | } | |||
1346 | ||||
1347 | if (a->z_number_of_adjustments != b->z_number_of_adjustments) | |||
1348 | return a->z_number_of_adjustments < b->z_number_of_adjustments ? -1 : 1; | |||
1349 | ||||
1350 | return 0; | |||
1351 | } | |||
1352 | ||||
1353 | /** Compare two key (k=) fields */ | |||
1354 | int sdp_key_cmp(sdp_key_t const *a, sdp_key_t const *b) | |||
1355 | { | |||
1356 | int rv; | |||
1357 | ||||
1358 | if (a == b) | |||
1359 | return 0; | |||
1360 | if ((a != NULL((void*)0)) != (b != NULL((void*)0))) | |||
1361 | return (a != NULL((void*)0)) < (b != NULL((void*)0)) ? -1 : 1; | |||
1362 | ||||
1363 | if (a->k_method != b->k_method) | |||
1364 | return a->k_method < b->k_method ? -1 : 1; | |||
1365 | if (a->k_method == sdp_key_x && | |||
1366 | (rv = su_strcmp(a->k_method_name, b->k_method_name))) | |||
1367 | return rv; | |||
1368 | return su_strcmp(a->k_material, b->k_material); | |||
1369 | } | |||
1370 | ||||
1371 | /** Compare two attribute (a=) fields */ | |||
1372 | int sdp_attribute_cmp(sdp_attribute_t const *a, sdp_attribute_t const *b) | |||
1373 | { | |||
1374 | int rv; | |||
1375 | ||||
1376 | if (a == b) | |||
1377 | return 0; | |||
1378 | if ((a != NULL((void*)0)) != (b != NULL((void*)0))) | |||
1379 | return (a != NULL((void*)0)) < (b != NULL((void*)0)) ? -1 : 1; | |||
1380 | ||||
1381 | if ((rv = su_strcmp(a->a_name, b->a_name))) | |||
1382 | return rv; | |||
1383 | return su_strcmp(a->a_value, b->a_value); | |||
1384 | } | |||
1385 | ||||
1386 | /** Compare two rtpmap structures. */ | |||
1387 | int sdp_rtpmap_cmp(sdp_rtpmap_t const *a, sdp_rtpmap_t const *b) | |||
1388 | { | |||
1389 | int rv; | |||
1390 | ||||
1391 | if (a == b) | |||
1392 | return 0; | |||
1393 | if ((a != NULL((void*)0)) != (b != NULL((void*)0))) | |||
1394 | return (a != NULL((void*)0)) < (b != NULL((void*)0)) ? -1 : 1; | |||
1395 | ||||
1396 | if (a->rm_pt != b->rm_pt) | |||
1397 | return a->rm_pt < b->rm_pt ? -1 : 1; | |||
1398 | ||||
1399 | /* Case insensitive encoding */ | |||
1400 | if ((rv = su_strcmp(a->rm_encoding, b->rm_encoding))) | |||
1401 | return rv; | |||
1402 | /* Rate */ | |||
1403 | if (a->rm_rate != b->rm_rate) | |||
1404 | return a->rm_rate < b->rm_rate ? -1 : 1; | |||
1405 | ||||
1406 | { | |||
1407 | char const *a_param = "1", *b_param = "1"; | |||
1408 | ||||
1409 | if (a->rm_params) | |||
1410 | a_param = a->rm_params; | |||
1411 | if (b->rm_params) | |||
1412 | b_param = b->rm_params; | |||
1413 | ||||
1414 | rv = su_strcasecmp(a_param, b_param); | |||
1415 | ||||
1416 | if (rv) | |||
1417 | return rv; | |||
1418 | } | |||
1419 | ||||
1420 | return su_strcasecmp(a->rm_fmtp, b->rm_fmtp); | |||
1421 | } | |||
1422 | ||||
1423 | /** Compare two lists. */ | |||
1424 | int sdp_list_cmp(sdp_list_t const *a, sdp_list_t const *b) | |||
1425 | { | |||
1426 | int rv; | |||
1427 | ||||
1428 | for (;a || b; a = a->l_next, b = b->l_next) { | |||
1429 | if (a == b) | |||
1430 | return 0; | |||
1431 | if ((a != NULL((void*)0)) != (b != NULL((void*)0))) | |||
1432 | return (a != NULL((void*)0)) < (b != NULL((void*)0)) ? -1 : 1; | |||
1433 | if ((rv = su_strcmp(a->l_text, b->l_text))) | |||
1434 | return rv; | |||
1435 | } | |||
1436 | ||||
1437 | return 0; | |||
1438 | } | |||
1439 | ||||
1440 | /** Compare two media (m=) fields */ | |||
1441 | int sdp_media_cmp(sdp_media_t const *a, sdp_media_t const *b) | |||
1442 | { | |||
1443 | int rv; | |||
1444 | ||||
1445 | sdp_connection_t const *ac, *bc; | |||
1446 | sdp_bandwidth_t const *ab, *bb; | |||
1447 | sdp_rtpmap_t const *arm, *brm; | |||
1448 | sdp_attribute_t const *aa, *ba; | |||
1449 | ||||
1450 | if (a == b) | |||
| ||||
1451 | return 0; | |||
1452 | if ((rv = (a != NULL((void*)0)) - (b != NULL((void*)0)))) | |||
1453 | return rv; | |||
1454 | ||||
1455 | if (a->m_type != b->m_type) | |||
| ||||
1456 | return a->m_type < b->m_type ? -1 : 1; | |||
1457 | if (a->m_type == sdp_media_x) | |||
1458 | if ((rv = su_strcmp(a->m_type_name, b->m_type_name))) | |||
1459 | return rv; | |||
1460 | if (a->m_port != b->m_port) | |||
1461 | return a->m_port < b->m_port ? -1 : 1; | |||
1462 | ||||
1463 | if (a->m_port == 0 /* && b->m_port == 0 */) | |||
1464 | /* Ignore transport protocol and media list if media has been rejected */ | |||
1465 | return 0; | |||
1466 | ||||
1467 | if (a->m_number_of_ports != b->m_number_of_ports) | |||
1468 | return a->m_number_of_ports < b->m_number_of_ports ? -1 : 1; | |||
1469 | ||||
1470 | if (a->m_proto != b->m_proto) | |||
1471 | return a->m_proto < b->m_proto ? -1 : 1; | |||
1472 | if (a->m_proto == sdp_proto_x) | |||
1473 | if ((rv = su_strcmp(a->m_proto_name, b->m_proto_name))) | |||
1474 | return rv; | |||
1475 | ||||
1476 | if (a->m_mode != b->m_mode) | |||
1477 | return a->m_mode < b->m_mode ? -1 : 1; | |||
1478 | ||||
1479 | for (arm = a->m_rtpmaps, brm = b->m_rtpmaps; | |||
1480 | arm || brm; | |||
1481 | arm = arm->rm_next, brm = brm->rm_next) | |||
1482 | if ((rv = sdp_rtpmap_cmp(arm, brm))) | |||
1483 | return rv; | |||
1484 | ||||
1485 | if ((rv = sdp_list_cmp(a->m_format, b->m_format))) | |||
1486 | return rv; | |||
1487 | ||||
1488 | if ((rv = su_strcmp(a->m_information, b->m_information))) | |||
1489 | return rv; | |||
1490 | ||||
1491 | for (ac = a->m_connections, bc = b->m_connections; | |||
1492 | ac || bc; | |||
1493 | ac = ac->c_next, bc = bc->c_next) | |||
1494 | if ((rv = sdp_connection_cmp(ac, bc))) | |||
1495 | return rv; | |||
1496 | ||||
1497 | for (ab = a->m_bandwidths, bb = b->m_bandwidths; | |||
1498 | ab || bb; | |||
1499 | ab = ab->b_next, bb = bb->b_next) | |||
1500 | if ((rv = sdp_bandwidth_cmp(a->m_bandwidths, b->m_bandwidths))) | |||
1501 | return rv; | |||
1502 | ||||
1503 | if ((rv = sdp_key_cmp(a->m_key, b->m_key))) | |||
1504 | return rv; | |||
1505 | ||||
1506 | for (aa = a->m_attributes, ba = b->m_attributes; | |||
1507 | aa || bb; | |||
1508 | aa = aa->a_next, ba = ba->a_next) | |||
1509 | if ((rv = sdp_attribute_cmp(aa, ba))) | |||
1510 | return rv; | |||
1511 | ||||
1512 | return 0; | |||
1513 | } | |||
1514 | ||||
1515 | /* ---------------------------------------------------------------------- */ | |||
1516 | ||||
1517 | sdp_connection_t *sdp_media_connections(sdp_media_t const *m) | |||
1518 | { | |||
1519 | if (m) { | |||
1520 | if (m->m_connections) | |||
1521 | return m->m_connections; | |||
1522 | if (m->m_session) | |||
1523 | return m->m_session->sdp_connection; | |||
1524 | } | |||
1525 | return NULL((void*)0); | |||
1526 | } | |||
1527 | ||||
1528 | /* ---------------------------------------------------------------------- */ | |||
1529 | ||||
1530 | /** Find named attribute from given list. */ | |||
1531 | sdp_attribute_t *sdp_attribute_find(sdp_attribute_t const *a, char const *name) | |||
1532 | { | |||
1533 | for (; a; a = a->a_next) { | |||
1534 | if (su_casematch(a->a_name, name)) | |||
1535 | break; | |||
1536 | } | |||
1537 | ||||
1538 | return (sdp_attribute_t *)a; | |||
1539 | } | |||
1540 | ||||
1541 | /** Find named attribute from given lists (a or a2). */ | |||
1542 | sdp_attribute_t *sdp_attribute_find2(sdp_attribute_t const *a, | |||
1543 | sdp_attribute_t const *a2, | |||
1544 | char const *name) | |||
1545 | { | |||
1546 | for (; a; a = a->a_next) { | |||
1547 | if (su_casematch(a->a_name, name)) | |||
1548 | break; | |||
1549 | } | |||
1550 | ||||
1551 | if (a == 0) | |||
1552 | for (a = a2; a; a = a->a_next) { | |||
1553 | if (su_casematch(a->a_name, name)) | |||
1554 | break; | |||
1555 | } | |||
1556 | ||||
1557 | return (sdp_attribute_t *)a; | |||
1558 | } | |||
1559 | ||||
1560 | /** Get session mode from attribute list. */ | |||
1561 | sdp_mode_t sdp_attribute_mode(sdp_attribute_t const *a, sdp_mode_t defmode) | |||
1562 | { | |||
1563 | for (; a; a = a->a_next) { | |||
1564 | if (su_casematch(a->a_name, "sendrecv")) | |||
1565 | return sdp_sendrecv; | |||
1566 | if (su_casematch(a->a_name, "inactive")) | |||
1567 | return sdp_inactive; | |||
1568 | if (su_casematch(a->a_name, "recvonly")) | |||
1569 | return sdp_recvonly; | |||
1570 | if (su_casematch(a->a_name, "sendonly")) | |||
1571 | return sdp_sendonly; | |||
1572 | } | |||
1573 | ||||
1574 | return defmode; | |||
1575 | } | |||
1576 | ||||
1577 | /** Convert session mode as #sdp_attribute_t structure. */ | |||
1578 | sdp_attribute_t *sdp_attribute_by_mode(su_home_t *home, sdp_mode_t mode) | |||
1579 | { | |||
1580 | sdp_attribute_t *a; | |||
1581 | char const *name; | |||
1582 | ||||
1583 | if (mode == sdp_inactive) | |||
1584 | name = "inactive"; | |||
1585 | else if (mode == sdp_sendonly) | |||
1586 | name = "sendonly"; | |||
1587 | else if (mode == sdp_recvonly) | |||
1588 | name = "recvonly"; | |||
1589 | else if (mode == sdp_sendrecv) | |||
1590 | name = "sendrecv"; | |||
1591 | else | |||
1592 | return NULL((void*)0); | |||
1593 | ||||
1594 | a = su_salloc(home, sizeof(*a)); | |||
1595 | if (a) | |||
1596 | a->a_name = name; | |||
1597 | ||||
1598 | return a; | |||
1599 | } | |||
1600 | ||||
1601 | /** Find a mapped attribute. | |||
1602 | * | |||
1603 | * A mapped attribute has form 'a=<name>:<pt> <value>' where pt is a RTP | |||
1604 | * payload type, integer in range 0..127. For example, "a=atmmap" [@RFC3108] | |||
1605 | * is a mapped attribute. Note that common mapped attributes, "a=rtpmap" and | |||
1606 | * "a=fmtp" are already parsed as list of #sdp_rtpmap_t in #sdp_media_t. | |||
1607 | * | |||
1608 | * @param a pointer to first attribute in the list | |||
1609 | * @param name name of the attribute | |||
1610 | * @param pt payload type number (must be 0..127) | |||
1611 | * @param return_result return value parameter for mapped attribute value | |||
1612 | * | |||
1613 | * @return Pointer to a matching attribute structure, or NULL. | |||
1614 | * | |||
1615 | * If a matching attribute is found, @a return_result will point to part of | |||
1616 | * the attribute after the payload type and whitespace. | |||
1617 | */ | |||
1618 | sdp_attribute_t *sdp_attribute_mapped_find(sdp_attribute_t const *a, | |||
1619 | char const *name, | |||
1620 | int pt, char **return_result) | |||
1621 | { | |||
1622 | char pt_value[4]; | |||
1623 | size_t pt_len; | |||
1624 | ||||
1625 | if (return_result) | |||
1626 | *return_result = NULL((void*)0); | |||
1627 | ||||
1628 | if (0 > pt || pt > 127) | |||
1629 | return NULL((void*)0); | |||
1630 | ||||
1631 | snprintf(pt_value, sizeof(pt_value), "%u", (unsigned)pt); | |||
1632 | pt_len = strlen(pt_value); | |||
1633 | ||||
1634 | for (; (a = sdp_attribute_find(a, name)); a = a->a_next) { | |||
1635 | char const *value = a->a_value; | |||
1636 | size_t wlen; | |||
1637 | ||||
1638 | if (strncmp(value, pt_value, pt_len)(__extension__ (__builtin_constant_p (pt_len) && ((__builtin_constant_p (value) && strlen (value) < ((size_t) (pt_len))) || (__builtin_constant_p (pt_value) && strlen (pt_value ) < ((size_t) (pt_len)))) ? __extension__ ({ size_t __s1_len , __s2_len; (__builtin_constant_p (value) && __builtin_constant_p (pt_value) && (__s1_len = __builtin_strlen (value), __s2_len = __builtin_strlen (pt_value), (!((size_t)(const void *)((value ) + 1) - (size_t)(const void *)(value) == 1) || __s1_len >= 4) && (!((size_t)(const void *)((pt_value) + 1) - (size_t )(const void *)(pt_value) == 1) || __s2_len >= 4)) ? __builtin_strcmp (value, pt_value) : (__builtin_constant_p (value) && ((size_t)(const void *)((value) + 1) - (size_t)(const void * )(value) == 1) && (__s1_len = __builtin_strlen (value ), __s1_len < 4) ? (__builtin_constant_p (pt_value) && ((size_t)(const void *)((pt_value) + 1) - (size_t)(const void *)(pt_value) == 1) ? __builtin_strcmp (value, pt_value) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (pt_value); int __result = (((const unsigned char *) (const char *) (value))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (value))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (value))[2] - __s2[2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (value))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p (pt_value) && ((size_t)(const void *)((pt_value) + 1 ) - (size_t)(const void *)(pt_value) == 1) && (__s2_len = __builtin_strlen (pt_value), __s2_len < 4) ? (__builtin_constant_p (value) && ((size_t)(const void *)((value) + 1) - (size_t )(const void *)(value) == 1) ? __builtin_strcmp (value, pt_value ) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (value); int __result = (((const unsigned char *) (const char *) (pt_value))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (pt_value))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (pt_value))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (pt_value))[3] - __s2[3]); } } __result ; })))) : __builtin_strcmp (value, pt_value)))); }) : strncmp (value, pt_value, pt_len)))) | |||
1639 | continue; | |||
1640 | ||||
1641 | wlen = strspn(value + pt_len, " \t")__extension__ ({ char __a0, __a1, __a2; (__builtin_constant_p (" \t") && ((size_t)(const void *)((" \t") + 1) - (size_t )(const void *)(" \t") == 1) ? ((__builtin_constant_p (value + pt_len) && ((size_t)(const void *)((value + pt_len) + 1) - (size_t)(const void *)(value + pt_len) == 1)) ? __builtin_strspn (value + pt_len, " \t") : ((__a0 = ((const char *) (" \t"))[ 0], __a0 == '\0') ? ((void) (value + pt_len), (size_t) 0) : ( (__a1 = ((const char *) (" \t"))[1], __a1 == '\0') ? __strspn_c1 (value + pt_len, __a0) : ((__a2 = ((const char *) (" \t"))[2 ], __a2 == '\0') ? __strspn_c2 (value + pt_len, __a0, __a1) : (((const char *) (" \t"))[3] == '\0' ? __strspn_c3 (value + pt_len , __a0, __a1, __a2) : __builtin_strspn (value + pt_len, " \t" )))))) : __builtin_strspn (value + pt_len, " \t")); }); | |||
1642 | ||||
1643 | if (wlen == 0 || value[pt_len + wlen] == '\0') | |||
1644 | continue; | |||
1645 | ||||
1646 | if (return_result) | |||
1647 | *return_result = (char *)value + pt_len + wlen; | |||
1648 | ||||
1649 | return (sdp_attribute_t *)a; | |||
1650 | } | |||
1651 | ||||
1652 | return NULL((void*)0); | |||
1653 | } | |||
1654 | ||||
1655 | /** Append a (list of) attribute(s) to a list of attributes. */ | |||
1656 | void sdp_attribute_append(sdp_attribute_t **list, | |||
1657 | sdp_attribute_t const *a) | |||
1658 | { | |||
1659 | assert(list)((list) ? (void) (0) : __assert_fail ("list", "sdp.c", 1659, __PRETTY_FUNCTION__ )); | |||
1660 | ||||
1661 | if (list == NULL((void*)0) || a == NULL((void*)0)) | |||
1662 | return; | |||
1663 | ||||
1664 | for (;*list; list = &(*list)->a_next) | |||
1665 | ; | |||
1666 | ||||
1667 | *list = (sdp_attribute_t *)a; | |||
1668 | } | |||
1669 | ||||
1670 | /**Replace or append a attribute within a list of attributes. | |||
1671 | * | |||
1672 | * @retval 1 if replaced existing attribute | |||
1673 | * @retval 0 if attribute was appended | |||
1674 | * @retval -1 upon an error | |||
1675 | */ | |||
1676 | int sdp_attribute_replace(sdp_attribute_t **list, | |||
1677 | sdp_attribute_t *a, | |||
1678 | sdp_attribute_t **return_replaced) | |||
1679 | { | |||
1680 | sdp_attribute_t *replaced; | |||
1681 | ||||
1682 | assert(list)((list) ? (void) (0) : __assert_fail ("list", "sdp.c", 1682, __PRETTY_FUNCTION__ )); | |||
1683 | ||||
1684 | if (return_replaced) | |||
1685 | *return_replaced = NULL((void*)0); | |||
1686 | ||||
1687 | if (list == NULL((void*)0) || a == NULL((void*)0)) | |||
1688 | return -1; | |||
1689 | ||||
1690 | assert(a->a_name != NULL)((a->a_name != ((void*)0)) ? (void) (0) : __assert_fail ("a->a_name != ((void*)0)" , "sdp.c", 1690, __PRETTY_FUNCTION__)); assert(a->a_next == NULL)((a->a_next == ((void*)0)) ? (void) (0) : __assert_fail ("a->a_next == ((void*)0)" , "sdp.c", 1690, __PRETTY_FUNCTION__)); | |||
1691 | ||||
1692 | for (; *list; list = &(*list)->a_next) { | |||
1693 | if (su_casematch((*list)->a_name, a->a_name)) | |||
1694 | break; | |||
1695 | } | |||
1696 | ||||
1697 | replaced = *list, *list = a; | |||
1698 | ||||
1699 | if (replaced) { | |||
1700 | a->a_next = replaced->a_next; | |||
1701 | replaced->a_next = NULL((void*)0); | |||
1702 | ||||
1703 | if (return_replaced) | |||
1704 | *return_replaced = replaced; | |||
1705 | ||||
1706 | return 1; | |||
1707 | } | |||
1708 | ||||
1709 | return 0; | |||
1710 | } | |||
1711 | ||||
1712 | /** Remove a named attribute from a list of attributes. */ | |||
1713 | sdp_attribute_t *sdp_attribute_remove(sdp_attribute_t **list, | |||
1714 | char const *name) | |||
1715 | { | |||
1716 | sdp_attribute_t *a; | |||
1717 | ||||
1718 | assert(list)((list) ? (void) (0) : __assert_fail ("list", "sdp.c", 1718, __PRETTY_FUNCTION__ )); | |||
1719 | ||||
1720 | if (list == NULL((void*)0)) | |||
1721 | return NULL((void*)0); | |||
1722 | if (name == NULL((void*)0)) | |||
1723 | return NULL((void*)0); | |||
1724 | ||||
1725 | for (a = *list; a; list = &a->a_next, a = *list) { | |||
1726 | if (su_casematch(name, a->a_name)) | |||
1727 | break; | |||
1728 | } | |||
1729 | ||||
1730 | if (a) { | |||
1731 | *list = a->a_next; | |||
1732 | a->a_next = NULL((void*)0); | |||
1733 | } | |||
1734 | ||||
1735 | return a; | |||
1736 | } | |||
1737 | ||||
1738 | /* Return 1 if m= line struct matches with given type and name */ | |||
1739 | unsigned sdp_media_match(sdp_media_t const *m, | |||
1740 | sdp_media_e type, | |||
1741 | sdp_text_t *type_name, | |||
1742 | sdp_proto_e proto, | |||
1743 | sdp_text_t *proto_name) | |||
1744 | { | |||
1745 | if (m == NULL((void*)0)) | |||
1746 | return 0; | |||
1747 | ||||
1748 | if (type == sdp_media_any || m->m_type == sdp_media_any) | |||
1749 | return 1; | |||
1750 | ||||
1751 | if (type_name == NULL((void*)0)) | |||
1752 | type_name = ""; | |||
1753 | ||||
1754 | if (type != m->m_type || | |||
1755 | (type == sdp_media_x && !su_casematch(m->m_type_name, type_name))) | |||
1756 | return 0; | |||
1757 | ||||
1758 | if (proto == sdp_proto_any || m->m_proto == sdp_proto_any) | |||
1759 | return 1; | |||
1760 | ||||
1761 | if (proto_name == NULL((void*)0)) | |||
1762 | proto_name = ""; | |||
1763 | ||||
1764 | if (proto != m->m_proto || | |||
1765 | (proto == sdp_proto_x && !su_casematch(m->m_proto_name, proto_name))) | |||
1766 | return 0; | |||
1767 | ||||
1768 | return 1; | |||
1769 | } | |||
1770 | ||||
1771 | /* Return 1 if media type and protocol of m= line structs matches */ | |||
1772 | unsigned sdp_media_match_with(sdp_media_t const *a, | |||
1773 | sdp_media_t const *b) | |||
1774 | { | |||
1775 | if (a == NULL((void*)0) || b == NULL((void*)0)) | |||
1776 | return a == b; | |||
1777 | ||||
1778 | if (a->m_type == sdp_media_any || b->m_type == sdp_media_any) | |||
1779 | return 1; | |||
1780 | ||||
1781 | if (a->m_type != b->m_type || | |||
1782 | (a->m_type == sdp_media_x | |||
1783 | && !su_casematch(b->m_type_name, a->m_type_name))) | |||
1784 | return 0; | |||
1785 | ||||
1786 | if (a->m_proto == sdp_proto_any || b->m_proto == sdp_proto_any) | |||
1787 | return 1; | |||
1788 | ||||
1789 | if (a->m_proto != b->m_proto || | |||
1790 | (a->m_proto == sdp_proto_x | |||
1791 | && !su_casematch(b->m_proto_name, a->m_proto_name))) | |||
1792 | return 0; | |||
1793 | ||||
1794 | return 1; | |||
1795 | } | |||
1796 | ||||
1797 | ||||
1798 | /** Count matching media lines in SDP. */ | |||
1799 | unsigned sdp_media_count(sdp_session_t const *sdp, | |||
1800 | sdp_media_e type, | |||
1801 | sdp_text_t *type_name, | |||
1802 | sdp_proto_e proto, | |||
1803 | sdp_text_t *proto_name) | |||
1804 | { | |||
1805 | unsigned count = 0; | |||
1806 | sdp_media_t const *m; | |||
1807 | ||||
1808 | if (sdp != NULL((void*)0)) | |||
1809 | for (m = sdp->sdp_media; m; m = m->m_next) | |||
1810 | count += sdp_media_match(m, type, type_name, proto, proto_name); | |||
1811 | ||||
1812 | return count; | |||
1813 | } | |||
1814 | ||||
1815 | /** Count matching media lines in SDP. */ | |||
1816 | unsigned sdp_media_count_with(sdp_session_t const *sdp, | |||
1817 | sdp_media_t const *m0) | |||
1818 | { | |||
1819 | unsigned count = 0; | |||
1820 | sdp_media_t const *m; | |||
1821 | ||||
1822 | if (sdp != NULL((void*)0)) | |||
1823 | for (m = sdp->sdp_media; m; m = m->m_next) | |||
1824 | count += sdp_media_match_with(m, m0); | |||
1825 | ||||
1826 | return count; | |||
1827 | } | |||
1828 | ||||
1829 | /** Return true if media uses RTP */ | |||
1830 | int sdp_media_uses_rtp(sdp_media_t const *m) | |||
1831 | { | |||
1832 | return m && | |||
1833 | (m->m_proto == sdp_proto_rtp || | |||
1834 | m->m_proto == sdp_proto_srtp || m->m_proto == sdp_proto_extended_srtp || | |||
1835 | (m->m_proto == sdp_proto_x && m->m_proto_name && | |||
1836 | su_casenmatch(m->m_proto_name, "RTP/", 4))); | |||
1837 | } | |||
1838 | ||||
1839 | /** Check if payload type, rtp rate and parameters match in rtpmaps*/ | |||
1840 | int sdp_rtpmap_match(sdp_rtpmap_t const *a, sdp_rtpmap_t const *b) | |||
1841 | { | |||
1842 | char const *aparam, *bparam; | |||
1843 | ||||
1844 | if (a == b) | |||
1845 | return 1; | |||
1846 | ||||
1847 | if (a == 0 || b == 0) | |||
1848 | return 0; | |||
1849 | ||||
1850 | if (a->rm_rate != b->rm_rate) | |||
1851 | return 0; | |||
1852 | ||||
1853 | if (!su_casematch(a->rm_encoding, b->rm_encoding)) | |||
1854 | return 0; | |||
1855 | ||||
1856 | aparam = a->rm_params; bparam = b->rm_params; | |||
1857 | ||||
1858 | if (aparam == bparam) | |||
1859 | return 1; | |||
1860 | ||||
1861 | if (!aparam) aparam = "1"; if (!bparam) bparam = "1"; | |||
1862 | ||||
1863 | if (!su_casematch(aparam, bparam)) | |||
1864 | return 0; | |||
1865 | ||||
1866 | return 1; | |||
1867 | } | |||
1868 | ||||
1869 | /** Search for matching rtpmap from list. | |||
1870 | * | |||
1871 | * @note | |||
1872 | * The a=fmtp: for the codecs are not compared. | |||
1873 | */ | |||
1874 | sdp_rtpmap_t *sdp_rtpmap_find_matching(sdp_rtpmap_t const *list, | |||
1875 | sdp_rtpmap_t const *rm) | |||
1876 | { | |||
1877 | char const *lparam, *rparam; | |||
1878 | sdp_rtpmap_t const *cp_list = NULL((void*)0); | |||
1879 | ||||
1880 | if (rm == NULL((void*)0)) | |||
1881 | return NULL((void*)0); | |||
1882 | ||||
1883 | for (; list; list = list->rm_next) { | |||
1884 | if (rm->rm_rate != list->rm_rate) | |||
1885 | continue; | |||
1886 | ||||
1887 | if (!su_casematch(rm->rm_encoding, list->rm_encoding)) | |||
1888 | continue; | |||
1889 | ||||
1890 | lparam = rm->rm_params; rparam = list->rm_params; | |||
1891 | ||||
1892 | if (lparam == rparam) { | |||
1893 | cp_list = list; | |||
1894 | if (rm->rm_pt != list->rm_pt) continue; | |||
1895 | break; | |||
1896 | } | |||
1897 | ||||
1898 | if (!lparam) lparam = "1"; if (!rparam) rparam = "1"; | |||
1899 | if (!su_casematch(lparam, rparam)) | |||
1900 | continue; | |||
1901 | ||||
1902 | break; | |||
1903 | } | |||
1904 | ||||
1905 | return cp_list ? (sdp_rtpmap_t *) cp_list : (sdp_rtpmap_t *)list; | |||
1906 | } |