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