1 /*****************************************************************************
2 * demux.c : Lua playlist demux module
3 *****************************************************************************
4 * Copyright (C) 2007-2008 the VideoLAN team
7 * Authors: Antoine Cellerier <dionoea at videolan tod org>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
35 #include <vlc_common.h>
36 #include <vlc_access.h>
41 /*****************************************************************************
42 * Demux specific functions
43 *****************************************************************************/
44 struct vlclua_playlist
52 static int vlclua_demux_peek( lua_State
*L
)
54 stream_t
*s
= (stream_t
*)vlclua_get_this(L
);
55 int n
= luaL_checkint( L
, 1 );
56 const uint8_t *p_peek
;
58 ssize_t val
= vlc_stream_Peek(s
->p_source
, &p_peek
, n
);
60 lua_pushlstring(L
, (const char *)p_peek
, val
);
66 static int vlclua_demux_read( lua_State
*L
)
68 stream_t
*s
= (stream_t
*)vlclua_get_this(L
);
69 int n
= luaL_checkint( L
, 1 );
70 char *buf
= malloc(n
);
74 ssize_t val
= vlc_stream_Read(s
->p_source
, buf
, n
);
76 lua_pushlstring(L
, buf
, val
);
87 static int vlclua_demux_readline( lua_State
*L
)
89 stream_t
*s
= (stream_t
*)vlclua_get_this(L
);
90 char *line
= vlc_stream_ReadLine(s
->p_source
);
94 lua_pushstring(L
, line
);
103 /*****************************************************************************
105 *****************************************************************************/
106 /* Functions to register */
107 static const luaL_Reg p_reg
[] =
109 { "peek", vlclua_demux_peek
},
113 /* Functions to register for parse() function call only */
114 static const luaL_Reg p_reg_parse
[] =
116 { "read", vlclua_demux_read
},
117 { "readline", vlclua_demux_readline
},
121 /*****************************************************************************
122 * Called through lua_scripts_batch_execute to call 'probe' on
123 * the script pointed by psz_filename.
124 *****************************************************************************/
125 static int probe_luascript(vlc_object_t
*obj
, const char *filename
,
126 const luabatch_context_t
*ctx
)
128 stream_t
*s
= (stream_t
*)obj
;
129 struct vlclua_playlist
*sys
= s
->p_sys
;
131 /* Initialise Lua state structure */
132 lua_State
*L
= luaL_newstate();
138 /* Load Lua libraries */
139 luaL_openlibs( L
); /* FIXME: Don't open all the libs? */
141 vlclua_set_this(L
, s
);
142 luaL_register_namespace( L
, "vlc", p_reg
);
144 luaopen_strings( L
);
146 luaopen_variables( L
);
149 if (sys
->path
!= NULL
)
150 lua_pushstring(L
, sys
->path
);
153 lua_setfield( L
, -2, "path" );
155 if (sys
->access
!= NULL
)
156 lua_pushstring(L
, sys
->access
);
159 lua_setfield( L
, -2, "access" );
163 /* Setup the module search path */
164 if (vlclua_add_modules_path(L
, filename
))
166 msg_Warn(s
, "error setting the module search path for %s", filename
);
170 /* Load and run the script(s) */
171 if (vlclua_dofile(VLC_OBJECT(s
), L
, filename
))
173 msg_Warn(s
, "error loading script %s: %s", filename
,
174 lua_tostring(L
, lua_gettop(L
)));
178 lua_getglobal( L
, "probe" );
179 if( !lua_isfunction( L
, -1 ) )
181 msg_Warn(s
, "error running script %s: function %s(): %s",
182 filename
, "probe", "not found");
186 if( lua_pcall( L
, 0, 1, 0 ) )
188 msg_Warn(s
, "error running script %s: function %s(): %s",
189 filename
, "probe", lua_tostring(L
, lua_gettop(L
)));
193 if( lua_gettop( L
) )
195 if( lua_toboolean( L
, 1 ) )
197 msg_Dbg(s
, "Lua playlist script %s's "
198 "probe() function was successful", filename
);
200 sys
->filename
= strdup(filename
);
212 static int ReadDir(stream_t
*s
, input_item_node_t
*node
)
214 struct vlclua_playlist
*sys
= s
->p_sys
;
215 lua_State
*L
= sys
->L
;
217 luaL_register_namespace( L
, "vlc", p_reg_parse
);
219 lua_getglobal( L
, "parse" );
221 if( !lua_isfunction( L
, -1 ) )
223 msg_Warn(s
, "error running script %s: function %s(): %s",
224 sys
->filename
, "parse", "not found");
228 if( lua_pcall( L
, 0, 1, 0 ) )
230 msg_Warn(s
, "error running script %s: function %s(): %s",
231 sys
->filename
, "parse", lua_tostring(L
, lua_gettop(L
)));
237 msg_Err(s
, "script went completely foobar");
241 if (!lua_istable(L
, -1))
243 msg_Warn(s
, "Playlist should be a table.");
250 while (lua_next(L
, -2))
252 input_item_t
*item
= vlclua_read_input_item(VLC_OBJECT(s
), L
);
255 /* copy the original URL to the meta data,
256 * if "URL" is still empty */
257 char *url
= input_item_GetURL(item
);
258 if (url
== NULL
&& s
->psz_url
!= NULL
)
259 input_item_SetURL(item
, s
->psz_url
);
262 input_item_node_AppendItem(node
, item
);
263 input_item_Release(item
);
265 /* pop the value, keep the key for the next lua_next() call */
273 /*****************************************************************************
274 * Import_LuaPlaylist: main import function
275 *****************************************************************************/
276 int Import_LuaPlaylist(vlc_object_t
*obj
)
278 stream_t
*s
= (stream_t
*)obj
;
280 if( !vlc_stream_Control( s
->p_source
, STREAM_IS_DIRECTORY
) )
283 struct vlclua_playlist
*sys
= malloc(sizeof (*sys
));
284 if (unlikely(sys
== NULL
))
291 if (s
->psz_url
!= NULL
)
292 { /* Backward compatibility hack: Lua scripts expect the URI scheme and
293 * the rest of the URI separately. */
294 const char *p
= strstr(s
->psz_url
, "://");
297 sys
->access
= strndup(s
->psz_url
, p
- s
->psz_url
);
302 int ret
= vlclua_scripts_batch_execute(VLC_OBJECT(s
), "playlist",
303 probe_luascript
, NULL
);
304 if (ret
!= VLC_SUCCESS
)
311 s
->pf_readdir
= ReadDir
;
312 s
->pf_control
= access_vaDirectoryControlHelper
;
316 void Close_LuaPlaylist(vlc_object_t
*obj
)
318 stream_t
*s
= (stream_t
*)obj
;
319 struct vlclua_playlist
*sys
= s
->p_sys
;
322 assert(sys
->L
!= NULL
);