1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2016 VLC authors and VideoLAN
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 2.1 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
19 *****************************************************************************/
21 #ifndef INPUT_MRL_HELPERS_H
22 #define INPUT_MRL_HELPERS_H
27 #include <vlc_common.h>
28 #include <vlc_memstream.h>
29 #include <vlc_arrays.h>
33 * \defgroup mrl_helpers MRL helpers
36 * Helper functions related to parsing, as well as generating, data
37 * related to the \link MRL-specification\endlink.
44 * Escape a fragment identifier for use within an MRL
46 * The function will generate a string that follows the \link mrl
47 * MRL-specification\endlink regarding \em fragment-identifiers.
49 * See the \link mrl MRL-specification\endlink for a detailed
50 * explanation of how `payload` will be escaped.
52 * \param[out] out `*out` will refer to the created string on success,
53 * and an unspecified value on error.
54 * \param[in] payload the data to escape.
55 * \return VLC_SUCCESS on success, an error-code on failure.
58 mrl_EscapeFragmentIdentifier( char** out
, char const* payload
)
60 struct vlc_memstream mstream
;
62 #define RFC3986_SUBDELIMS "!" "$" "&" "'" "(" ")" \
64 #define RFC3986_ALPHA "abcdefghijklmnopqrstuvwxyz" \
65 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
66 #define RFC3986_DIGIT "0123456789"
67 #define RFC3986_UNRESERVED RFC3986_ALPHA RFC3986_DIGIT "-" "." "_" "~"
68 #define RFC3986_PCHAR RFC3986_UNRESERVED RFC3986_SUBDELIMS ":" "@"
69 #define RFC3986_FRAGMENT RFC3986_PCHAR "/" "?"
71 if( vlc_memstream_open( &mstream
) )
74 for( char const* p
= payload
; *p
; ++p
)
76 vlc_memstream_printf( &mstream
,
77 ( strchr( "!?", *p
) == NULL
&&
78 strchr( RFC3986_FRAGMENT
, *p
) ? "%c" : "%%%02hhx"), *p
);
81 #undef RFC3986_FRAGMENT
83 #undef RFC3986_UNRESERVEd
86 #undef RFC3986_SUBDELIMS
88 if( vlc_memstream_close( &mstream
) )
96 * Split an \link mrl_technical_fragment MRL-fragment\endlink into identifiers
98 * Function used to split the fragment-data (also referred to as
99 * anchor-data) into an array containing each of the files specified.
101 * See the \link mrl MRL-specification\endlink for detailed
102 * information regarding how `payload` will be interpreted.
104 * \warning On success, the caller has ownership of the contents of *out_items
105 * which means that it is responsible for freeing the individual
106 * elements, as well as cleaning the array itself.
108 * \param[out] out_items storage for a vlc_array_t that will contain the
109 * parsed identifiers on success.
110 * \param[out] out_extra `*out_extra` will point to any remaining data (if any)
111 * \param[in] payload the data to parse
112 * \return VLC_SUCCESS on success, an error-code on failure
115 mrl_FragmentSplit( vlc_array_t
* out_items
,
116 char const** out_extra
,
117 char const* payload
)
119 char const* extra
= NULL
;
121 vlc_array_init( out_items
);
123 while( strncmp( payload
, "!/", 2 ) == 0 )
127 int len
= strcspn( payload
, "!?" );
128 char* decoded
= strndup( payload
, len
);
130 if( unlikely( !decoded
) || !vlc_uri_decode( decoded
) )
133 if( vlc_array_append( out_items
, decoded
) )
143 if( *payload
== '!' )
146 if( *payload
== '?' && vlc_array_count( out_items
) )
156 for( size_t i
= 0; i
< vlc_array_count( out_items
); ++i
)
157 free( vlc_array_item_at_index( out_items
, i
) );
158 vlc_array_clear( out_items
);
159 return VLC_EGENERIC
;;
166 #endif /* include-guard */