[vlc-commits] stream_filter: smooth: fix url template token replacement

Francois Cartegnie git at videolan.org
Tue Oct 28 21:48:22 CET 2014


vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Tue Oct 28 21:46:00 2014 +0100| [8880f6c7e58d75d52810f5c82f24c62825184b67] | committer: Francois Cartegnie

stream_filter: smooth: fix url template token replacement

Also handles CustomAttributes

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=8880f6c7e58d75d52810f5c82f24c62825184b67
---

 modules/stream_filter/smooth/downloader.c |  105 +++++++++++++++++++++++------
 1 file changed, 86 insertions(+), 19 deletions(-)

diff --git a/modules/stream_filter/smooth/downloader.c b/modules/stream_filter/smooth/downloader.c
index b941b97..ded6f38 100644
--- a/modules/stream_filter/smooth/downloader.c
+++ b/modules/stream_filter/smooth/downloader.c
@@ -28,32 +28,99 @@
 #include <assert.h>
 #include <vlc_stream.h>
 #include <vlc_es.h>
+#include <vlc_charset.h>
 
 #include "smooth.h"
 #include "../../demux/mp4/libmp4.h"
 
-static char *ConstructUrl( const char *template, const char *base_url,
-        const uint64_t bandwidth, const uint64_t start_time )
+static bool Replace( char **ppsz_string, off_t off, const char *psz_old,
+                     const char *psz_new )
 {
-    char *frag, *end, *qual;
-    char *url_template = strdup( template );
-    char *saveptr = NULL;
-
-    qual = strtok_r( url_template, "{", &saveptr );
-    strtok_r( NULL, "}", &saveptr );
-    frag = strtok_r( NULL, "{", &saveptr );
-    strtok_r( NULL, "}", &saveptr );
-    end = strtok_r( NULL, "", &saveptr );
-    char *url = NULL;
-
-    if( asprintf( &url, "%s/%s%"PRIu64"%s%"PRIu64"%s", base_url, qual,
-                bandwidth, frag, start_time, end) < 0 )
+    const size_t i_oldlen = strlen( psz_old );
+    const size_t i_newlen = strlen( psz_new );
+    size_t i_stringlen = strlen( *ppsz_string );
+
+    if ( i_newlen > i_oldlen )
     {
-       return NULL;
+        i_stringlen += i_newlen - i_oldlen;
+        char *psz_realloc = realloc( *ppsz_string, i_stringlen + 1 );
+        if( !psz_realloc )
+            return false;
+        *ppsz_string = psz_realloc;
     }
+    memmove( *ppsz_string + off + i_newlen,
+             *ppsz_string + off + i_oldlen,
+             i_stringlen - off - i_newlen );
+    strncpy( *ppsz_string + off, psz_new, i_newlen );
+
+    return true;
+}
 
-    free( url_template );
-    return url;
+static char *ConstructUrl( const char *psz_template, const char *psz_base_url,
+                           const quality_level_t *p_qlevel, const uint64_t i_start_time )
+{
+    char *psz_path = strdup( psz_template );
+    if ( !psz_path )
+        return NULL;
+
+    char *psz_start;
+    while( true )
+    {
+        if ( (psz_start = strstr( psz_path, "{bitrate}" )) )
+        {
+            char *psz_bitrate = NULL;
+            if ( us_asprintf( &psz_bitrate, "%u", p_qlevel->Bitrate ) < 0 ||
+                 ! Replace( &psz_path, psz_start - psz_path, "{bitrate}", psz_bitrate ) )
+            {
+                free( psz_bitrate );
+                free( psz_path );
+                return false;
+            }
+            free( psz_bitrate );
+        }
+        else if ( (psz_start = strstr( psz_path, "{start time}" )) )
+        {
+            char *psz_starttime = NULL;
+            if ( us_asprintf( &psz_starttime, "%"PRIu64, i_start_time ) < 0 ||
+                 ! Replace( &psz_path, psz_start - psz_path, "{start time}", psz_starttime ) )
+            {
+                free( psz_starttime );
+                free( psz_path );
+                return false;
+            }
+            free( psz_starttime );
+        }
+        else if ( (psz_start = strstr( psz_path, "{CustomAttributes}" )) )
+        {
+            char *psz_attributes = NULL;
+            FOREACH_ARRAY( const custom_attrs_t *p_attrs, p_qlevel->custom_attrs )
+            if ( asprintf( &psz_attributes,
+                           psz_attributes ? "%s,%s=%s" : "%s%s=%s",
+                           psz_attributes ? psz_attributes : "",
+                           p_attrs->psz_key, p_attrs->psz_value ) < 0 )
+                    break;
+            FOREACH_END()
+            if ( !psz_attributes ||
+                 ! Replace( &psz_path, psz_start - psz_path, "{CustomAttributes}", psz_attributes ) )
+            {
+                free( psz_attributes );
+                free( psz_path );
+                return false;
+            }
+            free( psz_attributes );
+        }
+        else
+            break;
+    }
+
+    char *psz_url;
+    if( asprintf( &psz_url, "%s/%s", psz_base_url, psz_path ) < 0 )
+    {
+        free( psz_path );
+        return NULL;
+    }
+    free( psz_path );
+    return psz_url;
 }
 
 static chunk_t * chunk_Get( sms_stream_t *sms, const uint64_t start_time )
@@ -417,7 +484,7 @@ static int Download( stream_t *s, sms_stream_t *sms )
     chunk->type = sms->type;
 
     char *url = ConstructUrl( sms->url_template, p_sys->base_url,
-                                  qlevel->Bitrate, chunk->start_time );
+                              qlevel, chunk->start_time );
     if( !url )
     {
         msg_Err( s, "ConstructUrl returned NULL" );



More information about the vlc-commits mailing list