[vlc-commits] lua: revector input item generation
Rémi Denis-Courmont
git at videolan.org
Tue Apr 18 22:43:18 CEST 2017
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Tue Apr 18 23:13:33 2017 +0300| [6030a44d47e2a4d9daed4ac85d8852c594e9b026] | committer: Rémi Denis-Courmont
lua: revector input item generation
This splits vlclua_playlist_add_internal() in two functions. The new
function parses a single input item from a Lua script.
This also adds handling for a few error cases.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=6030a44d47e2a4d9daed4ac85d8852c594e9b026
---
modules/lua/vlc.c | 268 +++++++++++++++++++++++++++---------------------------
modules/lua/vlc.h | 2 +
2 files changed, 136 insertions(+), 134 deletions(-)
diff --git a/modules/lua/vlc.c b/modules/lua/vlc.c
index 0270a4bd73..db3bb4afa6 100644
--- a/modules/lua/vlc.c
+++ b/modules/lua/vlc.c
@@ -463,158 +463,158 @@ void vlclua_read_options( vlc_object_t *p_this, lua_State *L,
lua_pop( L, 1 ); /* pop "options" */
}
+input_item_t *vlclua_read_input_item(vlc_object_t *obj, lua_State *L)
+{
+ if (!lua_istable(L, -1))
+ {
+ msg_Warn(obj, "Playlist item should be a table" );
+ return NULL;
+ }
+
+ lua_getfield(L, -1, "path");
+
+ /* playlist key item path */
+ if (!lua_isstring(L, -1))
+ {
+ lua_pop(L, 1); /* pop "path" */
+ msg_Warn(obj, "Playlist item's path should be a string");
+ return NULL;
+ }
+
+ /* Read path and name */
+ const char *path = lua_tostring(L, -1);
+ msg_Dbg(obj, "Path: %s", path);
+
+ const char *name = NULL;
+ lua_getfield(L, -2, "name");
+ if (lua_isstring(L, -1))
+ {
+ name = lua_tostring(L, -1);
+ msg_Dbg(obj, "Name: %s", name);
+ }
+ else if (!lua_isnil(L, -1))
+ msg_Warn(obj, "Playlist item name should be a string" );
+
+ /* Read duration */
+ mtime_t duration = -1;
+
+ lua_getfield( L, -3, "duration" );
+ if (lua_isnumber(L, -1))
+ duration = (mtime_t)(lua_tonumber(L, -1) * (CLOCK_FREQ * 1.));
+ else if (!lua_isnil(L, -1))
+ msg_Warn(obj, "Playlist item duration should be a number (seconds)");
+ lua_pop( L, 1 ); /* pop "duration" */
+
+ /* Read options: item must be on top of stack */
+ char **optv = NULL;
+ int optc = 0;
+
+ lua_pushvalue(L, -3);
+ vlclua_read_options(obj, L, &optc, &optv);
+
+ /* Create input item */
+ input_item_t *item = input_item_NewExt(path, name, duration,
+ ITEM_TYPE_UNKNOWN,
+ ITEM_NET_UNKNOWN);
+ if (unlikely(item == NULL))
+ goto out;
+
+ input_item_AddOptions(item, optc, (const char **)optv,
+ VLC_INPUT_OPTION_TRUSTED);
+ lua_pop(L, 3); /* pop "path name item" */
+ /* playlist key item */
+
+ /* Read meta data: item must be on top of stack */
+ vlclua_read_meta_data(obj, L, item);
+
+ /* copy the psz_name to the meta data, if "Title" is still empty */
+ char* title = input_item_GetTitle(item);
+ if (title == NULL)
+ input_item_SetTitle(item, name);
+ free(title);
+
+ /* Read custom meta data: item must be on top of stack*/
+ vlclua_read_custom_meta_data(obj, L, item);
+
+out:
+ while (optc > 0)
+ free(optv[--optc]);
+ free(optv);
+ return item;
+}
+
#undef vlclua_playlist_add_internal
-int vlclua_playlist_add_internal( vlc_object_t *p_this, lua_State *L,
- playlist_t *p_playlist,
- input_item_t *p_parent, bool b_play )
+int vlclua_playlist_add_internal(vlc_object_t *obj, lua_State *L,
+ playlist_t *playlist, input_item_t *parent,
+ bool play)
{
- int i_count = 0;
- input_item_node_t *p_parent_node = NULL;
+ int count = 0;
- assert( p_parent || p_playlist );
+ assert(parent != NULL || playlist != NULL);
/* playlist */
- if( lua_istable( L, -1 ) )
+ if (!lua_istable(L, -1))
{
- if( p_parent ) p_parent_node = input_item_node_Create( p_parent );
- lua_pushnil( L );
- /* playlist nil */
- while( lua_next( L, -2 ) )
- {
- /* playlist key item */
- /* <Parse playlist item> */
- if( lua_istable( L, -1 ) )
- {
- lua_getfield( L, -1, "path" );
- /* playlist key item path */
- if( lua_isstring( L, -1 ) )
- {
- char *psz_oldurl = NULL;
- const char *psz_path = NULL;
- const char *psz_name = NULL;
- char **ppsz_options = NULL;
- int i_options = 0;
- mtime_t i_duration = -1;
- input_item_t *p_input;
-
- /* Read path and name */
- if (p_parent) {
- psz_oldurl = input_item_GetURI( p_parent );
- msg_Dbg( p_this, "old path: %s", psz_oldurl );
- }
- psz_path = lua_tostring( L, -1 );
- msg_Dbg( p_this, "Path: %s", psz_path );
- lua_getfield( L, -2, "name" );
- /* playlist key item path name */
- if( lua_isstring( L, -1 ) )
- {
- psz_name = lua_tostring( L, -1 );
- msg_Dbg( p_this, "Name: %s", psz_name );
- }
- else
- {
- if( !lua_isnil( L, -1 ) )
- msg_Warn( p_this, "Playlist item name should be a string." );
- }
+ msg_Warn(obj, "Playlist should be a table.");
+ return 0;
+ }
- /* Read duration */
- lua_getfield( L, -3, "duration" );
- /* playlist key item path name duration */
- if( lua_isnumber( L, -1 ) )
- {
- i_duration = (mtime_t)(lua_tonumber( L, -1 )*1e6);
- }
- else if( !lua_isnil( L, -1 ) )
- {
- msg_Warn( p_this, "Playlist item duration should be a number (in seconds)." );
- }
- lua_pop( L, 1 ); /* pop "duration" */
-
- /* playlist key item path name */
-
- /* Read options: item must be on top of stack */
- lua_pushvalue( L, -3 );
- /* playlist key item path name item */
- vlclua_read_options( p_this, L, &i_options, &ppsz_options );
-
- /* Create input item */
- p_input = input_item_NewExt( psz_path, psz_name, i_duration,
- ITEM_TYPE_UNKNOWN, ITEM_NET_UNKNOWN );
- input_item_AddOptions( p_input, i_options,
- (const char **)ppsz_options,
- VLC_INPUT_OPTION_TRUSTED );
- lua_pop( L, 3 ); /* pop "path name item" */
- /* playlist key item */
-
- /* Read meta data: item must be on top of stack */
- vlclua_read_meta_data( p_this, L, p_input );
-
- /* copy the original URL to the meta data, if "URL" is still empty */
- char* url = input_item_GetURL( p_input );
- if( url == NULL && p_parent)
- {
- EnsureUTF8( psz_oldurl );
- msg_Dbg( p_this, "meta-URL: %s", psz_oldurl );
- input_item_SetURL ( p_input, psz_oldurl );
- }
- free( psz_oldurl );
- free( url );
+ input_item_node_t *node = NULL;
- /* copy the psz_name to the meta data, if "Title" is still empty */
- char* title = input_item_GetTitle( p_input );
- if( title == NULL )
- input_item_SetTitle ( p_input, psz_name );
- free( title );
+ if (parent != NULL)
+ node = input_item_node_Create(parent);
- /* Read custom meta data: item must be on top of stack*/
- vlclua_read_custom_meta_data( p_this, L, p_input );
+ lua_pushnil(L);
- /* Append item to playlist */
- if( p_parent ) /* Add to node */
+ /* playlist nil */
+ while (lua_next(L, -2))
+ {
+ input_item_t *item = vlclua_read_input_item(obj, L);
+ if (item != NULL)
+ {
+ /* Append item to playlist */
+ if (node != NULL) /* Add to node */
+ {
+ /* copy the original URL to the meta data,
+ * if "URL" is still empty */
+ char *url = input_item_GetURL(item);
+ if (url == NULL)
+ {
+ url = input_item_GetURI(parent);
+ if (likely(url != NULL))
{
- input_item_CopyOptions( p_input, p_parent );
- input_item_node_AppendItem( p_parent_node, p_input );
+ EnsureUTF8(url);
+ msg_Dbg(obj, "meta-URL: %s", url);
+ input_item_SetURL(item, url);
}
- else /* Play or Enqueue (preparse) */
- /* FIXME: playlist_AddInput() can fail */
- playlist_AddInput( p_playlist, p_input,
- ( b_play ? PLAYLIST_GO : 0 ),
- true );
- i_count ++; /* increment counter */
- input_item_Release( p_input );
- while( i_options > 0 )
- free( ppsz_options[--i_options] );
- free( ppsz_options );
}
- else
- {
- lua_pop( L, 1 ); /* pop "path" */
- msg_Warn( p_this,
- "Playlist item's path should be a string" );
- }
- /* playlist key item */
- }
- else
- {
- msg_Warn( p_this, "Playlist item should be a table" );
+ free(url);
+
+ input_item_CopyOptions(item, parent);
+ input_item_node_AppendItem(node, item);
}
- /* <Parse playlist item> */
- lua_pop( L, 1 ); /* pop the value, keep the key for
- * the next lua_next() call */
- /* playlist key */
- }
- /* playlist */
- if( p_parent )
- {
- if( i_count ) input_item_node_PostAndDelete( p_parent_node );
- else input_item_node_Delete( p_parent_node );
+ else if (likely(parent == NULL))
+ /* Play or Enqueue (preparse) */
+ /* FIXME: playlist_AddInput() can fail */
+ playlist_AddInput(playlist, item, play ? PLAYLIST_GO : 0,
+ true);
+
+ input_item_Release(item);
+ count++;
}
+ /* pop the value, keep the key for the next lua_next() call */
+ lua_pop(L, 1);
}
- else
+ /* playlist */
+
+ if (node != NULL)
{
- msg_Warn( p_this, "Playlist should be a table." );
+ if (count > 0)
+ input_item_node_PostAndDelete(node);
+ else
+ input_item_node_Delete(node);
}
- return i_count;
+ return count;
}
static int vlc_sd_probe_Open( vlc_object_t *obj )
diff --git a/modules/lua/vlc.h b/modules/lua/vlc.h
index f79d9c6c1d..972b35f1da 100644
--- a/modules/lua/vlc.h
+++ b/modules/lua/vlc.h
@@ -180,6 +180,8 @@ void vlclua_read_meta_data( vlc_object_t *, lua_State *, input_item_t * );
void vlclua_read_custom_meta_data( vlc_object_t *, lua_State *,
input_item_t *);
#define vlclua_read_custom_meta_data( a, b, c ) vlclua_read_custom_meta_data( VLC_OBJECT( a ), b, c )
+
+input_item_t *vlclua_read_input_item(vlc_object_t *, lua_State *);
int vlclua_playlist_add_internal( vlc_object_t *, lua_State *, playlist_t *,
input_item_t *, bool );
#define vlclua_playlist_add_internal( a, b, c, d, e ) vlclua_playlist_add_internal( VLC_OBJECT( a ), b, c, d, e )
More information about the vlc-commits
mailing list