| File: | libs/sofia-sip/libsofia-sip-ua/sdp/sdp.c |
| Location: | line 1192, column 13 |
| Description: | Access to field 'b_next' results in a dereference of a null pointer (loaded from variable 'ab') |
| 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 | } |