[vlc-devel] [RFC 05/10] stream_extractor: add vlc_stream_extractor_CreateMRL

Rémi Denis-Courmont remi at remlab.net
Mon Nov 28 17:46:50 CET 2016


Le maanantaina 28. marraskuuta 2016, 3.22.24 EET Filip Roséen a écrit :
> Function used by stream-extractor modules to make it easy to create a
> relative MRL for an entity within the data handled by the
> stream-extractor.
> ---
>  include/vlc_stream_extractor.h | 18 ++++++++++
>  src/input/mrl_helpers.h        | 78
> ++++++++++++++++++++++++++++++++++++++++++ src/input/stream_extractor.c   |
> 31 ++++++++++++++++-
>  src/libvlccore.sym             |  1 +
>  4 files changed, 127 insertions(+), 1 deletion(-)
>  create mode 100644 src/input/mrl_helpers.h
> 
> diff --git a/include/vlc_stream_extractor.h b/include/vlc_stream_extractor.h
> index 1f6d01a..87be9d2 100644
> --- a/include/vlc_stream_extractor.h
> +++ b/include/vlc_stream_extractor.h
> @@ -67,6 +67,24 @@ struct stream_extractor_t {
>  typedef struct stream_extractor_t stream_extractor_t;
> 
>  /**
> + * Create a relative MRL for the associated entity
> + *
> + * This function shall be used by stream_extractor_t's in order to
> + * generate a MRL that refers to an entity within the stream. Normally
> + * this function will only be invoked within `pf_readdir` in order to
> + * get the virtual path of the listed items.
> + *
> + * \warning the returned value is to be freed by the caller
> + *
> + * \param extractor the stream_extractor_t in which the entity belongs
> + * \param subentry the name of the entity in question
> + *
> + * \return a pointer to the resulting MRL on success, NULL on failure
> + **/
> +VLC_API char* vlc_stream_extractor_CreateMRL( stream_extractor_t*,
> +                                              char const* subentry );
> +
> +/**
>   * Construct a new stream_extractor-based stream
>   *
>   * This function is used to create a stream_t where the underlying
> diff --git a/src/input/mrl_helpers.h b/src/input/mrl_helpers.h
> new file mode 100644
> index 0000000..a3fc7a4
> --- /dev/null
> +++ b/src/input/mrl_helpers.h
> @@ -0,0 +1,78 @@
> +#ifndef INPUT_MRL_HELPERS_H
> +#define INPUT_MRL_HELPERS_H
> +
> +#include <string.h>
> +#include <stdlib.h>
> +
> +#include <vlc_common.h>
> +#include <vlc_memstream.h>
> +#include <vlc_arrays.h>
> +
> +/**
> + * \defgroup mrl_helpers MRL helpers
> + * \ingroup mrl
> + *
> + * Helper functions related to parsing, as well as generating, data
> + * related to the \link MRL-specification\endlink.
> + *
> + * @{
> + * \file
> + **/
> +
> +/**
> + * Escape a fragment identifier for use within an MRL
> + *
> + * The function will generate a string that follows the \link mrl
> + * MRL-specification\endlink regarding \em fragment-identifiers.
> + *
> + * See the \link mrl MRL-specification\endlink for a detailed
> + * explanation of how `payload` will be escaped.
> + *
> + * \param[out] out `*out` will refer to the created string on success,
> + *                  and an unspecified value on error.
> + * \param[in] payload the data to escape.
> + * \return VLC_SUCCESS on success, an error-code on failure.
> + **/
> +static inline int
> +mrl_EscapeFragmentIdentifier( char** out, char const* payload )
> +{
> +    struct vlc_memstream mstream;
> +
> +#define RFC3986_SUBDELIMS  "!" "$" "&" "'" "(" ")" \
> +                           "*" "+" "," ";" "="
> +#define RFC3986_ALPHA      "abcdefghijklmnopqrstuvwxyz" \
> +                           "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
> +#define RFC3986_DIGIT      "0123456789"
> +#define RFC3986_UNRESERVED RFC3986_ALPHA RFC3986_DIGIT "-" "." "_" "~"
> +#define RFC3986_PCHAR      RFC3986_UNRESERVED RFC3986_SUBDELIMS ":" "@"
> +#define RFC3986_FRAGMENT   RFC3986_PCHAR "/" "?"
> +
> +    if( vlc_memstream_open( &mstream ) )
> +        return VLC_EGENERIC;
> +
> +    for( char const* p = payload; *p; ++p )
> +    {
> +        vlc_memstream_printf( &mstream,
> +            ( strchr( "!?", *p ) == NULL &&
> +              strchr( RFC3986_FRAGMENT, *p ) ? "%c" : "%%%x"), *p );

%02hhx otherwise non-printable and non-ASCII values won´t work.

> +    }
> +
> +#undef RFC3986_FRAGMENT
> +#undef RFC3986_PCHAR
> +#undef RFC3986_UNRESERVEd
> +#undef RFC3986_DIGIT
> +#undef RFC3986_ALPHA
> +#undef RFC3986_SUBDELIMS
> +
> +    if( vlc_memstream_close( &mstream ) )
> +        return VLC_EGENERIC;
> +
> +    *out = mstream.ptr;
> +    return VLC_SUCCESS;
> +}
> +
> +/*
> + * @}
> + **/
> +
> +#endif /* include-guard */
> diff --git a/src/input/stream_extractor.c b/src/input/stream_extractor.c
> index 78800e4..9d559a5 100644
> --- a/src/input/stream_extractor.c
> +++ b/src/input/stream_extractor.c
> @@ -15,6 +15,7 @@
>  #include <assert.h>
> 
>  #include "stream.h"
> +#include "mrl_helpers.h"
> 
>  /**
>   * \defgroup stream_extractor_Private Stream Extractor Private
> @@ -146,7 +147,8 @@ se_InitStream( struct stream_extractor_private* priv,
> stream_t* source ) else                              s->pf_block =
> se_StreamBlock;
> 
>          s->pf_seek = se_StreamSeek;
> -        s->psz_url = NULL;
> +        s->psz_url = vlc_stream_extractor_CreateMRL( &priv->public,
> +                                                     
> priv->public.identifier ); }
>      else
>      {
> @@ -196,6 +198,33 @@ error:
>      return VLC_EGENERIC;
>  }
> 
> +char*
> +vlc_stream_extractor_CreateMRL( stream_extractor_t* extractor,
> +                                char const* subentry )
> +{
> +    struct vlc_memstream buffer;
> +    char* escaped;
> +
> +    if( mrl_EscapeFragmentIdentifier( &escaped, subentry ) )
> +        return NULL;
> +
> +    if( vlc_memstream_open( &buffer ) )
> +    {
> +        free( escaped );
> +        return NULL;
> +    }
> +
> +    vlc_memstream_puts( &buffer, extractor->source->psz_url );
> +
> +    if( !strstr( extractor->source->psz_url, "#" ) )
> +        vlc_memstream_putc( &buffer, '#' );
> +
> +    vlc_memstream_printf( &buffer, "!/%s", escaped );
> +
> +    free( escaped );
> +    return vlc_memstream_close( &buffer ) ? NULL : buffer.ptr;
> +}
> +
>  /**
>   * @}
>   **/
> diff --git a/src/libvlccore.sym b/src/libvlccore.sym
> index cd8d0b5..6c66b09 100644
> --- a/src/libvlccore.sym
> +++ b/src/libvlccore.sym
> @@ -396,6 +396,7 @@ spu_Render
>  spu_RegisterChannel
>  spu_ClearChannel
>  vlc_stream_extractor_Attach
> +vlc_stream_extractor_CreateMRL
>  vlc_stream_Block
>  vlc_stream_CommonNew
>  vlc_stream_Delete


-- 
Rémi Denis-Courmont
https://www.remlab.net/



More information about the vlc-devel mailing list