diff --git a/include/vlc_epg.h b/include/vlc_epg.h index 3313e4a6ba..ded3f7f09f 100644 --- a/include/vlc_epg.h +++ b/include/vlc_epg.h @@ -49,73 +49,48 @@ typedef struct vlc_epg_event_t **pp_event; } vlc_epg_t; -static inline void vlc_epg_Init( vlc_epg_t *p_epg, const char *psz_name ) -{ - p_epg->psz_name = psz_name ? strdup( psz_name ) : NULL; - p_epg->p_current = NULL; - TAB_INIT( p_epg->i_event, p_epg->pp_event ); -} +/** + * It initializes a vlc_epg_t. + * + * You must call vlc_epg_Clean to release the associated resource. + */ +VLC_EXPORT(void, vlc_epg_Init, (vlc_epg_t *p_epg, const char *psz_name)); -static inline void vlc_epg_Clean( vlc_epg_t *p_epg ) -{ - int i; - for( i = 0; i < p_epg->i_event; i++ ) - { - vlc_epg_event_t *p_evt = p_epg->pp_event[i]; - free( p_evt->psz_name ); - free( p_evt->psz_short_description ); - free( p_evt->psz_description ); - free( p_evt ); - } - TAB_CLEAN( p_epg->i_event, p_epg->pp_event ); - free( p_epg->psz_name ); -} - -static inline void vlc_epg_AddEvent( vlc_epg_t *p_epg, int64_t i_start, int i_duration, - const char *psz_name, const char *psz_short_description, const char *psz_description ) -{ - vlc_epg_event_t *p_evt = (vlc_epg_event_t*)malloc( sizeof(vlc_epg_event_t) ); - if( !p_evt ) - return; - p_evt->i_start = i_start; - p_evt->i_duration = i_duration; - p_evt->psz_name = psz_name ? strdup( psz_name ) : NULL; - p_evt->psz_short_description = psz_short_description ? strdup( psz_short_description ) : NULL; - p_evt->psz_description = psz_description ? strdup( psz_description ) : NULL; - TAB_APPEND_CPP( vlc_epg_event_t, p_epg->i_event, p_epg->pp_event, p_evt ); -} - -LIBVLC_USED -static inline vlc_epg_t *vlc_epg_New( const char *psz_name ) -{ - vlc_epg_t *p_epg = (vlc_epg_t*)malloc( sizeof(vlc_epg_t) ); - if( p_epg ) - vlc_epg_Init( p_epg, psz_name ); - return p_epg; -} +/** + * It releases all resources associated to a vlc_epg_t + */ +VLC_EXPORT(void, vlc_epg_Clean, (vlc_epg_t *p_epg)); -static inline void vlc_epg_Delete( vlc_epg_t *p_epg ) -{ - vlc_epg_Clean( p_epg ); - free( p_epg ); -} +/** + * It creates and appends a new vlc_epg_event_t to a vlc_epg_t. + * + * \see vlc_epg_t for the definitions of the parameters. + */ +VLC_EXPORT(void, vlc_epg_AddEvent, (vlc_epg_t *p_epg, int64_t i_start, int i_duration, const char *psz_name, const char *psz_short_description, const char *psz_description)); -static inline void vlc_epg_SetCurrent( vlc_epg_t *p_epg, int64_t i_start ) -{ - int i; - p_epg->p_current = NULL; - if( i_start < 0 ) - return; - - for( i = 0; i < p_epg->i_event; i++ ) - { - if( p_epg->pp_event[i]->i_start == i_start ) - { - p_epg->p_current = p_epg->pp_event[i]; - break; - } - } -} +/** + * It creates a new vlc_epg_t* + * + * You must call vlc_epg_Delete to release the associated resource. + */ +VLC_EXPORT(vlc_epg_t *, vlc_epg_New, (const char *psz_name)); + +/** + * It releases a vlc_epg_t*. + */ +VLC_EXPORT(void, vlc_epg_Delete, (vlc_epg_t *p_epg)); + +/** + * It set the current event of a vlc_epg_t given a start time + */ +VLC_EXPORT(void, vlc_epg_SetCurrent, (vlc_epg_t *p_epg, int64_t i_start)); + +/** + * It merges all the event of \p p_src and \p p_dst into \p p_dst. + * + * \p p_src is not modified. + */ +VLC_EXPORT(void, vlc_epg_Merge, (vlc_epg_t *p_dst, const vlc_epg_t *p_src)); #endif diff --git a/src/Makefile.am b/src/Makefile.am index 8c6c09121c..5f45287572 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -413,6 +413,7 @@ SOURCES_libvlc_common = \ misc/stats.c \ misc/cpu.c \ misc/action.c \ + misc/epg.c \ config/configuration.h \ config/core.c \ config/chain.c \ diff --git a/src/input/es_out.c b/src/input/es_out.c index ab4b5897a8..31a894ba83 100644 --- a/src/input/es_out.c +++ b/src/input/es_out.c @@ -1260,52 +1260,6 @@ static void EsOutProgramMeta( es_out_t *out, int i_group, const vlc_meta_t *p_me free( psz_cat ); } -static void vlc_epg_Merge( vlc_epg_t *p_dst, const vlc_epg_t *p_src ) -{ - int i; - - /* Add new event */ - for( i = 0; i < p_src->i_event; i++ ) - { - vlc_epg_event_t *p_evt = p_src->pp_event[i]; - bool b_add = true; - int j; - - for( j = 0; j < p_dst->i_event; j++ ) - { - if( p_dst->pp_event[j]->i_start == p_evt->i_start && p_dst->pp_event[j]->i_duration == p_evt->i_duration ) - { - b_add = false; - break; - } - if( p_dst->pp_event[j]->i_start > p_evt->i_start ) - break; - } - if( b_add ) - { - vlc_epg_event_t *p_copy = calloc( 1, sizeof(vlc_epg_event_t) ); - if( !p_copy ) - break; - p_copy->i_start = p_evt->i_start; - p_copy->i_duration = p_evt->i_duration; - p_copy->psz_name = p_evt->psz_name ? strdup( p_evt->psz_name ) : NULL; - p_copy->psz_short_description = p_evt->psz_short_description ? strdup( p_evt->psz_short_description ) : NULL; - p_copy->psz_description = p_evt->psz_description ? strdup( p_evt->psz_description ) : NULL; - TAB_INSERT( p_dst->i_event, p_dst->pp_event, p_copy, j ); - } - } - /* Update current */ - if( p_src->p_current ) - vlc_epg_SetCurrent( p_dst, p_src->p_current->i_start ); - - /* Keep only 1 old event */ - if( p_dst->p_current ) - { - while( p_dst->i_event > 1 && p_dst->pp_event[0] != p_dst->p_current && p_dst->pp_event[1] != p_dst->p_current ) - TAB_REMOVE( p_dst->i_event, p_dst->pp_event, p_dst->pp_event[0] ); - } -} - static void EsOutProgramEpg( es_out_t *out, int i_group, const vlc_epg_t *p_epg ) { es_out_sys_t *p_sys = out->p_sys; diff --git a/src/libvlccore.sym b/src/libvlccore.sym index da2f4b65a0..ef24ff34b3 100644 --- a/src/libvlccore.sym +++ b/src/libvlccore.sym @@ -549,6 +549,13 @@ vlc_timer_schedule vlc_ureduce VLC_Version vlc_wclosedir +vlc_epg_Init +vlc_epg_Clean +vlc_epg_New +vlc_epg_Delete +vlc_epg_AddEvent +vlc_epg_SetCurrent +vlc_epg_Merge vlm_Control vlm_Delete vlm_ExecuteCommand diff --git a/src/misc/epg.c b/src/misc/epg.c new file mode 100644 index 0000000000..3074c77e34 --- /dev/null +++ b/src/misc/epg.c @@ -0,0 +1,150 @@ +/***************************************************************************** + * epg.c: Electronic Program Guide + ***************************************************************************** + * Copyright (C) 2007 the VideoLAN team + * $Id$ + * + * Authors: Laurent Aimar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + *****************************************************************************/ + +/***************************************************************************** + * Preamble + *****************************************************************************/ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include +#include + +void vlc_epg_Init( vlc_epg_t *p_epg, const char *psz_name ) +{ + p_epg->psz_name = psz_name ? strdup( psz_name ) : NULL; + p_epg->p_current = NULL; + TAB_INIT( p_epg->i_event, p_epg->pp_event ); +} + +void vlc_epg_Clean( vlc_epg_t *p_epg ) +{ + int i; + for( i = 0; i < p_epg->i_event; i++ ) + { + vlc_epg_event_t *p_evt = p_epg->pp_event[i]; + free( p_evt->psz_name ); + free( p_evt->psz_short_description ); + free( p_evt->psz_description ); + free( p_evt ); + } + TAB_CLEAN( p_epg->i_event, p_epg->pp_event ); + free( p_epg->psz_name ); +} + +void vlc_epg_AddEvent( vlc_epg_t *p_epg, int64_t i_start, int i_duration, + const char *psz_name, const char *psz_short_description, const char *psz_description ) +{ + vlc_epg_event_t *p_evt = (vlc_epg_event_t*)malloc( sizeof(vlc_epg_event_t) ); + if( !p_evt ) + return; + p_evt->i_start = i_start; + p_evt->i_duration = i_duration; + p_evt->psz_name = psz_name ? strdup( psz_name ) : NULL; + p_evt->psz_short_description = psz_short_description ? strdup( psz_short_description ) : NULL; + p_evt->psz_description = psz_description ? strdup( psz_description ) : NULL; + TAB_APPEND_CPP( vlc_epg_event_t, p_epg->i_event, p_epg->pp_event, p_evt ); +} + +vlc_epg_t *vlc_epg_New( const char *psz_name ) +{ + vlc_epg_t *p_epg = (vlc_epg_t*)malloc( sizeof(vlc_epg_t) ); + if( p_epg ) + vlc_epg_Init( p_epg, psz_name ); + return p_epg; +} + +void vlc_epg_Delete( vlc_epg_t *p_epg ) +{ + vlc_epg_Clean( p_epg ); + free( p_epg ); +} + +void vlc_epg_SetCurrent( vlc_epg_t *p_epg, int64_t i_start ) +{ + int i; + p_epg->p_current = NULL; + if( i_start < 0 ) + return; + + for( i = 0; i < p_epg->i_event; i++ ) + { + if( p_epg->pp_event[i]->i_start == i_start ) + { + p_epg->p_current = p_epg->pp_event[i]; + break; + } + } +} + +void vlc_epg_Merge( vlc_epg_t *p_dst, const vlc_epg_t *p_src ) +{ + int i; + + /* Add new event */ + for( i = 0; i < p_src->i_event; i++ ) + { + vlc_epg_event_t *p_evt = p_src->pp_event[i]; + bool b_add = true; + int j; + + for( j = 0; j < p_dst->i_event; j++ ) + { + if( p_dst->pp_event[j]->i_start == p_evt->i_start && p_dst->pp_event[j]->i_duration == p_evt->i_duration ) + { + b_add = false; + break; + } + if( p_dst->pp_event[j]->i_start > p_evt->i_start ) + break; + } + if( b_add ) + { + vlc_epg_event_t *p_copy = calloc( 1, sizeof(vlc_epg_event_t) ); + if( !p_copy ) + break; + p_copy->i_start = p_evt->i_start; + p_copy->i_duration = p_evt->i_duration; + p_copy->psz_name = p_evt->psz_name ? strdup( p_evt->psz_name ) : NULL; + p_copy->psz_short_description = p_evt->psz_short_description ? strdup( p_evt->psz_short_description ) : NULL; + p_copy->psz_description = p_evt->psz_description ? strdup( p_evt->psz_description ) : NULL; + TAB_INSERT( p_dst->i_event, p_dst->pp_event, p_copy, j ); + } + } + /* Update current */ + if( p_src->p_current ) + vlc_epg_SetCurrent( p_dst, p_src->p_current->i_start ); + + /* Keep only 1 old event */ + if( p_dst->p_current ) + { + while( p_dst->i_event > 1 && p_dst->pp_event[0] != p_dst->p_current && p_dst->pp_event[1] != p_dst->p_current ) + TAB_REMOVE( p_dst->i_event, p_dst->pp_event, p_dst->pp_event[0] ); + } +} +