1 /*****************************************************************************
2 * stream_filter.c : Lua playlist stream filter module
3 *****************************************************************************
4 * Copyright (C) 2007-2008 the VideoLAN team
6 * Authors: Antoine Cellerier <dionoea at videolan tod org>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21 *****************************************************************************/
23 /*****************************************************************************
25 *****************************************************************************/
34 #include <vlc_common.h>
35 #include <vlc_access.h>
40 /*****************************************************************************
41 * Demux specific functions
42 *****************************************************************************/
43 struct vlclua_playlist
51 static int vlclua_demux_peek( lua_State
*L
)
53 stream_t
*s
= (stream_t
*)vlclua_get_this(L
);
54 int n
= luaL_checkinteger( L
, 1 );
55 const uint8_t *p_peek
;
57 ssize_t val
= vlc_stream_Peek(s
->s
, &p_peek
, n
);
59 lua_pushlstring(L
, (const char *)p_peek
, val
);
65 static int vlclua_demux_read( lua_State
*L
)
67 stream_t
*s
= (stream_t
*)vlclua_get_this(L
);
68 int n
= luaL_checkinteger( L
, 1 );
69 char *buf
= malloc(n
);
73 ssize_t val
= vlc_stream_Read(s
->s
, buf
, n
);
75 lua_pushlstring(L
, buf
, val
);
86 static int vlclua_demux_readline( lua_State
*L
)
88 stream_t
*s
= (stream_t
*)vlclua_get_this(L
);
89 char *line
= vlc_stream_ReadLine(s
->s
);
93 lua_pushstring(L
, line
);
102 /*****************************************************************************
104 *****************************************************************************/
105 /* Functions to register */
106 static const luaL_Reg p_reg
[] =
108 { "peek", vlclua_demux_peek
},
112 /* Functions to register for parse() function call only */
113 static const luaL_Reg p_reg_parse
[] =
115 { "read", vlclua_demux_read
},
116 { "readline", vlclua_demux_readline
},
120 /*****************************************************************************
121 * Called through lua_scripts_batch_execute to call 'probe' on
122 * the script pointed by psz_filename.
123 *****************************************************************************/
124 static int probe_luascript(vlc_object_t
*obj
, const char *filename
,
125 const luabatch_context_t
*ctx
)
127 stream_t
*s
= (stream_t
*)obj
;
128 struct vlclua_playlist
*sys
= s
->p_sys
;
130 /* Initialise Lua state structure */
131 lua_State
*L
= luaL_newstate();
137 /* Load Lua libraries */
138 luaL_openlibs( L
); /* FIXME: Don't open all the libs? */
140 vlclua_set_this(L
, s
);
141 luaL_register_namespace( L
, "vlc", p_reg
);
143 luaopen_strings( L
);
145 luaopen_variables( L
);
148 if (sys
->path
!= NULL
)
149 lua_pushstring(L
, sys
->path
);
152 lua_setfield( L
, -2, "path" );
154 if (sys
->access
!= NULL
)
155 lua_pushstring(L
, sys
->access
);
158 lua_setfield( L
, -2, "access" );
162 /* Setup the module search path */
163 if (vlclua_add_modules_path(L
, filename
))
165 msg_Warn(s
, "error setting the module search path for %s", filename
);
169 /* Load and run the script(s) */
170 if (vlclua_dofile(VLC_OBJECT(s
), L
, filename
))
172 msg_Warn(s
, "error loading script %s: %s", filename
,
173 lua_tostring(L
, lua_gettop(L
)));
177 lua_getglobal( L
, "probe" );
178 if( !lua_isfunction( L
, -1 ) )
180 msg_Warn(s
, "error running script %s: function %s(): %s",
181 filename
, "probe", "not found");
185 if( lua_pcall( L
, 0, 1, 0 ) )
187 msg_Warn(s
, "error running script %s: function %s(): %s",
188 filename
, "probe", lua_tostring(L
, lua_gettop(L
)));
192 if( lua_gettop( L
) )
194 if( lua_toboolean( L
, 1 ) )
196 msg_Dbg(s
, "Lua playlist script %s's "
197 "probe() function was successful", filename
);
199 sys
->filename
= strdup(filename
);
211 static int ReadDir(stream_t
*s
, input_item_node_t
*node
)
213 struct vlclua_playlist
*sys
= s
->p_sys
;
214 lua_State
*L
= sys
->L
;
216 luaL_register_namespace( L
, "vlc", p_reg_parse
);
218 lua_getglobal( L
, "parse" );
220 if( !lua_isfunction( L
, -1 ) )
222 msg_Warn(s
, "error running script %s: function %s(): %s",
223 sys
->filename
, "parse", "not found");
227 if( lua_pcall( L
, 0, 1, 0 ) )
229 msg_Warn(s
, "error running script %s: function %s(): %s",
230 sys
->filename
, "parse", lua_tostring(L
, lua_gettop(L
)));
236 msg_Err(s
, "script went completely foobar");
240 if (!lua_istable(L
, -1))
242 msg_Warn(s
, "Playlist should be a table.");
249 while (lua_next(L
, -2))
251 input_item_t
*item
= vlclua_read_input_item(VLC_OBJECT(s
), L
);
254 /* copy the original URL to the meta data,
255 * if "URL" is still empty */
256 char *url
= input_item_GetURL(item
);
257 if (url
== NULL
&& s
->psz_url
!= NULL
)
258 input_item_SetURL(item
, s
->psz_url
);
261 input_item_node_AppendItem(node
, item
);
262 input_item_Release(item
);
264 /* pop the value, keep the key for the next lua_next() call */
272 /*****************************************************************************
273 * Import_LuaPlaylist: main import function
274 *****************************************************************************/
275 int Import_LuaPlaylist(vlc_object_t
*obj
)
277 stream_t
*s
= (stream_t
*)obj
;
279 if( lua_Disabled( obj
) )
282 struct vlclua_playlist
*sys
= malloc(sizeof (*sys
));
283 if (unlikely(sys
== NULL
))
290 if (s
->psz_url
!= NULL
)
291 { /* Backward compatibility hack: Lua scripts expect the URI scheme and
292 * the rest of the URI separately. */
293 const char *p
= strstr(s
->psz_url
, "://");
296 sys
->access
= strndup(s
->psz_url
, p
- s
->psz_url
);
301 int ret
= vlclua_scripts_batch_execute(VLC_OBJECT(s
), "playlist",
302 probe_luascript
, NULL
);
303 if (ret
!= VLC_SUCCESS
)
310 s
->pf_readdir
= ReadDir
;
311 s
->pf_control
= access_vaDirectoryControlHelper
;
315 void Close_LuaPlaylist(vlc_object_t
*obj
)
317 stream_t
*s
= (stream_t
*)obj
;
318 struct vlclua_playlist
*sys
= s
->p_sys
;
321 assert(sys
->L
!= NULL
);