Bug Summary

File:libs/sofia-sip/libsofia-sip-ua/sdp/sdp.c
Location:line 1247, column 7
Description:Access to field 'c_nettype' results in a dereference of a null pointer (loaded from variable 'a')

Annotated Source Code

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
48struct 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
56const 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
97typedef size_t xtra_f(void const *);
98typedef void *dup_f(char **bb, void const *src);
99
100static size_t list_xtra_all(xtra_f *xtra, void const *v);
101static void *list_dup_all(dup_f *dup, char **bb, void const *vsrc);
102
103static size_t session_xtra(sdp_session_t const *o);
104static sdp_session_t *session_dup(char **pp, sdp_session_t const *o);
105
106static size_t origin_xtra(sdp_origin_t const *o);
107static sdp_origin_t *origin_dup(char **pp, sdp_origin_t const *o);
108
109static size_t connection_xtra(sdp_connection_t const *o);
110static sdp_connection_t *connection_dup(char **pp, sdp_connection_t const *o);
111
112static size_t bandwidth_xtra(sdp_bandwidth_t const *o);
113static sdp_bandwidth_t *bandwidth_dup(char **pp, sdp_bandwidth_t const *o);
114
115static size_t time_xtra(sdp_time_t const *o);
116static sdp_time_t *time_dup(char **pp, sdp_time_t const *o);
117
118static size_t repeat_xtra(sdp_repeat_t const *o);
119static sdp_repeat_t *repeat_dup(char **pp, sdp_repeat_t const *o);
120
121static size_t zone_xtra(sdp_zone_t const *o);
122static sdp_zone_t *zone_dup(char **pp, sdp_zone_t const *o);
123
124static size_t key_xtra(sdp_key_t const *o);
125static sdp_key_t *key_dup(char **pp, sdp_key_t const *o);
126
127static size_t attribute_xtra(sdp_attribute_t const *o);
128static sdp_attribute_t *attribute_dup(char **pp, sdp_attribute_t const *o);
129
130static size_t list_xtra(sdp_list_t const *o);
131static sdp_list_t *list_dup(char **pp, sdp_list_t const *o);
132
133static size_t rtpmap_xtra(sdp_rtpmap_t const *o);
134static sdp_rtpmap_t *rtpmap_dup(char **pp, sdp_rtpmap_t const *o);
135
136static size_t media_xtra(sdp_media_t const *o);
137static sdp_media_t *media_dup(char **pp,
138 sdp_media_t const *o,
139 sdp_session_t *sdp);
140#ifdef nomore
141static size_t media_xtra_ex(sdp_media_t const *o,
142 sdp_connection_t const *c);
143static 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
149static size_t media_xtra_all(sdp_media_t const *o);
150static 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 */
190sdp_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 */
210sdp_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 */
230sdp_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 */
250sdp_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 */
270sdp_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 */
290sdp_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 */
310sdp_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 */
330sdp_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 */
350sdp_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 */
370sdp_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 */
392sdp_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 */
420sdp_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 */
452sdp_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
469static 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
477static
478sdp_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
493static 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
500static
501sdp_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
516static 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
523static
524sdp_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
540static 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
548static
549sdp_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
566static size_t repeat_xtra(sdp_repeat_t const *r)
567{
568 return (size_t)r->r_size;
569}
570
571static
572sdp_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
586static size_t zone_xtra(sdp_zone_t const *z)
587{
588 return z->z_size;
589}
590
591static
592sdp_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
606static 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
614static
615sdp_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
631static 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
639static
640sdp_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
657static 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
674static
675sdp_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
709static
710int 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
733static
734sdp_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
784static 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
796static
797sdp_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
818static 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
825static
826sdp_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
842static 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
851static
852sdp_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 */
870static 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
883static
884void *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
905static 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
914static
915sdp_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
931static 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
952static
953sdp_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
997sdp_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
1004static 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
1024static
1025sdp_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 */
1055typedef 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
1074sdp_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
1085size_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
1095tagi_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
1117int 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 */
1142tag_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 */
1162int 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 */
1218int 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 */
1240int sdp_connection_cmp(sdp_connection_t const *a, sdp_connection_t const *b)
1241{
1242 if (a == b)
1
Assuming 'a' is not equal to 'b'
2
Taking false branch
1243 return 0;
1244 if ((a != NULL((void*)0)) != (b != NULL((void*)0)))
3
Assuming 'a' is equal to null
4
Assuming 'b' is equal to null
5
Taking false branch
1245 return (a != NULL((void*)0)) < (b != NULL((void*)0)) ? -1 : 1;
1246
1247 if (a->c_nettype != b->c_nettype)
6
Access to field 'c_nettype' results in a dereference of a null pointer (loaded from variable 'a')
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 */
1260int 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 */
1282int 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 */
1302int 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 */
1328int 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 */
1354int 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 */
1372int 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. */
1387int 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. */
1424int 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 */
1441int 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
1517sdp_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. */
1531sdp_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). */
1542sdp_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. */
1561sdp_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. */
1578sdp_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 */
1618sdp_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. */
1656void 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 */
1676int 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. */
1713sdp_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 */
1739unsigned 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 */
1772unsigned 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. */
1799unsigned 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. */
1816unsigned 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 */
1830int 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*/
1840int 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 */
1874sdp_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}