VLC  3.0.15
mrl_helpers.h
Go to the documentation of this file.
1 /*****************************************************************************
2  * mrl_helpers.h
3  *****************************************************************************
4  * Copyright (C) 2016 VLC authors and VideoLAN
5  *
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.
10  *
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.
15  *
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  *****************************************************************************/
20 
21 #ifndef INPUT_MRL_HELPERS_H
22 #define INPUT_MRL_HELPERS_H
23 
24 #include <string.h>
25 #include <stdlib.h>
26 
27 #include <vlc_common.h>
28 #include <vlc_memstream.h>
29 #include <vlc_arrays.h>
30 #include <vlc_url.h>
31 
32 /**
33  * \defgroup mrl_helpers MRL helpers
34  * \ingroup mrl
35  *
36  * Helper functions related to parsing, as well as generating, data
37  * related to the \link MRL-specification\endlink.
38  *
39  * @{
40  * \file
41  **/
42 
43 /**
44  * Escape a fragment identifier for use within an MRL
45  *
46  * The function will generate a string that follows the \link mrl
47  * MRL-specification\endlink regarding \em fragment-identifiers.
48  *
49  * See the \link mrl MRL-specification\endlink for a detailed
50  * explanation of how `payload` will be escaped.
51  *
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 )
59 {
60  struct vlc_memstream mstream;
61 
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 "/" "?"
70 
71  if( vlc_memstream_open( &mstream ) )
72  return VLC_EGENERIC;
73 
74  for( char const* p = payload; *p; ++p )
75  {
76  vlc_memstream_printf( &mstream,
77  ( strchr( "!?", *p ) == NULL &&
78  strchr( RFC3986_FRAGMENT, *p ) ? "%c" : "%%%02hhx"), *p );
79  }
80 
81 #undef RFC3986_FRAGMENT
82 #undef RFC3986_PCHAR
83 #undef RFC3986_UNRESERVEd
84 #undef RFC3986_DIGIT
85 #undef RFC3986_ALPHA
86 #undef RFC3986_SUBDELIMS
87 
88  if( vlc_memstream_close( &mstream ) )
89  return VLC_EGENERIC;
90 
91  *out = mstream.ptr;
92  return VLC_SUCCESS;
93 }
94 
95 /**
96  * Split an \link mrl_technical_fragment MRL-fragment\endlink into identifiers
97  *
98  * Function used to split the fragment-data (also referred to as
99  * anchor-data) into an array containing each of the files specified.
100  *
101  * See the \link mrl MRL-specification\endlink for detailed
102  * information regarding how `payload` will be interpreted.
103  *
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.
107  *
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
113  **/
114 static inline int
115 mrl_FragmentSplit( vlc_array_t* out_items,
116  char const** out_extra,
117  char const* payload )
118 {
119  char const* extra = NULL;
120 
121  vlc_array_init( out_items );
122 
123  while( strncmp( payload, "!/", 2 ) == 0 )
124  {
125  payload += 2;
126 
127  int len = strcspn( payload, "!?" );
128  char* decoded = strndup( payload, len );
129 
130  if( unlikely( !decoded ) || !vlc_uri_decode( decoded ) )
131  goto error;
132 
133  if( vlc_array_append( out_items, decoded ) )
134  {
135  free( decoded );
136  goto error;
137  }
138  payload += len;
139  }
140 
141  if( *payload )
142  {
143  if( *payload == '!' )
144  goto error;
145 
146  if( *payload == '?' && vlc_array_count( out_items ) )
147  ++payload;
148 
149  extra = payload;
150  }
151 
152  *out_extra = extra;
153  return VLC_SUCCESS;
154 
155 error:
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;;
160 }
161 
162 /*
163  * @}
164  **/
165 
166 #endif /* include-guard */
vlc_dictionary_insert
static void vlc_dictionary_insert(vlc_dictionary_t *p_dict, const char *psz_key, void *p_value)
Definition: vlc_arrays.h:566
vlc_meta_Actors
Definition: vlc_meta.h:58
vlc_memstream
Definition: vlc_memstream.h:27
input_attachment_t
Definition: vlc_input.h:154
playlist_SaveArt
int playlist_SaveArt(vlc_object_t *obj, input_item_t *p_item, const void *data, size_t length, const char *psz_type)
Definition: art.c:267
vlc_meta_Get
const char * vlc_meta_Get(const vlc_meta_t *p_meta, vlc_meta_type_t meta_type)
Definition: meta.c:131
vlc_meta_AddExtra
void vlc_meta_AddExtra(vlc_meta_t *m, const char *psz_name, const char *psz_value)
Definition: meta.c:136
vlc_meta_Merge
void vlc_meta_Merge(vlc_meta_t *dst, const vlc_meta_t *src)
Merging meta.
Definition: meta.c:177
vlc_meta_Album
Definition: vlc_meta.h:39
vlc_memstream::ptr
char * ptr
Definition: vlc_memstream.h:51
vlc_meta_Language
Definition: vlc_meta.h:46
vlc_memstream::error
int error
Definition: vlc_memstream.h:66
vlc_common.h
vlc_meta_CopyExtraNames
char ** vlc_meta_CopyExtraNames(const vlc_meta_t *m)
Allocate a copy of all extra meta names and a table with it.
Definition: meta.c:155
vlc_meta_DiscNumber
Definition: vlc_meta.h:60
vlc_meta_GetExtra
const char * vlc_meta_GetExtra(const vlc_meta_t *m, const char *psz_name)
Definition: meta.c:145
vlc_meta_URL
Definition: vlc_meta.h:45
audio_replay_gain_t
Definition: vlc_es.h:56
vlc_dictionary_keys_count
static int vlc_dictionary_keys_count(const vlc_dictionary_t *p_dict)
Definition: vlc_arrays.h:472
input_item_t
Describes an input and is used to spawn input_thread_t objects.
Definition: vlc_input_item.h:58
vlc_dictionary_t
Definition: vlc_arrays.h:386
vlc_meta_Episode
Definition: vlc_meta.h:56
AUDIO_REPLAY_GAIN_TRACK
#define AUDIO_REPLAY_GAIN_TRACK
Definition: vlc_es.h:54
vlc_dictionary_clear
static void vlc_dictionary_clear(vlc_dictionary_t *p_dict, void(*pf_free)(void *p_data, void *p_obj), void *p_obj)
Definition: vlc_arrays.h:407
ITEM_TYPE_FILE
Definition: vlc_input_item.h:110
vlc_uri2path
char * vlc_uri2path(const char *url)
Converts a URI to a local path.
Definition: url.c:240
vlc_input_attachment_Duplicate
static input_attachment_t * vlc_input_attachment_Duplicate(const input_attachment_t *a)
Definition: vlc_input.h:203
input_item_t::lock
vlc_mutex_t lock
Lock for the item.
Definition: vlc_input_item.h:93
vlc_charset.h
meta_export_t::p_item
input_item_t * p_item
Definition: vlc_meta.h:103
vlc_array_append
static int vlc_array_append(vlc_array_t *ar, void *elem)
Definition: vlc_arrays.h:315
audio_replay_gain_t::pf_peak
float pf_peak[(2)]
Definition: vlc_es.h:61
vlc_meta_NowPlaying
Definition: vlc_meta.h:47
input_ExtractAttachmentAndCacheArt
void input_ExtractAttachmentAndCacheArt(input_thread_t *p_input, const char *name)
Definition: meta.c:206
AUDIO_REPLAY_GAIN_ALBUM
#define AUDIO_REPLAY_GAIN_ALBUM
Definition: vlc_es.h:55
VLC_EGENERIC
#define VLC_EGENERIC
Unspecified error.
Definition: vlc_common.h:350
vlc_meta_t::extra_tags
vlc_dictionary_t extra_tags
Definition: meta.c:66
vlc_meta_FreeExtraKey
static void vlc_meta_FreeExtraKey(void *p_data, void *p_obj)
Definition: meta.c:104
RFC3986_FRAGMENT
#define RFC3986_FRAGMENT
input_attachment_t::p_data
void * p_data
Definition: vlc_input.h:162
input_attachment_t::psz_mime
char * psz_mime
Definition: vlc_input.h:158
vlc_meta_TypeToLocalizedString
const char * vlc_meta_TypeToLocalizedString(vlc_meta_type_t meta_type)
Returns a localizes string describing the meta.
Definition: meta.c:51
vlc_gettext
char * vlc_gettext(const char *msgid)
In-tree plugins share their gettext domain with LibVLC.
Definition: textdomain.c:89
vlc_meta_GetExtraCount
unsigned vlc_meta_GetExtraCount(const vlc_meta_t *m)
Definition: meta.c:150
vlc_uri_decode
char * vlc_uri_decode(char *str)
Decodes an URI component in place.
Definition: url.c:53
strndup
char * strndup(const char *, size_t)
vlc_memstream_open
int vlc_memstream_open(struct vlc_memstream *ms)
Definition: memstream.c:104
vlc_meta_t
Definition: meta.c:41
meta_export_t
Definition: vlc_meta.h:100
vlc_meta_Title
Definition: vlc_meta.h:35
meta_export_t::psz_file
const char * psz_file
Definition: vlc_meta.h:104
vlc_meta_EncodedBy
Definition: vlc_meta.h:50
msg_Warn
#define msg_Warn(p_this,...)
Definition: vlc_messages.h:84
vlc_array_t
Definition: vlc_arrays.h:238
vlc_object_release
#define vlc_object_release(a)
Definition: vlc_objects.h:63
vlc_meta_Artist
Definition: vlc_meta.h:36
module_t
Internal module descriptor.
Definition: modules.h:79
vlc_array_count
static size_t vlc_array_count(vlc_array_t *p_array)
Definition: vlc_arrays.h:257
vlc_memstream.h
audio_replay_gain_t::pb_peak
bool pb_peak[(2)]
Definition: vlc_es.h:59
vlc_dictionary_all_keys
static char ** vlc_dictionary_all_keys(const vlc_dictionary_t *p_dict)
Definition: vlc_arrays.h:498
vlc_dictionary_value_for_key
static void * vlc_dictionary_value_for_key(const vlc_dictionary_t *p_dict, const char *psz_key)
Definition: vlc_arrays.h:450
vlc_meta_ArtworkURL
Definition: vlc_meta.h:51
vlc_meta_SetStatus
void vlc_meta_SetStatus(vlc_meta_t *m, int status)
Definition: meta.c:168
input_thread_private_t::p_item
input_item_t * p_item
Definition: input_internal.h:135
vlc_meta_Date
Definition: vlc_meta.h:43
vlc_meta_TrackTotal
Definition: vlc_meta.h:53
vlc_meta_Delete
void vlc_meta_Delete(vlc_meta_t *m)
Definition: meta.c:110
mrl_FragmentSplit
static int mrl_FragmentSplit(vlc_array_t *out_items, char const **out_extra, char const *payload)
Split an MRL-fragment into identifiers.
Definition: mrl_helpers.h:114
input_item_IsArtFetched
bool input_item_IsArtFetched(input_item_t *p_item)
Definition: item.c:449
vlc_meta_t::ppsz_meta
char * ppsz_meta[27]
Definition: meta.c:64
psz_name
const char * psz_name
Definition: vlc_codecs.h:315
vlc_meta_New
vlc_meta_t * vlc_meta_New(void)
vlc_meta contructor.
Definition: meta.c:92
playlist_FindArtInCache
int playlist_FindArtInCache(input_item_t *p_item)
Definition: art.c:161
audio_replay_gain_t::pf_gain
float pf_gain[(2)]
Definition: vlc_es.h:66
vlc_meta_Genre
Definition: vlc_meta.h:37
vlc_input_attachment_Delete
static void vlc_input_attachment_Delete(input_attachment_t *a)
Definition: vlc_input.h:164
vlc_url.h
mrl_EscapeFragmentIdentifier
static int mrl_EscapeFragmentIdentifier(char **out, char const *payload)
Escape a fragment identifier for use within an MRL.
Definition: mrl_helpers.h:57
likely
#define likely(p)
Definition: vlc_common.h:113
vlc_object_t
The main vlc_object_t structure.
Definition: vlc_objects.h:39
input_item_WriteMeta
int input_item_WriteMeta(vlc_object_t *obj, input_item_t *p_item)
Definition: meta.c:256
VLC_ENOMEM
#define VLC_ENOMEM
Not enough memory.
Definition: vlc_common.h:351
vlc_array_init
static void vlc_array_init(vlc_array_t *p_array)
Definition: vlc_arrays.h:244
VLC_UNUSED
#define VLC_UNUSED(x)
Definition: vlc_common.h:912
vlc_meta_AlbumArtist
Definition: vlc_meta.h:59
VLC_SUCCESS
#define VLC_SUCCESS
No error.
Definition: vlc_common.h:349
input_attachment_t::i_data
size_t i_data
Definition: vlc_input.h:161
vlc_array_clear
static void vlc_array_clear(vlc_array_t *p_array)
Definition: vlc_arrays.h:250
vlc_meta_Copyright
Definition: vlc_meta.h:38
strdup
char * strdup(const char *)
psz_value
char psz_value[8]
Definition: vout_intf.c:91
input_thread_private_t::i_attachment
int i_attachment
Definition: input_internal.h:128
vlc_custom_create
#define vlc_custom_create(o, s, n)
Definition: libvlc.h:108
input_item_GetURI
char * input_item_GetURI(input_item_t *p_i)
Definition: item.c:320
input_priv
static input_thread_private_t * input_priv(input_thread_t *input)
Definition: input_internal.h:179
name
const char name[16]
Definition: httpd.c:1249
vlc_meta_GetStatus
int vlc_meta_GetStatus(vlc_meta_t *m)
vlc_meta status (see vlc_meta_status_e)
Definition: meta.c:163
vlc_meta_Publisher
Definition: vlc_meta.h:49
vlc_array_item_at_index
#define vlc_array_item_at_index(ar, idx)
Definition: vlc_arrays.h:263
N_
#define N_(str)
Definition: vlc_fixups.h:372
vlc_meta_Season
Definition: vlc_meta.h:55
vlc_meta_Rating
Definition: vlc_meta.h:42
vlc_mutex_unlock
void vlc_mutex_unlock(vlc_mutex_t *p_mutex)
Releases a mutex.
Definition: thread.c:138
unlikely
#define unlikely(p)
Definition: vlc_common.h:114
vlc_memstream_printf
int vlc_memstream_printf(struct vlc_memstream *ms, const char *fmt,...)
Definition: memstream.c:184
input_attachment_t::psz_name
char * psz_name
Definition: vlc_input.h:157
vlc_meta_t::i_status
int i_status
Definition: meta.c:68
vlc_meta_TrackNumber
Definition: vlc_meta.h:40
vlc_meta_Set
void vlc_meta_Set(vlc_meta_t *p_meta, vlc_meta_type_t meta_type, const char *psz_val)
vlc_meta has two kinds of meta, the one in a table, and the one in a dictionary.
Definition: meta.c:124
kVLCDictionaryNotFound
static void *const kVLCDictionaryNotFound
Definition: vlc_arrays.h:392
vlc_dictionary_init
static void vlc_dictionary_init(vlc_dictionary_t *p_dict, int i_size)
Definition: vlc_arrays.h:394
vlc_meta_TrackID
Definition: vlc_meta.h:52
vlc_playlist.h
vlc_meta_Setting
Definition: vlc_meta.h:44
vlc_meta_ESNowPlaying
Definition: vlc_meta.h:48
vlc_arrays.h
input_thread_private_t::attachment
input_attachment_t ** attachment
Definition: input_internal.h:129
input_thread_t
Main structure representing an input thread.
Definition: vlc_input.h:221
VLC_OBJECT
#define VLC_OBJECT(x)
Type-safe vlc_object_t cast.
Definition: vlc_common.h:464
vlc_meta_type_t
vlc_meta_type_t
Definition: vlc_meta.h:33
us_atof
double us_atof(const char *str)
us_atof() has the same prototype as ANSI C atof() but it expects a dot as decimal separator,...
Definition: charset.c:87
vlc_meta_Description
Definition: vlc_meta.h:41
vlc_audio_replay_gain_MergeFromMeta
void vlc_audio_replay_gain_MergeFromMeta(audio_replay_gain_t *p_dst, const vlc_meta_t *p_meta)
Definition: meta.c:290
module_unneed
#define module_unneed(a, b)
Definition: vlc_modules.h:49
input_internal.h
IsUTF8
static const char * IsUTF8(const char *str)
Checks UTF-8 validity.
Definition: vlc_charset.h:63
vlc_meta_Director
Definition: vlc_meta.h:54
vlc_mutex_lock
void vlc_mutex_lock(vlc_mutex_t *p_mutex)
Acquires a mutex.
Definition: thread.c:123
input_item_t::i_type
uint8_t i_type
Type (file, disc, ...
Definition: vlc_input_item.h:95
vlc_dictionary_remove_value_for_key
static void vlc_dictionary_remove_value_for_key(const vlc_dictionary_t *p_dict, const char *psz_key, void(*pf_free)(void *p_data, void *p_obj), void *p_obj)
Definition: vlc_arrays.h:572
msg_Err
#define msg_Err(p_this,...)
Definition: vlc_messages.h:82
audio_replay_gain_t::pb_gain
bool pb_gain[(2)]
Definition: vlc_es.h:64
vlc_memstream_close
int vlc_memstream_close(struct vlc_memstream *ms)
Definition: memstream.c:119
VLC_META_TYPE_COUNT
#define VLC_META_TYPE_COUNT
Definition: vlc_meta.h:64
module_need
#define module_need(a, b, c, d)
Definition: vlc_modules.h:47
vlc_meta_ShowName
Definition: vlc_meta.h:57
p
#define p(t)
vlc_modules.h