1 /*****************************************************************************
2 * epg.c: Electronic Program Guide
3 *****************************************************************************
4 * Copyright (C) 2007 VLC authors and VideoLAN
7 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU Lesser General Public License as published by
11 * the Free Software Foundation; either version 2.1 of the License, or
12 * (at your option) any later version.
14 * This program 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
17 * GNU Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
32 #include <vlc_common.h>
35 static void vlc_epg_event_Clean(vlc_epg_event_t
*p_event
)
37 for(int i
=0; i
<p_event
->i_description_items
; i
++)
39 free(p_event
->description_items
[i
].psz_key
);
40 free(p_event
->description_items
[i
].psz_value
);
42 free(p_event
->description_items
);
43 free(p_event
->psz_description
);
44 free(p_event
->psz_short_description
);
45 free(p_event
->psz_name
);
48 void vlc_epg_event_Delete(vlc_epg_event_t
*p_event
)
50 vlc_epg_event_Clean(p_event
);
54 static void vlc_epg_event_Init(vlc_epg_event_t
*p_event
, uint16_t i_id
,
55 int64_t i_start
, uint32_t i_duration
)
57 memset(p_event
, 0, sizeof(*p_event
));
58 p_event
->i_start
= i_start
;
60 p_event
->i_duration
= i_duration
;
61 p_event
->i_description_items
= 0;
62 p_event
->description_items
= NULL
;
65 vlc_epg_event_t
* vlc_epg_event_New(uint16_t i_id
,
66 int64_t i_start
, uint32_t i_duration
)
68 vlc_epg_event_t
*p_event
= (vlc_epg_event_t
*) malloc(sizeof(*p_event
));
70 vlc_epg_event_Init(p_event
, i_id
, i_start
, i_duration
);
75 vlc_epg_event_t
* vlc_epg_event_Duplicate( const vlc_epg_event_t
*p_src
)
77 vlc_epg_event_t
*p_evt
= vlc_epg_event_New( p_src
->i_id
, p_src
->i_start
,
81 if( p_src
->psz_description
)
82 p_evt
->psz_description
= strdup( p_src
->psz_description
);
84 p_evt
->psz_name
= strdup( p_src
->psz_name
);
85 if( p_src
->psz_short_description
)
86 p_evt
->psz_short_description
= strdup( p_src
->psz_short_description
);
87 if( p_src
->i_description_items
)
89 p_evt
->description_items
= malloc( sizeof(*p_evt
->description_items
) *
90 p_src
->i_description_items
);
91 if( p_evt
->description_items
)
93 for( int i
=0; i
<p_src
->i_description_items
; i
++ )
95 p_evt
->description_items
[i
].psz_key
=
96 strdup( p_src
->description_items
[i
].psz_key
);
97 p_evt
->description_items
[i
].psz_value
=
98 strdup( p_src
->description_items
[i
].psz_value
);
99 if(!p_evt
->description_items
[i
].psz_value
||
100 !p_evt
->description_items
[i
].psz_key
)
102 free(p_evt
->description_items
[i
].psz_key
);
103 free(p_evt
->description_items
[i
].psz_value
);
106 p_evt
->i_description_items
++;
110 p_evt
->i_rating
= p_src
->i_rating
;
115 static void vlc_epg_Init( vlc_epg_t
*p_epg
, uint32_t i_id
, uint16_t i_source_id
)
118 p_epg
->i_source_id
= i_source_id
;
119 p_epg
->psz_name
= NULL
;
120 p_epg
->p_current
= NULL
;
121 p_epg
->b_present
= false;
122 TAB_INIT( p_epg
->i_event
, p_epg
->pp_event
);
125 static void vlc_epg_Clean( vlc_epg_t
*p_epg
)
128 for( i
= 0; i
< p_epg
->i_event
; i
++ )
129 vlc_epg_event_Delete( p_epg
->pp_event
[i
] );
130 TAB_CLEAN( p_epg
->i_event
, p_epg
->pp_event
);
131 free( p_epg
->psz_name
);
134 bool vlc_epg_AddEvent( vlc_epg_t
*p_epg
, vlc_epg_event_t
*p_evt
)
138 /* Insertions are supposed in sequential order first */
141 if( p_epg
->pp_event
[0]->i_start
> p_evt
->i_start
)
145 else if ( p_epg
->pp_event
[p_epg
->i_event
- 1]->i_start
>= p_evt
->i_start
)
147 /* Do bisect search lower start time entry */
149 size_t i_upper
= p_epg
->i_event
- 1;
151 while( i_lower
< i_upper
)
153 size_t i_split
= ( i_lower
+ i_upper
) / 2;
154 vlc_epg_event_t
*p_cur
= p_epg
->pp_event
[i_split
];
156 if( p_cur
->i_start
< p_evt
->i_start
)
158 i_lower
= i_split
+ 1;
160 else if ( p_cur
->i_start
>= p_evt
->i_start
)
171 /* There can be only one event at same time */
172 if( p_epg
->pp_event
[i_pos
]->i_start
== p_evt
->i_start
)
174 vlc_epg_event_Delete( p_epg
->pp_event
[i_pos
] );
175 if( p_epg
->p_current
== p_epg
->pp_event
[i_pos
] )
176 p_epg
->p_current
= p_evt
;
177 p_epg
->pp_event
[i_pos
] = p_evt
;
182 TAB_INSERT( p_epg
->i_event
, p_epg
->pp_event
, p_evt
, i_pos
);
186 TAB_APPEND( p_epg
->i_event
, p_epg
->pp_event
, p_evt
);
191 vlc_epg_t
*vlc_epg_New( uint32_t i_id
, uint16_t i_source_id
)
193 vlc_epg_t
*p_epg
= malloc( sizeof(*p_epg
) );
195 vlc_epg_Init( p_epg
, i_id
, i_source_id
);
199 void vlc_epg_Delete( vlc_epg_t
*p_epg
)
201 vlc_epg_Clean( p_epg
);
205 void vlc_epg_SetCurrent( vlc_epg_t
*p_epg
, int64_t i_start
)
208 p_epg
->p_current
= NULL
;
212 for( i
= 0; i
< p_epg
->i_event
; i
++ )
214 if( p_epg
->pp_event
[i
]->i_start
== i_start
)
216 p_epg
->p_current
= p_epg
->pp_event
[i
];
222 vlc_epg_t
* vlc_epg_Duplicate( const vlc_epg_t
*p_src
)
224 vlc_epg_t
*p_epg
= vlc_epg_New( p_src
->i_id
, p_src
->i_source_id
);
227 p_epg
->psz_name
= ( p_src
->psz_name
) ? strdup( p_src
->psz_name
) : NULL
;
228 p_epg
->b_present
= p_src
->b_present
;
229 for( size_t i
=0; i
<p_src
->i_event
; i
++ )
231 vlc_epg_event_t
*p_dup
= vlc_epg_event_Duplicate( p_src
->pp_event
[i
] );
234 if( p_src
->p_current
== p_src
->pp_event
[i
] )
235 p_epg
->p_current
= p_dup
;
236 TAB_APPEND( p_epg
->i_event
, p_epg
->pp_event
, p_dup
);