diff options
Diffstat (limited to 'usr/src/lib/libcommputil/common/sdp_parse_helper.c')
-rw-r--r-- | usr/src/lib/libcommputil/common/sdp_parse_helper.c | 367 |
1 files changed, 367 insertions, 0 deletions
diff --git a/usr/src/lib/libcommputil/common/sdp_parse_helper.c b/usr/src/lib/libcommputil/common/sdp_parse_helper.c new file mode 100644 index 0000000000..ee7ab406fb --- /dev/null +++ b/usr/src/lib/libcommputil/common/sdp_parse_helper.c @@ -0,0 +1,367 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * Helper functions to skip white spaces, find tokens, find separators and free + * memory. + */ + +#include <stdio.h> +#include <assert.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <sdp.h> + +#include "sdp_parse.h" +#include "commp_util.h" + +void +sdp_free_origin(sdp_origin_t *origin) +{ + if (origin != NULL) { + if (origin->o_username != NULL) + free(origin->o_username); + if (origin->o_nettype != NULL) + free(origin->o_nettype); + if (origin->o_addrtype != NULL) + free(origin->o_addrtype); + if (origin->o_address != NULL) + free(origin->o_address); + free(origin); + } +} + +void +sdp_free_key(sdp_key_t *key) +{ + if (key != NULL) { + if (key->k_method != NULL) + free(key->k_method); + if (key->k_enckey != NULL) + free(key->k_enckey); + free(key); + } +} + +void +sdp_free_zone(sdp_zone_t *zone) +{ + sdp_zone_t *next_zone; + + while (zone != NULL) { + next_zone = zone->z_next; + if (zone->z_offset != NULL) + free(zone->z_offset); + free(zone); + zone = next_zone; + } +} + +void +sdp_free_list(sdp_list_t *list) +{ + sdp_list_t *next_list; + + while (list != NULL) { + next_list = list->next; + if (list->value != NULL) + free(list->value); + free(list); + list = next_list; + } +} + +void +sdp_free_media(sdp_media_t *media) +{ + sdp_media_t *next_media; + + while (media != NULL) { + next_media = media->m_next; + if (media->m_name != NULL) + free(media->m_name); + if (media->m_proto != NULL) + free(media->m_proto); + if (media->m_format != NULL) + sdp_free_list(media->m_format); + if (media->m_info != NULL) + free(media->m_info); + if (media->m_conn != NULL) + sdp_free_connection(media->m_conn); + if (media->m_bw != NULL) + sdp_free_bandwidth(media->m_bw); + if (media->m_key != NULL) + sdp_free_key(media->m_key); + if (media->m_attr != NULL) + sdp_free_attribute(media->m_attr); + free(media); + media = next_media; + } +} + +void +sdp_free_attribute(sdp_attr_t *attr) +{ + sdp_attr_t *next_attr; + + while (attr != NULL) { + next_attr = attr->a_next; + if (attr->a_name != NULL) + free(attr->a_name); + if (attr->a_value != NULL) + free(attr->a_value); + free(attr); + attr = next_attr; + } +} + +void +sdp_free_connection(sdp_conn_t *conn) +{ + sdp_conn_t *next_conn; + + while (conn != NULL) { + next_conn = conn->c_next; + if (conn->c_nettype != NULL) + free(conn->c_nettype); + if (conn->c_addrtype != NULL) + free(conn->c_addrtype); + if (conn->c_address != NULL) + free(conn->c_address); + free(conn); + conn = next_conn; + } +} + +void +sdp_free_bandwidth(sdp_bandwidth_t *bw) +{ + sdp_bandwidth_t *next_bw; + + while (bw != NULL) { + next_bw = bw->b_next; + if (bw->b_type != NULL) + free(bw->b_type); + free(bw); + bw = next_bw; + } +} + +void +sdp_free_repeat(sdp_repeat_t *repeat) +{ + sdp_repeat_t *next_repeat; + + while (repeat != NULL) { + next_repeat = repeat->r_next; + sdp_free_list(repeat->r_offset); + free(repeat); + repeat = next_repeat; + } +} + +void +sdp_free_time(sdp_time_t *time) +{ + sdp_time_t *next_time; + + while (time != NULL) { + next_time = time->t_next; + sdp_free_repeat(time->t_repeat); + free(time); + time = next_time; + } +} + +void +sdp_free_session(sdp_session_t *session) +{ + if (session == NULL) + return; + if (session->s_origin != NULL) + sdp_free_origin(session->s_origin); + if (session->s_name != NULL) + free(session->s_name); + if (session->s_info != NULL) + free(session->s_info); + if (session->s_uri != NULL) + free(session->s_uri); + if (session->s_email != NULL) + sdp_free_list(session->s_email); + if (session->s_phone != NULL) + sdp_free_list(session->s_phone); + if (session->s_conn != NULL) + sdp_free_connection(session->s_conn); + if (session->s_bw != NULL) + sdp_free_bandwidth(session->s_bw); + if (session->s_time != NULL) + sdp_free_time(session->s_time); + if (session->s_zone != NULL) + sdp_free_zone(session->s_zone); + if (session->s_key != NULL) + sdp_free_key(session->s_key); + if (session->s_attr != NULL) + sdp_free_attribute(session->s_attr); + if (session->s_media != NULL) + sdp_free_media(session->s_media); + free(session); +} + +/* + * Adds text of a given length to a linked list. If the list is NULL to + * start with it builds the new list + */ +int +add_value_to_list(sdp_list_t **list, const char *value, int len, boolean_t text) +{ + sdp_list_t *new = NULL; + sdp_list_t *tmp = NULL; + + new = malloc(sizeof (sdp_list_t)); + if (new == NULL) + return (ENOMEM); + new->next = NULL; + if (text) + new->value = (char *)calloc(1, len + 1); + else + new->value = (uint64_t *)calloc(1, sizeof (uint64_t)); + if (new->value == NULL) { + free(new); + return (ENOMEM); + } + if (text) { + (void) strncpy(new->value, value, len); + } else { + if (commp_time_to_secs((char *)value, (char *)(value + + len), new->value) != 0) { + sdp_free_list(new); + return (EINVAL); + } + } + if (*list == NULL) { + *list = new; + } else { + tmp = *list; + while (tmp->next != NULL) + tmp = tmp->next; + tmp->next = new; + } + return (0); +} + +/* + * Given a linked list converts it to space separated string. + */ +int +sdp_list_to_str(sdp_list_t *list, char **buf, boolean_t text) +{ + int size = 0; + int wrote = 0; + sdp_list_t *tmp; + char *ret; + char c[1]; + + if (list == NULL) { + *buf = NULL; + return (EINVAL); + } + tmp = list; + while (list != NULL) { + if (text) + size += strlen((char *)list->value); + else + size += snprintf(c, 1, "%lld", + *(uint64_t *)list->value); + size++; + list = list->next; + } + list = tmp; + if (size > 0) { + *buf = calloc(1, size + 1); + if (*buf == NULL) + return (ENOMEM); + ret = *buf; + while (list != NULL) { + if (text) { + wrote = snprintf(ret, size, "%s ", + (char *)list->value); + } else { + wrote = snprintf(ret, size, "%lld ", + *(uint64_t *)list->value); + } + ret = ret + wrote; + size = size - wrote; + list = list->next; + } + } else { + return (EINVAL); + } + return (0); +} + +/* + * Given a space separated string, converts it into linked list. SDP field + * repeat and media can have undefined number of offsets or formats + * respectively. We need to capture it in a linked list. + */ +int +sdp_str_to_list(sdp_list_t **list, const char *buf, int len, boolean_t text) +{ + const char *begin; + const char *current; + const char *end; + int ret = 0; + + if (len == 0) + return (EINVAL); + current = buf; + end = current + len; + /* takes care of strings with just spaces */ + if (commp_skip_white_space(¤t, end) != 0) + return (EINVAL); + while (current < end) { + (void) commp_skip_white_space(¤t, end); + begin = current; + while (current < end) { + if (isspace(*current)) + break; + ++current; + } + if (current != begin) { + if ((ret = add_value_to_list(list, begin, + current - begin, text)) != 0) { + sdp_free_list(*list); + *list = NULL; + return (ret); + } + } + } + return (0); +} |