1 /*****************************************************************************
2 * desc_4d.h: ETSI EN 300 468 Descriptor 0x4d: Short event descriptor
3 *****************************************************************************
4 * Copyright (C) 2011 Unix Solutions Ltd.
5 *
6 * Authors: Georgi Chorbadzhiyski <georgi@unixsol.org>
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining
9 * a copy of this software and associated documentation files (the
10 * "Software"), to deal in the Software without restriction, including
11 * without limitation the rights to use, copy, modify, merge, publish,
12 * distribute, sublicense, and/or sell copies of the Software, and to
13 * permit persons to whom the Software is furnished to do so, subject
14 * to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be
17 * included in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 *****************************************************************************/
27
28 /*
29 * Normative references:
30 * - ETSI EN 300 468 V1.11.1 (2010-04) (SI in DVB systems)
31 */
32
33 #ifndef __BITSTREAM_DVB_DESC_4D_H__
34 #define __BITSTREAM_DVB_DESC_4D_H__
35
36 #include <bitstream/common.h>
37 #include <bitstream/mpeg/psi/descriptors.h>
38 #include <bitstream/dvb/si/numbers.h>
39 #include <bitstream/dvb/si/strings.h>
40
41 #ifdef __cplusplus
42 extern "C"
43 {
44 #endif
45
46 /*****************************************************************************
47 * Descriptor 0x4d: Short event descriptor
48 *****************************************************************************/
49 #define DESC4D_HEADER_SIZE (DESC_HEADER_SIZE + 3)
50
desc4d_init(uint8_t * p_desc)51 static inline void desc4d_init(uint8_t *p_desc)
52 {
53 desc_set_tag(p_desc, 0x4d);
54 }
55
desc4d_get_lang(const uint8_t * p_desc)56 static inline const uint8_t *desc4d_get_lang(const uint8_t *p_desc)
57 {
58 return p_desc + DESC_HEADER_SIZE;
59 }
60
desc4d_set_lang(uint8_t * p_desc,const uint8_t p_lang[3])61 static inline void desc4d_set_lang(uint8_t *p_desc, const uint8_t p_lang[3])
62 {
63 p_desc[2] = p_lang[0];
64 p_desc[3] = p_lang[1];
65 p_desc[4] = p_lang[2];
66 }
67
desc4d_get_event_name(const uint8_t * p_desc,uint8_t * pi_length)68 static inline const uint8_t *desc4d_get_event_name(const uint8_t *p_desc,
69 uint8_t *pi_length)
70 {
71 const uint8_t *p = p_desc + DESC4D_HEADER_SIZE;
72 *pi_length = p[0];
73 return p + 1;
74 }
75
desc4d_set_event_name(uint8_t * p_desc,const uint8_t * p_event_name,uint8_t i_length)76 static inline void desc4d_set_event_name(uint8_t *p_desc,
77 const uint8_t *p_event_name,
78 uint8_t i_length)
79 {
80 uint8_t *p = p_desc + DESC4D_HEADER_SIZE;
81 p[0] = i_length;
82 memcpy(p + 1, p_event_name, i_length);
83 }
84
desc4d_get_text(const uint8_t * p_desc,uint8_t * pi_length)85 static inline uint8_t *desc4d_get_text(const uint8_t *p_desc,
86 uint8_t *pi_length)
87 {
88 const uint8_t *p = (uint8_t *)p_desc + DESC4D_HEADER_SIZE + 1 + p_desc[5];
89 *pi_length = p[0];
90 return (uint8_t *)p + 1;
91 }
92
desc4d_set_text(uint8_t * p_desc,const uint8_t * p_text,uint8_t i_length)93 static inline void desc4d_set_text(uint8_t *p_desc,
94 const uint8_t *p_text,
95 uint8_t i_length)
96 {
97 uint8_t *p = p_desc + DESC4D_HEADER_SIZE + 1 + p_desc[5];
98 p[0] = i_length;
99 memcpy(p + 1, p_text, i_length);
100 }
101
desc4d_set_length(uint8_t * p_desc)102 static inline void desc4d_set_length(uint8_t *p_desc)
103 {
104 uint8_t i_event_name_len, i_text_len;
105 desc4d_get_event_name(p_desc, &i_event_name_len);
106 desc4d_get_text(p_desc, &i_text_len);
107 desc_set_length(p_desc, DESC4D_HEADER_SIZE - DESC_HEADER_SIZE
108 + 1 + i_event_name_len
109 + 1 + i_text_len);
110 }
111
desc4d_validate(const uint8_t * p_desc)112 static inline bool desc4d_validate(const uint8_t *p_desc)
113 {
114 uint8_t i_length = desc_get_length(p_desc);
115 const uint8_t *p = p_desc + DESC4D_HEADER_SIZE;
116
117 p += *p + 1;
118 if (DESC4D_HEADER_SIZE + 2 > i_length + DESC_HEADER_SIZE ||
119 p + 1 - p_desc > i_length + DESC_HEADER_SIZE)
120 return false;
121
122 p += *p + 1;
123 if (p - p_desc > i_length + DESC_HEADER_SIZE)
124 return false;
125
126 return true;
127 }
128
desc4d_print(const uint8_t * p_desc,f_print pf_print,void * print_opaque,f_iconv pf_iconv,void * iconv_opaque,print_type_t i_print_type)129 static inline void desc4d_print(const uint8_t *p_desc,
130 f_print pf_print, void *print_opaque,
131 f_iconv pf_iconv, void *iconv_opaque,
132 print_type_t i_print_type)
133 {
134 uint8_t i_event_name_length, i_text_length;
135 const uint8_t *p_event_name = desc4d_get_event_name(p_desc, &i_event_name_length);
136 const uint8_t *p_text = desc4d_get_text(p_desc, &i_text_length);
137 char *psz_event_name = dvb_string_get(p_event_name, i_event_name_length,
138 pf_iconv, iconv_opaque);
139 char *psz_text = dvb_string_get(p_text, i_text_length,
140 pf_iconv, iconv_opaque);
141 switch (i_print_type) {
142 case PRINT_XML:
143 psz_event_name = dvb_string_xml_escape(psz_event_name);
144 psz_text = dvb_string_xml_escape(psz_text);
145 pf_print(print_opaque,
146 "<SHORT_EVENT_DESC lang=\"%3.3s\" event_name=\"%s\" text=\"%s\"/>",
147 (char *)desc4d_get_lang(p_desc), psz_event_name, psz_text);
148 break;
149 default:
150 pf_print(print_opaque,
151 " - desc 4d short_event lang=%3.3s event_name=\"%s\" text=\"%s\"",
152 (char *)desc4d_get_lang(p_desc), psz_event_name, psz_text);
153 }
154 free(psz_event_name);
155 free(psz_text);
156 }
157
158 #ifdef __cplusplus
159 }
160 #endif
161
162 #endif
163