Commit fcf55930 authored by Filip Roséen's avatar Filip Roséen Committed by 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's avatarThomas Guillem <thomas@gllm.fr>
parent 70992481
......@@ -86,12 +86,29 @@ 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
......
......@@ -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 \
......
/*****************************************************************************
* 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 */
......@@ -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;
}
/**
* @}
**/
......
......@@ -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
......
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