[vlc-devel] [RFC 05/10] stream_extractor: add vlc_stream_extractor_CreateMRL
Filip Roséen
filip at atch.se
Mon Nov 28 03:22:24 CET 2016
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 );
+ }
+
+#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
--
2.10.2
More information about the vlc-devel
mailing list