1 /*****************************************************************************
2  * descriptor.c: descriptors functions
3  *----------------------------------------------------------------------------
4  * Copyright (C) 2001-2011 VideoLAN
5  * $Id: descriptor.c,v 1.6 2002/10/07 14:15:14 sam Exp $
6  *
7  * Authors: Arnaud de Bossoreille de Ribou <bozo@via.ecp.fr>
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22  *
23  *----------------------------------------------------------------------------
24  *
25  *****************************************************************************/
26 
27 #include "config.h"
28 
29 #include <stdlib.h>
30 #include <stdbool.h>
31 #include <string.h>
32 
33 #if defined(HAVE_INTTYPES_H)
34 #include <inttypes.h>
35 #elif defined(HAVE_STDINT_H)
36 #include <stdint.h>
37 #endif
38 
39 #include <assert.h>
40 
41 #include "dvbpsi.h"
42 #include "descriptor.h"
43 
44 /*****************************************************************************
45  * dvbpsi_IsDescriptor
46  *****************************************************************************
47  * Is this descriptor of type i_tag?
48  *****************************************************************************/
dvbpsi_IsDescriptor(dvbpsi_descriptor_t * p_descriptor,const uint8_t i_tag)49 static inline bool dvbpsi_IsDescriptor(dvbpsi_descriptor_t *p_descriptor, const uint8_t i_tag)
50 {
51     return (p_descriptor->i_tag == i_tag);
52 }
53 
54 /*****************************************************************************
55  * IsDescriptorDecoded
56  *****************************************************************************
57  * Is this descriptor already decoded?
58  *****************************************************************************/
dvbpsi_IsDescriptorDecoded(dvbpsi_descriptor_t * p_descriptor)59 bool dvbpsi_IsDescriptorDecoded(dvbpsi_descriptor_t *p_descriptor)
60 {
61     return (p_descriptor->p_decoded != NULL);
62 }
63 
64 /*****************************************************************************
65  * dvbpsi_CanDescodeAsDescriptor
66  *****************************************************************************
67  * Can Decode this descriptor as?
68  *****************************************************************************/
dvbpsi_CanDecodeAsDescriptor(dvbpsi_descriptor_t * p_descriptor,const uint8_t i_tag)69 bool dvbpsi_CanDecodeAsDescriptor(dvbpsi_descriptor_t *p_descriptor, const uint8_t i_tag)
70 {
71     if (!p_descriptor)
72         return false;
73 
74     if (!dvbpsi_IsDescriptor(p_descriptor, i_tag))
75         return false;
76 
77     return true;
78 }
79 
80 /*****************************************************************************
81  * dvbpsi_NewDescriptor
82  *****************************************************************************
83  * Creation of a new dvbpsi_descriptor_t structure.
84  *****************************************************************************/
dvbpsi_NewDescriptor(uint8_t i_tag,uint8_t i_length,uint8_t * p_data)85 dvbpsi_descriptor_t* dvbpsi_NewDescriptor(uint8_t i_tag, uint8_t i_length,
86                                           uint8_t* p_data)
87 {
88     dvbpsi_descriptor_t* p_descriptor
89                 = (dvbpsi_descriptor_t*)malloc(sizeof(dvbpsi_descriptor_t));
90 
91     if (p_descriptor == NULL)
92         return NULL;
93 
94     p_descriptor->p_data = (uint8_t*)malloc(i_length * sizeof(uint8_t));
95     if (p_descriptor->p_data)
96     {
97         p_descriptor->i_tag = i_tag;
98         p_descriptor->i_length = i_length;
99         if (p_data)
100             memcpy(p_descriptor->p_data, p_data, i_length);
101         p_descriptor->p_decoded = NULL;
102         p_descriptor->p_next = NULL;
103     }
104     else
105     {
106         free(p_descriptor);
107         p_descriptor = NULL;
108     }
109 
110     return p_descriptor;
111 }
112 
113 /*****************************************************************************
114  * dvbpsi_AddDescriptor
115  *****************************************************************************
116  * Add 'p_descriptor' to the list of descriptors 'p_list'
117  *****************************************************************************/
dvbpsi_AddDescriptor(dvbpsi_descriptor_t * p_list,dvbpsi_descriptor_t * p_descriptor)118 dvbpsi_descriptor_t *dvbpsi_AddDescriptor(dvbpsi_descriptor_t *p_list,
119                                           dvbpsi_descriptor_t *p_descriptor)
120 {
121     assert(p_descriptor);
122 
123     if (p_list == NULL)
124         p_list = p_descriptor;
125     else
126     {
127         dvbpsi_descriptor_t *p_last = p_list;
128         while (p_last->p_next != NULL)
129                 p_last = p_last->p_next;
130         p_last->p_next = p_descriptor;
131     }
132     return p_list;
133 }
134 
135 /*****************************************************************************
136  * dvbpsi_DeleteDescriptors
137  *****************************************************************************
138  * Destruction of a dvbpsi_descriptor_t structure.
139  *****************************************************************************/
dvbpsi_DeleteDescriptors(dvbpsi_descriptor_t * p_descriptor)140 void dvbpsi_DeleteDescriptors(dvbpsi_descriptor_t* p_descriptor)
141 {
142     while(p_descriptor != NULL)
143     {
144         dvbpsi_descriptor_t* p_next = p_descriptor->p_next;
145 
146         if (p_descriptor->p_data != NULL)
147             free(p_descriptor->p_data);
148 
149         if (p_descriptor->p_decoded != NULL)
150             free(p_descriptor->p_decoded);
151 
152         free(p_descriptor);
153         p_descriptor = p_next;
154     }
155 }
156 
157 /*****************************************************************************
158  * dvbpsi_DuplicateDecodedDescriptor
159  *****************************************************************************
160  * Generic function for duplicating a decoded descriptor structure.
161  *****************************************************************************/
dvbpsi_DuplicateDecodedDescriptor(void * p_decoded,ssize_t i_size)162 void *dvbpsi_DuplicateDecodedDescriptor(void *p_decoded, ssize_t i_size)
163 {
164     if (!p_decoded)
165         return NULL;
166 
167     void *p_duplicate = calloc(1, i_size);
168     if (p_duplicate)
169         memcpy(p_duplicate, p_decoded, i_size);
170     return p_duplicate;
171 }
172