Commit fea5f220 authored by Laurent Aimar's avatar Laurent Aimar

Factorized and clean up input_item_t::info_cat_t manipulations.

parent 81d5bdde
/*****************************************************************************
* info.h
*****************************************************************************
* Copyright (C) 2010 Laurent Aimar
* $Id$
*
* Authors: Laurent Aimar <fenrir _AT_ videolan _DOT_ org>
*
* 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.
*****************************************************************************/
#if defined(__PLUGIN__) || defined(__BUILTIN__) || !defined(__LIBVLC__)
# error This header file can only be included from LibVLC.
#endif
#ifndef _INPUT_INFO_H
#define _INPUT_INFO_H 1
#include "vlc_input_item.h"
static inline info_t *info_New(const char *name, const char *value )
{
info_t *info = malloc(sizeof(*info));
if (!info)
return NULL;
info->psz_name = strdup(name);
info->psz_value = value ? strdup(value) : NULL;
return info;
}
static inline void info_Delete(info_t *i)
{
free(i->psz_name);
free(i->psz_value);
free(i);
}
static inline info_category_t *info_category_New(const char *name)
{
info_category_t *cat = malloc(sizeof(*cat));
if (!cat)
return NULL;
cat->psz_name = strdup(name);
cat->i_infos = 0;
cat->pp_infos = NULL;
return cat;
}
static inline info_t *info_category_FindInfo(const info_category_t *cat,
int *index, const char *name)
{
for (int i = 0; i < cat->i_infos; i++) {
if (!strcmp(cat->pp_infos[i]->psz_name, name)) {
if (index)
*index = i;
return cat->pp_infos[i];
}
}
return NULL;
}
static inline void info_category_AddInfo(info_category_t *cat, info_t *info)
{
int index;
if (info_category_FindInfo(cat, &index, info->psz_name)) {
info_Delete(cat->pp_infos[index]);
cat->pp_infos[index] = info;
} else {
INSERT_ELEM(cat->pp_infos, cat->i_infos, cat->i_infos, info);
}
}
static inline info_t *info_category_VaAddInfo(info_category_t *cat,
const char *name,
const char *format, va_list args)
{
info_t *info = info_category_FindInfo(cat, NULL, name);
if (!info) {
info = info_New(name, NULL);
if (!info)
return NULL;
INSERT_ELEM(cat->pp_infos, cat->i_infos, cat->i_infos, info);
} else {
free(info->psz_value);
}
if (vasprintf(&info->psz_value, format, args) == -1)
info->psz_value = NULL;
return info;
}
static inline int info_category_DeleteInfo(info_category_t *cat, const char *name)
{
int index;
if (info_category_FindInfo(cat, &index, name)) {
info_Delete(cat->pp_infos[index]);
REMOVE_ELEM(cat->pp_infos, cat->i_infos, index);
return VLC_SUCCESS;
}
return VLC_EGENERIC;
}
static inline void info_category_Delete(info_category_t *cat)
{
for (int i = 0; i < cat->i_infos; i++)
info_Delete(cat->pp_infos[i]);
free(cat->pp_infos);
free(cat);
}
#endif
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include "vlc_interface.h" #include "vlc_interface.h"
#include "item.h" #include "item.h"
#include "info.h"
static int GuessType( const input_item_t *p_item ); static int GuessType( const input_item_t *p_item );
...@@ -102,23 +103,7 @@ static inline void input_item_Clean( input_item_t *p_i ) ...@@ -102,23 +103,7 @@ static inline void input_item_Clean( input_item_t *p_i )
TAB_CLEAN( p_i->i_epg, p_i->pp_epg ); TAB_CLEAN( p_i->i_epg, p_i->pp_epg );
for( i = 0; i < p_i->i_categories; i++ ) for( i = 0; i < p_i->i_categories; i++ )
{ info_category_Delete( p_i->pp_categories[i] );
info_category_t *p_category = p_i->pp_categories[i];
int j;
for( j = 0; j < p_category->i_infos; j++ )
{
struct info_t *p_info = p_category->pp_infos[j];
free( p_info->psz_name);
free( p_info->psz_value );
free( p_info );
}
TAB_CLEAN( p_category->i_infos, p_category->pp_infos );
free( p_category->psz_name );
free( p_category );
}
TAB_CLEAN( p_i->i_categories, p_i->pp_categories ); TAB_CLEAN( p_i->i_categories, p_i->pp_categories );
vlc_mutex_destroy( &p_i->lock ); vlc_mutex_destroy( &p_i->lock );
...@@ -525,6 +510,24 @@ out: ...@@ -525,6 +510,24 @@ out:
return err; return err;
} }
static info_category_t *InputItemFindCat( input_item_t *p_item,
int *pi_index, const char *psz_cat )
{
vlc_assert_locked( &p_item->lock );
for( int i = 0; i < p_item->i_categories && psz_cat; i++ )
{
info_category_t *p_cat = p_item->pp_categories[i];
if( !strcmp( p_cat->psz_name, psz_cat ) )
{
if( pi_index )
*pi_index = i;
return p_cat;
}
}
return NULL;
}
/** /**
* Get a info item from a given category in a given input item. * Get a info item from a given category in a given input item.
* *
...@@ -541,21 +544,15 @@ char *input_item_GetInfo( input_item_t *p_i, ...@@ -541,21 +544,15 @@ char *input_item_GetInfo( input_item_t *p_i,
{ {
vlc_mutex_lock( &p_i->lock ); vlc_mutex_lock( &p_i->lock );
for( int i = 0; i< p_i->i_categories; i++ ) const info_category_t *p_cat = InputItemFindCat( p_i, NULL, psz_cat );
if( p_cat )
{ {
const info_category_t *p_cat = p_i->pp_categories[i]; info_t *p_info = info_category_FindInfo( p_cat, NULL, psz_name );
if( p_info && p_info->psz_value )
if( !psz_cat || strcmp( p_cat->psz_name, psz_cat ) )
continue;
for( int j = 0; j < p_cat->i_infos; j++ )
{ {
if( !strcmp( p_cat->pp_infos[j]->psz_name, psz_name ) ) char *psz_ret = strdup( p_info->psz_value );
{ vlc_mutex_unlock( &p_i->lock );
char *psz_ret = strdup( p_cat->pp_infos[j]->psz_value ); return psz_ret;
vlc_mutex_unlock( &p_i->lock );
return psz_ret;
}
} }
} }
vlc_mutex_unlock( &p_i->lock ); vlc_mutex_unlock( &p_i->lock );
...@@ -567,58 +564,21 @@ static int InputItemVaAddInfo( input_item_t *p_i, ...@@ -567,58 +564,21 @@ static int InputItemVaAddInfo( input_item_t *p_i,
const char *psz_name, const char *psz_name,
const char *psz_format, va_list args ) const char *psz_format, va_list args )
{ {
int i;
info_t *p_info = NULL;
info_category_t *p_cat = NULL ;
vlc_assert_locked( &p_i->lock ); vlc_assert_locked( &p_i->lock );
for( i = 0 ; i < p_i->i_categories ; i ++ ) info_category_t *p_cat = InputItemFindCat( p_i, NULL, psz_cat );
{
if( !strcmp( p_i->pp_categories[i]->psz_name, psz_cat ) )
{
p_cat = p_i->pp_categories[i];
break;
}
}
if( !p_cat ) if( !p_cat )
{ {
if( !(p_cat = malloc( sizeof(*p_cat) )) ) p_cat = info_category_New( psz_cat );
if( !p_cat )
return VLC_ENOMEM; return VLC_ENOMEM;
p_cat->psz_name = strdup( psz_cat );
p_cat->i_infos = 0;
p_cat->pp_infos = 0;
INSERT_ELEM( p_i->pp_categories, p_i->i_categories, p_i->i_categories, INSERT_ELEM( p_i->pp_categories, p_i->i_categories, p_i->i_categories,
p_cat ); p_cat );
} }
info_t *p_info = info_category_VaAddInfo( p_cat, psz_name, psz_format, args );
for( i = 0; i< p_cat->i_infos; i++ ) if( !p_info || !p_info->psz_value )
{ return VLC_EGENERIC;
if( !strcmp( p_cat->pp_infos[i]->psz_name, psz_name ) ) return VLC_SUCCESS;
{
p_info = p_cat->pp_infos[i];
break;
}
}
if( !p_info )
{
if( ( p_info = malloc( sizeof( *p_info ) ) ) == NULL )
return VLC_ENOMEM;
INSERT_ELEM( p_cat->pp_infos, p_cat->i_infos, p_cat->i_infos, p_info );
p_info->psz_name = strdup( psz_name );
}
else
{
free( p_info->psz_value );
}
if( vasprintf( &p_info->psz_value, psz_format, args ) == -1 )
p_info->psz_value = NULL;
return p_info->psz_value ? VLC_SUCCESS : VLC_ENOMEM;
} }
static int InputItemAddInfo( input_item_t *p_i, static int InputItemAddInfo( input_item_t *p_i,
...@@ -665,21 +625,11 @@ int input_item_DelInfo( input_item_t *p_i, ...@@ -665,21 +625,11 @@ int input_item_DelInfo( input_item_t *p_i,
const char *psz_cat, const char *psz_cat,
const char *psz_name ) const char *psz_name )
{ {
info_category_t *p_cat = NULL;
int i_cat;
int i;
vlc_mutex_lock( &p_i->lock ); vlc_mutex_lock( &p_i->lock );
for( i_cat = 0; i_cat < p_i->i_categories; i_cat++ ) int i_cat;
{ info_category_t *p_cat = InputItemFindCat( p_i, &i_cat, psz_cat );
if( !strcmp( p_i->pp_categories[i_cat]->psz_name, if( !p_cat )
psz_cat ) )
{
p_cat = p_i->pp_categories[i_cat];
break;
}
}
if( p_cat == NULL )
{ {
vlc_mutex_unlock( &p_i->lock ); vlc_mutex_unlock( &p_i->lock );
return VLC_EGENERIC; return VLC_EGENERIC;
...@@ -688,18 +638,8 @@ int input_item_DelInfo( input_item_t *p_i, ...@@ -688,18 +638,8 @@ int input_item_DelInfo( input_item_t *p_i,
if( psz_name ) if( psz_name )
{ {
/* Remove a specific info */ /* Remove a specific info */
for( i = 0; i < p_cat->i_infos; i++ ) int i_ret = info_category_DeleteInfo( p_cat, psz_name );
{ if( i_ret )
if( !strcmp( p_cat->pp_infos[i]->psz_name, psz_name ) )
{
free( p_cat->pp_infos[i]->psz_name );
free( p_cat->pp_infos[i]->psz_value );
free( p_cat->pp_infos[i] );
REMOVE_ELEM( p_cat->pp_infos, p_cat->i_infos, i );
break;
}
}
if( i >= p_cat->i_infos )
{ {
vlc_mutex_unlock( &p_i->lock ); vlc_mutex_unlock( &p_i->lock );
return VLC_EGENERIC; return VLC_EGENERIC;
...@@ -708,16 +648,8 @@ int input_item_DelInfo( input_item_t *p_i, ...@@ -708,16 +648,8 @@ int input_item_DelInfo( input_item_t *p_i,
else else
{ {
/* Remove the complete categorie */ /* Remove the complete categorie */
for( i = 0; i < p_cat->i_infos; i++ ) info_category_Delete( p_cat );
{
free( p_cat->pp_infos[i]->psz_name );
free( p_cat->pp_infos[i]->psz_value );
free( p_cat->pp_infos[i] );
}
free( p_cat->pp_infos );
REMOVE_ELEM( p_i->pp_categories, p_i->i_categories, i_cat ); REMOVE_ELEM( p_i->pp_categories, p_i->i_categories, i_cat );
free( p_cat->psz_name );
free( p_cat );
} }
vlc_mutex_unlock( &p_i->lock ); vlc_mutex_unlock( &p_i->lock );
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment