codec/esout: add support for CEA708
[vlc.git] / src / input / mrl_helpers.h
blob09916c6070ce03df2fa540f5a4d911f73b161f24
1 /*****************************************************************************
2 * mrl_helpers.h
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
24 #include <string.h>
25 #include <stdlib.h>
27 #include <vlc_common.h>
28 #include <vlc_memstream.h>
29 #include <vlc_arrays.h>
30 #include <vlc_url.h>
32 /**
33 * \defgroup mrl_helpers MRL helpers
34 * \ingroup mrl
36 * Helper functions related to parsing, as well as generating, data
37 * related to the \link MRL-specification\endlink.
39 * @{
40 * \file
41 **/
43 /**
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.
56 **/
57 static inline int
58 mrl_EscapeFragmentIdentifier( char** out, char const* payload )
60 struct vlc_memstream mstream;
62 #define RFC3986_SUBDELIMS "!" "$" "&" "'" "(" ")" \
63 "*" "+" "," ";" "="
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 ) )
72 return VLC_EGENERIC;
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
82 #undef RFC3986_PCHAR
83 #undef RFC3986_UNRESERVEd
84 #undef RFC3986_DIGIT
85 #undef RFC3986_ALPHA
86 #undef RFC3986_SUBDELIMS
88 if( vlc_memstream_close( &mstream ) )
89 return VLC_EGENERIC;
91 *out = mstream.ptr;
92 return VLC_SUCCESS;
95 /**
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
114 static inline int
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 )
125 payload += 2;
127 int len = strcspn( payload, "!?" );
128 char* decoded = strndup( payload, len );
130 if( unlikely( !decoded ) || !vlc_uri_decode( decoded ) )
131 goto error;
133 vlc_array_append( out_items, decoded );
134 payload += len;
137 if( *payload )
139 if( *payload == '!' )
140 goto error;
142 if( *payload == '?' && vlc_array_count( out_items ) )
143 ++payload;
145 extra = payload;
148 *out_extra = extra;
149 return VLC_SUCCESS;
151 error:
152 for( size_t i = 0; i < vlc_array_count( out_items ); ++i )
153 free( vlc_array_item_at_index( out_items, i ) );
154 vlc_array_clear( out_items );
155 return VLC_EGENERIC;;
159 * @}
162 #endif /* include-guard */