vlc | branch: master | Filip Roséen <[email protected]> | Tue Nov 22 00:50:52 2016 +0100| [fcf559302e42146959a8266ada9d952c9fd9fde1] | committer: Thomas Guillem
stream_extractor: add vlc_stream_extractor_CreateMRL 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. Signed-off-by: Thomas Guillem <[email protected]> > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=fcf559302e42146959a8266ada9d952c9fd9fde1 --- include/vlc_stream_extractor.h | 23 ++++++++-- src/Makefile.am | 1 + src/input/mrl_helpers.h | 98 ++++++++++++++++++++++++++++++++++++++++++ src/input/stream_extractor.c | 31 ++++++++++++- src/libvlccore.sym | 1 + 5 files changed, 150 insertions(+), 4 deletions(-) diff --git a/include/vlc_stream_extractor.h b/include/vlc_stream_extractor.h index 0d0e63e..9045264 100644 --- a/include/vlc_stream_extractor.h +++ b/include/vlc_stream_extractor.h @@ -87,11 +87,28 @@ 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 attach a stream to an already existing - * stream, where the underlying, attached, stream is a - * stream_extractor. + * This function is used to attach a stream extractor to an already + * existing stream. * * If \p identifier is `NULL`, `*stream` is guaranteed to refer to a * directory, otherwise \p identifier denotes the specific subentry diff --git a/src/Makefile.am b/src/Makefile.am index ccc8dfb..2c8800e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -247,6 +247,7 @@ libvlccore_la_SOURCES = \ input/es_out_timeshift.h \ input/event.h \ input/item.h \ + input/mrl_helpers.h \ input/stream.h \ input/input_internal.h \ input/input_interface.h \ diff --git a/src/input/mrl_helpers.h b/src/input/mrl_helpers.h new file mode 100644 index 0000000..f4f815c --- /dev/null +++ b/src/input/mrl_helpers.h @@ -0,0 +1,98 @@ +/***************************************************************************** + * mrl_helpers.h + ***************************************************************************** + * Copyright (C) 2016 VLC authors and VideoLAN + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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. + *****************************************************************************/ + +#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" : "%%%02hhx"), *p ); + } + +#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 82b04cc..573ba9d 100644 --- a/src/input/stream_extractor.c +++ b/src/input/stream_extractor.c @@ -35,6 +35,7 @@ #include <assert.h> #include "stream.h" +#include "mrl_helpers.h" /** * \defgroup stream_extractor_Private Stream Extractor Private @@ -166,7 +167,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 { @@ -219,6 +221,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 cdb8f31..b4e37e4 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 _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
