[vlc-devel] [PATCH 2/6] Add support for pf_readdir access modules in Streams
Rémi Denis-Courmont
remi at remlab.net
Sat Jun 21 10:54:06 CEST 2014
Le vendredi 20 juin 2014, 19:53:04 Julien 'Lta' BALLET a écrit :
> From: Julien 'Lta' BALLET <contact at lta.io>
>
> ---
> include/vlc_stream.h | 9 ++++---
> src/input/stream.c | 71
> ++++++++++++++++++++++++++++++++++++++++++++-------- src/libvlccore.sym |
> 1 +
> 3 files changed, 67 insertions(+), 14 deletions(-)
>
> diff --git a/include/vlc_stream.h b/include/vlc_stream.h
> index 10a98ef..db247bc 100644
> --- a/include/vlc_stream.h
> +++ b/include/vlc_stream.h
> @@ -65,9 +65,10 @@ struct stream_t
> stream_t *p_source;
>
> /* */
> - int (*pf_read) ( stream_t *, void *p_read, unsigned int i_read
> ); - int (*pf_peek) ( stream_t *, const uint8_t **pp_peek,
> unsigned int i_peek ); - int (*pf_control)( stream_t *, int
> i_query, va_list );
> + int (*pf_read) ( stream_t *, void *p_read, unsigned int
> i_read ); + int (*pf_peek) ( stream_t *, const uint8_t
> **pp_peek, unsigned int i_peek ); + int (*pf_readdir)( stream_t
> *, input_item_node_t * ); + int (*pf_control)( stream_t *, int
> i_query, va_list );
>
> /* */
> void (*pf_destroy)( stream_t *);
> @@ -92,6 +93,7 @@ enum stream_query_e
> STREAM_CAN_FASTSEEK, /**< arg1= bool * res=cannot fail*/
> STREAM_CAN_PAUSE, /**< arg1= bool * res=cannot fail*/
> STREAM_CAN_CONTROL_PACE, /**< arg1= bool * res=cannot fail*/
> + STREAM_IS_DIRECTORY, /**< arg1= bool * res=cannot fail*/
>
> /* */
> STREAM_SET_POSITION, /**< arg1= uint64_t res=can fail */
> @@ -132,6 +134,7 @@ VLC_API int stream_Control( stream_t *s, int i_query,
> ... ); VLC_API block_t * stream_Block( stream_t *s, int i_size );
> VLC_API block_t * stream_BlockRemaining( stream_t *s, int i_max_size );
> VLC_API char * stream_ReadLine( stream_t * );
> +VLC_API int stream_ReadDir( stream_t *, input_item_node_t * );
>
> /**
> * Get the current position in a stream
> diff --git a/src/input/stream.c b/src/input/stream.c
> index 18e77e2..a5d041c 100644
> --- a/src/input/stream.c
> +++ b/src/input/stream.c
> @@ -116,7 +116,8 @@ typedef struct
> typedef enum
> {
> STREAM_METHOD_BLOCK,
> - STREAM_METHOD_STREAM
> + STREAM_METHOD_STREAM,
> + STREAM_METHOD_READDIR
> } stream_read_method_t;
>
> struct stream_sys_t
> @@ -197,6 +198,9 @@ static int AStreamSeekStream( stream_t *s, uint64_t
> i_pos ); static void AStreamPrebufferStream( stream_t *s );
> static int AReadStream( stream_t *s, void *p_read, unsigned int i_read );
>
> +/* ReadDir */
> +static int AStreamReadDir( stream_t *s, input_item_node_t *p_node );
> +
> /* Common */
> static int AStreamControl( stream_t *s, int i_query, va_list );
> static void AStreamDestroy( stream_t *s );
> @@ -285,8 +289,9 @@ stream_t *stream_AccessNew( access_t *p_access, char
> **ppsz_list ) return NULL;
> }
>
> - s->pf_read = NULL; /* Set up later */
> - s->pf_peek = NULL;
> + s->pf_read = NULL; /* Set up later */
> + s->pf_peek = NULL;
> + s->pf_readdir = NULL;
> s->pf_control = AStreamControl;
> s->pf_destroy = AStreamDestroy;
>
> @@ -294,8 +299,10 @@ stream_t *stream_AccessNew( access_t *p_access, char
> **ppsz_list ) p_sys->p_access = p_access;
> if( p_access->pf_block )
> p_sys->method = STREAM_METHOD_BLOCK;
> - else
> + else if( p_access->pf_read )
> p_sys->method = STREAM_METHOD_STREAM;
> + else
> + p_sys->method = STREAM_METHOD_READDIR;
>
> p_sys->i_pos = p_access->info.i_pos;
>
> @@ -385,12 +392,10 @@ stream_t *stream_AccessNew( access_t *p_access, char
> **ppsz_list ) goto error;
> }
> }
> - else
> + else if ( p_sys->method == STREAM_METHOD_STREAM )
> {
> int i;
>
> - assert( p_sys->method == STREAM_METHOD_STREAM );
> -
> msg_Dbg( s, "Using stream method for AStream*" );
>
> s->pf_read = AStreamReadStream;
> @@ -426,6 +431,11 @@ stream_t *stream_AccessNew( access_t *p_access, char
> **ppsz_list ) goto error;
> }
> }
> + else
> + {
> + assert( p_sys->method == STREAM_METHOD_READDIR );
> + s->pf_readdir = AStreamReadDir;
> + }
>
> return s;
>
> @@ -434,7 +444,7 @@ error:
> {
> /* Nothing yet */
> }
> - else
> + else if( p_sys->method == STREAM_METHOD_STREAM )
> {
> free( p_sys->stream.p_buffer );
> }
> @@ -456,7 +466,7 @@ static void AStreamDestroy( stream_t *s )
>
> if( p_sys->method == STREAM_METHOD_BLOCK )
> block_ChainRelease( p_sys->block.p_first );
> - else
> + else if( p_sys->method == STREAM_METHOD_STREAM )
> free( p_sys->stream.p_buffer );
>
> free( p_sys->p_peek );
> @@ -637,6 +647,13 @@ static int AStreamControl( stream_t *s, int i_query,
> va_list args ) return ret;
> }
>
> + case STREAM_IS_DIRECTORY:
> + {
> + bool *pb_canreaddir = va_arg( args, bool * );
> + *pb_canreaddir = p_sys->method == STREAM_METHOD_READDIR;
> + return VLC_SUCCESS;
> + }
> +
> case STREAM_SET_RECORD_STATE:
> default:
> msg_Err( s, "invalid stream_vaControl query=0x%x", i_query );
> @@ -1473,6 +1490,10 @@ char *stream_ReadLine( stream_t *s )
> char *p_line = NULL;
> int i_line = 0, i_read = 0;
>
> + /* Let's fail quickly if this is a readdir access */
> + if( s->pf_read == NULL )
> + return NULL;
> +
> for( ;; )
> {
> char *psz_eol;
> @@ -1830,6 +1851,15 @@ static int ASeek( stream_t *s, uint64_t i_pos )
> return p_access->pf_seek( p_access, i_pos );
> }
>
> +int AStreamReadDir( stream_t *s, input_item_node_t *p_node )
> +{
> + access_t *p_access = s->p_sys->p_access;
> +
> + if( p_access->pf_readdir != NULL )
> + return p_access->pf_readdir( p_access, p_node );
> + else
> + return VLC_ENOITEM;
> +}
I would define a callback that just returns an error instead of checking for
NULL. It can even be used for all cases, but I guess that's a matter of taste:
int AStreamGenericError(/* ... */)
{
return VLC_EGENERIC;
}
>
> /**
> * Try to read "i_read" bytes into a buffer pointed by "p_read". If
> @@ -1841,7 +1871,10 @@ static int ASeek( stream_t *s, uint64_t i_pos )
> */
> int stream_Read( stream_t *s, void *p_read, int i_read )
> {
> - return s->pf_read( s, p_read, i_read );
> + if( likely( s->pf_read != NULL) )
> + return s->pf_read( s, p_read, i_read );
> + else
> + return VLC_EGENERIC;
> }
Ditto.
>
> /**
> @@ -1859,7 +1892,10 @@ int stream_Read( stream_t *s, void *p_read, int
> i_read ) */
> int stream_Peek( stream_t *s, const uint8_t **pp_peek, int i_peek )
> {
> - return s->pf_peek( s, pp_peek, i_peek );
> + if( likely( s->pf_peek != NULL ) )
> + return s->pf_peek( s, pp_peek, i_peek );
> + else
> + return VLC_EGENERIC;
> }
Ditto.
>
> /**
> @@ -1962,3 +1998,16 @@ block_t *stream_BlockRemaining( stream_t *s, int
> i_max_size ) return p_block;
> }
>
> +/**
> + * Returns a node containing all the input_item of the directory pointer by
> + * this stream. returns VLC_SUCCESS on success.
> + */
> +int stream_ReadDir( stream_t *s, input_item_node_t *p_node )
> +{
> + if( s->pf_readdir )
> + {
> + return s->pf_readdir( s, p_node );
> + }
> + else
> + return VLC_ENOITEM;
> +}
Ditto.
> diff --git a/src/libvlccore.sym b/src/libvlccore.sym
> index e583c21..7b40435 100644
> --- a/src/libvlccore.sym
> +++ b/src/libvlccore.sym
> @@ -402,6 +402,7 @@ stream_Read
> stream_ReadLine
> stream_UrlNew
> stream_vaControl
> +stream_ReadDir
> str_format_meta
> str_format_time
> str_duration
But it seems fine anyway.
--
Rémi Denis-Courmont
http://www.remlab.net/
More information about the vlc-devel
mailing list