diff --git a/include/vlc_stream_extractor.h b/include/vlc_stream_extractor.h index 888e3a5d22..bb4a736380 100644 --- a/include/vlc_stream_extractor.h +++ b/include/vlc_stream_extractor.h @@ -123,11 +123,14 @@ VLC_USED; * * \param extractor the stream_directory_t for which the entity belongs * \param subentry the name of the entity in question + * \param volumes media additional volumes MRLs + * \param volumes_count number of additional volumes * * \return a pointer to the resulting MRL on success, NULL on failure **/ VLC_API char* vlc_stream_extractor_CreateMRL( stream_directory_t *extractor, - char const* subentry ); + char const* subentry, + char const **volumes, size_t volumes_count ); /** * \name Attach a stream-extractor to the passed stream diff --git a/modules/stream_extractor/archive.c b/modules/stream_extractor/archive.c index 07c3da2945..f0f0bf4089 100644 --- a/modules/stream_extractor/archive.c +++ b/modules/stream_extractor/archive.c @@ -551,7 +551,7 @@ static int ReadDir( stream_directory_t* p_directory, input_item_node_t* p_node ) if( unlikely( !path ) ) break; - char* mrl = vlc_stream_extractor_CreateMRL( p_directory, path ); + char* mrl = vlc_stream_extractor_CreateMRL( p_directory, path, NULL, 0 ); if( unlikely( !mrl ) ) break; diff --git a/src/input/mrl_helpers.h b/src/input/mrl_helpers.h index 5e217ceb3e..a7fe2da1e5 100644 --- a/src/input/mrl_helpers.h +++ b/src/input/mrl_helpers.h @@ -92,6 +92,7 @@ mrl_EscapeFragmentIdentifier( char const* payload ) struct mrl_info { vlc_array_t identifiers; + vlc_array_t volumes; char const *extra; }; @@ -101,12 +102,16 @@ mrl_info_Clean( struct mrl_info *mrli ) for( size_t i = 0; i < vlc_array_count( &mrli->identifiers ); ++i ) free( vlc_array_item_at_index( &mrli->identifiers, i ) ); vlc_array_clear( &mrli->identifiers ); + for( size_t i = 0; i < vlc_array_count( &mrli->volumes ); ++i ) + free( vlc_array_item_at_index( &mrli->volumes, i ) ); + vlc_array_clear( &mrli->volumes ); } static inline void mrl_info_Init( struct mrl_info *mrli ) { vlc_array_init( &mrli->identifiers ); + vlc_array_init( &mrli->volumes ); mrli->extra = NULL; } @@ -151,6 +156,24 @@ mrl_FragmentSplit( struct mrl_info *mrli, payload += len; } + while( strncmp( payload, "!+", 2 ) == 0 ) + { + payload += 2; + + int len = strcspn( payload, "!?" ); + char* decoded = strndup( payload, len ); + + if( unlikely( !decoded ) || !vlc_uri_decode( decoded ) ) + goto error; + + if( vlc_array_append( &mrli->volumes, decoded ) ) + { + free( decoded ); + goto error; + } + payload += len; + } + if( *payload ) { if( *payload == '!' ) diff --git a/src/input/stream_extractor.c b/src/input/stream_extractor.c index 9baae004f4..5c5c42df32 100644 --- a/src/input/stream_extractor.c +++ b/src/input/stream_extractor.c @@ -87,7 +87,8 @@ struct stream_extractor_private { **/ VLC_MALLOC static char* -StreamExtractorCreateMRL( char const* base, char const* subentry ) +StreamExtractorCreateMRL( char const* base, char const* subentry, + char const** volumes, size_t volumes_count ) { struct vlc_memstream buffer; char* escaped; @@ -110,6 +111,12 @@ StreamExtractorCreateMRL( char const* base, char const* subentry ) vlc_memstream_puts( &buffer, "!/" ); vlc_memstream_puts( &buffer, escaped ); + for( size_t i=0; ipf_seek = se_StreamSeek; s->pf_control = se_StreamControl; s->psz_url = StreamExtractorCreateMRL( priv->extractor.source->psz_url, - priv->extractor.identifier ); + priv->extractor.identifier, + NULL, 0 ); if( unlikely( !s->psz_url ) ) return VLC_ENOMEM; @@ -362,9 +370,11 @@ stream_extractor_AttachParsed( stream_t** source, const struct mrl_info *mrli ) char* vlc_stream_extractor_CreateMRL( stream_directory_t* directory, - char const* subentry ) + char const* subentry, + char const **volumes, size_t volumes_count ) { - return StreamExtractorCreateMRL( directory->source->psz_url, subentry ); + return StreamExtractorCreateMRL( directory->source->psz_url, subentry, + volumes, volumes_count ); } /**