[vlc-commits] stream_extractor: add vlc_stream_extractor_CreateMRL

Filip Roséen git at videolan.org
Tue Dec 6 15:58:28 CET 2016


vlc | branch: master | Filip Roséen <filip at atch.se> | 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 <thomas at gllm.fr>

> 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



More information about the vlc-commits mailing list