Commit 319e629d authored by Sam Hocevar's avatar Sam Hocevar

* ./include/vlc_common.h: defined the INSERT_ELEM and REMOVE_ELEM macros

    which are a generic use of the realloc/memmove/index++ scheme we use for
    dynamic arrays.
  * ./src/misc/variables.c: properly free the choice list upon variable
    destruction.
parent 1063d36a
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* Collection of useful common types and macros definitions * Collection of useful common types and macros definitions
***************************************************************************** *****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN * Copyright (C) 1998, 1999, 2000 VideoLAN
* $Id: vlc_common.h,v 1.32 2002/10/25 09:21:09 sam Exp $ * $Id: vlc_common.h,v 1.33 2002/10/29 13:22:47 sam Exp $
* *
* Authors: Samuel Hocevar <sam@via.ecp.fr> * Authors: Samuel Hocevar <sam@via.ecp.fr>
* Vincent Seguin <seguin@via.ecp.fr> * Vincent Seguin <seguin@via.ecp.fr>
...@@ -346,6 +346,46 @@ typedef int ( * vlc_callback_t ) ( vlc_object_t *, /* variable's object */ ...@@ -346,6 +346,46 @@ typedef int ( * vlc_callback_t ) ( vlc_object_t *, /* variable's object */
# define __MIN(a, b) ( ((a) < (b)) ? (a) : (b) ) # define __MIN(a, b) ( ((a) < (b)) ? (a) : (b) )
#endif #endif
/* Dynamic array handling: realloc array, move data, increment position */
#define INSERT_ELEM( p_ar, i_oldsize, i_pos, elem ) \
do \
{ \
if( i_oldsize ) \
{ \
(p_ar) = realloc( p_ar, ((i_oldsize) + 1) * sizeof( *(p_ar) ) ); \
} \
else \
{ \
(p_ar) = malloc( ((i_oldsize) + 1) * sizeof( *(p_ar) ) ); \
} \
memmove( (p_ar) + (i_pos) + 1, \
(p_ar) + (i_pos), \
((i_oldsize) - (i_pos)) * sizeof( *(p_ar) ) ); \
(p_ar)[i_pos] = elem; \
(i_oldsize)++; \
} \
while( 0 )
#define REMOVE_ELEM( p_ar, i_oldsize, i_pos ) \
do \
{ \
memmove( (p_ar) + (i_pos), \
(p_ar) + (i_pos) + 1, \
((i_oldsize) - (i_pos) - 1) * sizeof( *(p_ar) ) ); \
if( i_oldsize > 1 ) \
{ \
(p_ar) = realloc( p_ar, ((i_oldsize) - 1) * sizeof( *(p_ar) ) ); \
} \
else \
{ \
free( p_ar ); \
(p_ar) = NULL; \
} \
(i_oldsize)--; \
} \
while( 0 )
/* MSB (big endian)/LSB (little endian) conversions - network order is always /* MSB (big endian)/LSB (little endian) conversions - network order is always
* MSB, and should be used for both network communications and files. Note that * MSB, and should be used for both network communications and files. Note that
* byte orders other than little and big endians are not supported, but only * byte orders other than little and big endians are not supported, but only
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* input_dec.c: Functions for the management of decoders * input_dec.c: Functions for the management of decoders
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * Copyright (C) 1999-2001 VideoLAN
* $Id: input_dec.c,v 1.48 2002/10/27 16:58:12 gbazin Exp $ * $Id: input_dec.c,v 1.49 2002/10/29 13:22:48 sam Exp $
* *
* Authors: Christophe Massiot <massiot@via.ecp.fr> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -284,20 +284,10 @@ static decoder_fifo_t * CreateDecoderFifo( input_thread_t * p_input, ...@@ -284,20 +284,10 @@ static decoder_fifo_t * CreateDecoderFifo( input_thread_t * p_input,
} }
/* Select a new ES */ /* Select a new ES */
p_input->stream.i_selected_es_number++; INSERT_ELEM( p_input->stream.pp_selected_es,
p_input->stream.pp_selected_es = realloc( p_input->stream.i_selected_es_number,
p_input->stream.pp_selected_es, p_input->stream.i_selected_es_number,
p_input->stream.i_selected_es_number p_es );
* sizeof(es_descriptor_t *) );
if( p_input->stream.pp_selected_es == NULL )
{
msg_Err( p_input, "out of memory" );
vlc_object_destroy( p_fifo );
return NULL;
}
p_input->stream.pp_selected_es[p_input->stream.i_selected_es_number - 1]
= p_es;
/* Initialize the p_fifo structure */ /* Initialize the p_fifo structure */
vlc_mutex_init( p_input, &p_fifo->data_lock ); vlc_mutex_init( p_input, &p_fifo->data_lock );
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* input_programs.c: es_descriptor_t, pgrm_descriptor_t management * input_programs.c: es_descriptor_t, pgrm_descriptor_t management
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2002 VideoLAN * Copyright (C) 1999-2002 VideoLAN
* $Id: input_programs.c,v 1.94 2002/07/31 20:56:52 sam Exp $ * $Id: input_programs.c,v 1.95 2002/10/29 13:22:48 sam Exp $
* *
* Authors: Christophe Massiot <massiot@via.ecp.fr> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -138,59 +138,48 @@ pgrm_descriptor_t * input_AddProgram( input_thread_t * p_input, ...@@ -138,59 +138,48 @@ pgrm_descriptor_t * input_AddProgram( input_thread_t * p_input,
u16 i_pgrm_id, size_t i_data_len ) u16 i_pgrm_id, size_t i_data_len )
{ {
/* Where to add the pgrm */ /* Where to add the pgrm */
int i_pgrm_index = p_input->stream.i_pgrm_number; pgrm_descriptor_t * p_pgrm = malloc( sizeof(pgrm_descriptor_t) );
/* Add an entry to the list of program associated with the stream */ if( p_pgrm == NULL )
p_input->stream.i_pgrm_number++;
p_input->stream.pp_programs = realloc( p_input->stream.pp_programs,
p_input->stream.i_pgrm_number
* sizeof(pgrm_descriptor_t *) );
if( p_input->stream.pp_programs == NULL )
{ {
msg_Err( p_input, "out of memory" ); msg_Err( p_input, "out of memory" );
return( NULL ); return NULL;
} }
/* Allocate the structure to store this description */
p_input->stream.pp_programs[i_pgrm_index] =
malloc( sizeof(pgrm_descriptor_t) );
if( p_input->stream.pp_programs[i_pgrm_index] == NULL )
{
msg_Err( p_input, "out of memory" );
return( NULL );
}
/* Init this entry */ /* Init this entry */
p_input->stream.pp_programs[i_pgrm_index]->i_number = i_pgrm_id; p_pgrm->i_number = i_pgrm_id;
p_input->stream.pp_programs[i_pgrm_index]->b_is_ok = 0; p_pgrm->b_is_ok = 0;
p_input->stream.pp_programs[i_pgrm_index]->i_version = 0; p_pgrm->i_version = 0;
p_input->stream.pp_programs[i_pgrm_index]->i_es_number = 0; p_pgrm->i_es_number = 0;
p_input->stream.pp_programs[i_pgrm_index]->pp_es = NULL; p_pgrm->pp_es = NULL;
input_ClockInit( p_input->stream.pp_programs[i_pgrm_index] ); input_ClockInit( p_pgrm );
p_input->stream.pp_programs[i_pgrm_index]->i_synchro_state p_pgrm->i_synchro_state = SYNCHRO_START;
= SYNCHRO_START;
if( i_data_len ) if( i_data_len )
{ {
p_input->stream.pp_programs[i_pgrm_index]->p_demux_data = p_pgrm->p_demux_data = malloc( i_data_len );
malloc( i_data_len ); if( p_pgrm->p_demux_data == NULL )
if( p_input->stream.pp_programs[i_pgrm_index]->p_demux_data == NULL )
{ {
msg_Err( p_input, "out of memory" ); msg_Err( p_input, "out of memory" );
return( NULL ); return NULL;
} }
memset( p_input->stream.pp_programs[i_pgrm_index]->p_demux_data, 0, memset( p_pgrm->p_demux_data, 0, i_data_len );
i_data_len );
} }
else else
{ {
p_input->stream.pp_programs[i_pgrm_index]->p_demux_data = NULL; p_pgrm->p_demux_data = NULL;
} }
return p_input->stream.pp_programs[i_pgrm_index]; /* Add an entry to the list of program associated with the stream */
INSERT_ELEM( p_input->stream.pp_programs,
p_input->stream.i_pgrm_number,
p_input->stream.i_pgrm_number,
p_pgrm );
return p_pgrm;
} }
/***************************************************************************** /*****************************************************************************
...@@ -230,25 +219,9 @@ void input_DelProgram( input_thread_t * p_input, pgrm_descriptor_t * p_pgrm ) ...@@ -230,25 +219,9 @@ void input_DelProgram( input_thread_t * p_input, pgrm_descriptor_t * p_pgrm )
} }
/* Remove this program from the stream's list of programs */ /* Remove this program from the stream's list of programs */
p_input->stream.i_pgrm_number--; REMOVE_ELEM( p_input->stream.pp_programs,
p_input->stream.i_pgrm_number,
p_input->stream.pp_programs[i_pgrm_index] = i_pgrm_index );
p_input->stream.pp_programs[p_input->stream.i_pgrm_number];
if( p_input->stream.i_pgrm_number )
{
p_input->stream.pp_programs = realloc( p_input->stream.pp_programs,
p_input->stream.i_pgrm_number
* sizeof(pgrm_descriptor_t *) );
if( p_input->stream.pp_programs == NULL )
{
msg_Err( p_input, "cannot realloc memory" );
}
}
else
{
free( p_input->stream.pp_programs );
p_input->stream.pp_programs = NULL;
}
/* Free the description of this program */ /* Free the description of this program */
free( p_pgrm ); free( p_pgrm );
...@@ -262,38 +235,30 @@ void input_DelProgram( input_thread_t * p_input, pgrm_descriptor_t * p_pgrm ) ...@@ -262,38 +235,30 @@ void input_DelProgram( input_thread_t * p_input, pgrm_descriptor_t * p_pgrm )
input_area_t * input_AddArea( input_thread_t * p_input ) input_area_t * input_AddArea( input_thread_t * p_input )
{ {
/* Where to add the pgrm */ /* Where to add the pgrm */
int i_area_index = p_input->stream.i_area_nb; input_area_t * p_area = malloc( sizeof(input_area_t) );
/* Add an entry to the list of program associated with the stream */ if( p_area == NULL )
p_input->stream.i_area_nb++;
p_input->stream.pp_areas = realloc( p_input->stream.pp_areas,
p_input->stream.i_area_nb
* sizeof(input_area_t *) );
if( p_input->stream.pp_areas == NULL )
{ {
msg_Err( p_input, "out of memory" ); msg_Err( p_input, "out of memory" );
return( NULL ); return NULL;
} }
/* Allocate the structure to store this description */
p_input->stream.pp_areas[i_area_index] =
malloc( sizeof(input_area_t) );
if( p_input->stream.pp_areas[i_area_index] == NULL )
{
msg_Err( p_input, "out of memory" );
return( NULL );
}
/* Init this entry */ /* Init this entry */
p_input->stream.pp_areas[i_area_index]->i_id = 0; p_area->i_id = 0;
p_input->stream.pp_areas[i_area_index]->i_start = 0; p_area->i_start = 0;
p_input->stream.pp_areas[i_area_index]->i_size = 0; p_area->i_size = 0;
p_input->stream.pp_areas[i_area_index]->i_tell = 0; p_area->i_tell = 0;
p_input->stream.pp_areas[i_area_index]->i_seek = NO_SEEK; p_area->i_seek = NO_SEEK;
p_input->stream.pp_areas[i_area_index]->i_part_nb = 1; p_area->i_part_nb = 1;
p_input->stream.pp_areas[i_area_index]->i_part= 0; p_area->i_part= 0;
return p_input->stream.pp_areas[i_area_index]; /* Add an entry to the list of program associated with the stream */
INSERT_ELEM( p_input->stream.pp_areas,
p_input->stream.i_area_nb,
p_input->stream.i_area_nb,
p_area );
return p_area;
} }
/***************************************************************************** /*****************************************************************************
...@@ -420,26 +385,9 @@ void input_DelArea( input_thread_t * p_input, input_area_t * p_area ) ...@@ -420,26 +385,9 @@ void input_DelArea( input_thread_t * p_input, input_area_t * p_area )
} }
/* Remove this area from the stream's list of areas */ /* Remove this area from the stream's list of areas */
p_input->stream.i_area_nb--; REMOVE_ELEM( p_input->stream.pp_areas,
p_input->stream.i_area_nb,
p_input->stream.pp_areas[i_area_index] = i_area_index );
p_input->stream.pp_areas[p_input->stream.i_area_nb];
if( p_input->stream.i_area_nb )
{
p_input->stream.pp_areas = realloc( p_input->stream.pp_areas,
p_input->stream.i_area_nb
* sizeof(input_area_t *) );
if( p_input->stream.pp_areas == NULL )
{
msg_Err( p_input, "cannot realloc memory" );
}
}
else
{
free( p_input->stream.pp_areas );
p_input->stream.pp_areas = NULL;
}
/* Free the description of this area */ /* Free the description of this area */
free( p_area ); free( p_area );
...@@ -483,17 +431,11 @@ es_descriptor_t * input_AddES( input_thread_t * p_input, ...@@ -483,17 +431,11 @@ es_descriptor_t * input_AddES( input_thread_t * p_input,
msg_Err( p_input, "out of memory" ); msg_Err( p_input, "out of memory" );
return( NULL); return( NULL);
} }
p_input->stream.i_es_number++;
p_input->stream.pp_es = realloc( p_input->stream.pp_es,
p_input->stream.i_es_number
* sizeof(es_descriptor_t *) );
if( p_input->stream.pp_es == NULL )
{
msg_Err( p_input, "out of memory" );
return( NULL );
}
p_input->stream.pp_es[p_input->stream.i_es_number - 1] = p_es; INSERT_ELEM( p_input->stream.pp_es,
p_input->stream.i_es_number,
p_input->stream.i_es_number,
p_es );
/* Init its values */ /* Init its values */
p_es->i_id = i_es_id; p_es->i_id = i_es_id;
...@@ -523,17 +465,10 @@ es_descriptor_t * input_AddES( input_thread_t * p_input, ...@@ -523,17 +465,10 @@ es_descriptor_t * input_AddES( input_thread_t * p_input,
/* Add this ES to the program definition if one is given */ /* Add this ES to the program definition if one is given */
if( p_pgrm ) if( p_pgrm )
{ {
p_pgrm->i_es_number++; INSERT_ELEM( p_pgrm->pp_es,
p_pgrm->pp_es = realloc( p_pgrm->pp_es, p_pgrm->i_es_number,
p_pgrm->i_es_number p_pgrm->i_es_number,
* sizeof(es_descriptor_t *) ); p_es );
if( p_pgrm->pp_es == NULL )
{
msg_Err( p_input, "out of memory" );
return( NULL );
}
p_pgrm->pp_es[p_pgrm->i_es_number - 1] = p_es;
p_es->p_pgrm = p_pgrm; p_es->p_pgrm = p_pgrm;
} }
else else
...@@ -583,23 +518,9 @@ void input_DelES( input_thread_t * p_input, es_descriptor_t * p_es ) ...@@ -583,23 +518,9 @@ void input_DelES( input_thread_t * p_input, es_descriptor_t * p_es )
{ {
if( p_pgrm->pp_es[i_index] == p_es ) if( p_pgrm->pp_es[i_index] == p_es )
{ {
p_pgrm->i_es_number--; REMOVE_ELEM( p_pgrm->pp_es,
p_pgrm->pp_es[i_index] = p_pgrm->pp_es[p_pgrm->i_es_number]; p_pgrm->i_es_number,
if( p_pgrm->i_es_number ) i_index );
{
p_pgrm->pp_es = realloc( p_pgrm->pp_es,
p_pgrm->i_es_number
* sizeof(es_descriptor_t *));
if( p_pgrm->pp_es == NULL )
{
msg_Err( p_input, "cannot realloc memory" );
}
}
else
{
free( p_pgrm->pp_es );
p_pgrm->pp_es = NULL;
}
break; break;
} }
} }
...@@ -620,25 +541,10 @@ void input_DelES( input_thread_t * p_input, es_descriptor_t * p_es ) ...@@ -620,25 +541,10 @@ void input_DelES( input_thread_t * p_input, es_descriptor_t * p_es )
} }
/* Remove this ES from the stream's list of ES */ /* Remove this ES from the stream's list of ES */
p_input->stream.i_es_number--; REMOVE_ELEM( p_input->stream.pp_es,
p_input->stream.pp_es[i_es_index] = p_input->stream.i_es_number,
p_input->stream.pp_es[p_input->stream.i_es_number]; i_es_index );
if( p_input->stream.i_es_number )
{
p_input->stream.pp_es = realloc( p_input->stream.pp_es,
p_input->stream.i_es_number
* sizeof(es_descriptor_t *));
if( p_input->stream.pp_es == NULL )
{
msg_Err( p_input, "cannot realloc memory" );
}
}
else
{
free( p_input->stream.pp_es );
p_input->stream.pp_es = NULL;
}
/* Free the ES */ /* Free the ES */
free( p_es ); free( p_es );
} }
...@@ -707,37 +613,23 @@ int input_UnselectES( input_thread_t * p_input, es_descriptor_t * p_es ) ...@@ -707,37 +613,23 @@ int input_UnselectES( input_thread_t * p_input, es_descriptor_t * p_es )
if( ( p_es->p_decoder_fifo == NULL ) && if( ( p_es->p_decoder_fifo == NULL ) &&
( p_input->stream.i_selected_es_number > 0 ) ) ( p_input->stream.i_selected_es_number > 0 ) )
{ {
p_input->stream.i_selected_es_number--; while( ( i_index < p_input->stream.i_selected_es_number - 1 ) &&
while( ( i_index < p_input->stream.i_selected_es_number ) &&
( p_input->stream.pp_selected_es[i_index] != p_es ) ) ( p_input->stream.pp_selected_es[i_index] != p_es ) )
{ {
i_index++; i_index++;
} }
p_input->stream.pp_selected_es[i_index] = /* XXX: no need to memmove, we have unordered data */
p_input->stream.pp_selected_es[p_input->stream.i_selected_es_number]; REMOVE_ELEM( p_input->stream.pp_selected_es,
p_input->stream.i_selected_es_number,
i_index );
if( p_input->stream.i_selected_es_number ) if( p_input->stream.i_selected_es_number == 0 )
{ {
p_input->stream.pp_selected_es = realloc(
p_input->stream.pp_selected_es,
p_input->stream.i_selected_es_number
* sizeof(es_descriptor_t *) );
if( p_input->stream.pp_selected_es == NULL )
{
msg_Err( p_input, "cannot realloc memory" );
return( -1 );
}
}
else
{
free( p_input->stream.pp_selected_es );
p_input->stream.pp_selected_es = NULL;
msg_Dbg( p_input, "no more selected ES" ); msg_Dbg( p_input, "no more selected ES" );
return( 1 ); return 1;
} }
} }
return( 0 ); return 0;
} }
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* modules, especially intf modules. See config.h for output configuration. * modules, especially intf modules. See config.h for output configuration.
***************************************************************************** *****************************************************************************
* Copyright (C) 1998-2002 VideoLAN * Copyright (C) 1998-2002 VideoLAN
* $Id: messages.c,v 1.17 2002/10/28 16:26:44 sam Exp $ * $Id: messages.c,v 1.18 2002/10/29 13:22:48 sam Exp $
* *
* Authors: Vincent Seguin <seguin@via.ecp.fr> * Authors: Vincent Seguin <seguin@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org> * Samuel Hocevar <sam@zoy.org>
...@@ -137,11 +137,7 @@ msg_subscription_t *__msg_Subscribe( vlc_object_t *p_this ) ...@@ -137,11 +137,7 @@ msg_subscription_t *__msg_Subscribe( vlc_object_t *p_this )
vlc_mutex_lock( &p_bank->lock ); vlc_mutex_lock( &p_bank->lock );
/* Add subscription to the list */ /* Add subscription to the list */
p_bank->i_sub++; INSERT_ELEM( p_bank->pp_sub, p_bank->i_sub, p_bank->i_sub, p_sub );
p_bank->pp_sub = realloc( p_bank->pp_sub,
p_bank->i_sub * sizeof( msg_subscription_t* ) );
p_bank->pp_sub[ p_bank->i_sub - 1 ] = p_sub;
p_sub->i_start = p_bank->i_start; p_sub->i_start = p_bank->i_start;
p_sub->pi_stop = &p_bank->i_stop; p_sub->pi_stop = &p_bank->i_stop;
...@@ -188,23 +184,7 @@ void __msg_Unsubscribe( vlc_object_t *p_this, msg_subscription_t *p_sub ) ...@@ -188,23 +184,7 @@ void __msg_Unsubscribe( vlc_object_t *p_this, msg_subscription_t *p_sub )
} }
/* Remove this subscription */ /* Remove this subscription */
for( ; i_index < (p_bank->i_sub - 1); i_index++ ) REMOVE_ELEM( p_bank->pp_sub, p_bank->i_sub, i_index );
{
p_bank->pp_sub[ i_index ] = p_bank->pp_sub[ i_index+1 ];
}
p_bank->i_sub--;
if( p_bank->i_sub )
{
p_bank->pp_sub = realloc( p_bank->pp_sub, p_bank->i_sub
* sizeof( msg_subscription_t* ) );
}
else
{
free( p_bank->pp_sub );
p_bank->pp_sub = NULL;
}
vlc_mutex_unlock( &p_bank->lock ); vlc_mutex_unlock( &p_bank->lock );
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* objects.c: vlc_object_t handling * objects.c: vlc_object_t handling
***************************************************************************** *****************************************************************************
* Copyright (C) 2002 VideoLAN * Copyright (C) 2002 VideoLAN
* $Id: objects.c,v 1.26 2002/10/17 13:15:31 sam Exp $ * $Id: objects.c,v 1.27 2002/10/29 13:22:48 sam Exp $
* *
* Authors: Samuel Hocevar <sam@zoy.org> * Authors: Samuel Hocevar <sam@zoy.org>
* *
...@@ -186,11 +186,10 @@ void * __vlc_object_create( vlc_object_t *p_this, int i_type ) ...@@ -186,11 +186,10 @@ void * __vlc_object_create( vlc_object_t *p_this, int i_type )
/* Wooohaa! If *this* fails, we're in serious trouble! Anyway it's /* Wooohaa! If *this* fails, we're in serious trouble! Anyway it's
* useless to try and recover anything if pp_objects gets smashed. */ * useless to try and recover anything if pp_objects gets smashed. */
p_new->p_libvlc->i_objects++; INSERT_ELEM( p_new->p_libvlc->pp_objects,
p_new->p_libvlc->pp_objects = p_new->p_libvlc->i_objects,
realloc( p_new->p_libvlc->pp_objects, p_new->p_libvlc->i_objects,
p_new->p_libvlc->i_objects * sizeof(vlc_object_t *) ); p_new );
p_new->p_libvlc->pp_objects[ p_new->p_libvlc->i_objects - 1 ] = p_new;
vlc_mutex_unlock( &structure_lock ); vlc_mutex_unlock( &structure_lock );
} }
...@@ -282,6 +281,7 @@ void __vlc_object_destroy( vlc_object_t *p_this ) ...@@ -282,6 +281,7 @@ void __vlc_object_destroy( vlc_object_t *p_this )
/* We are the root object ... no need to lock. */ /* We are the root object ... no need to lock. */