demux: avi: check chunk size
[vlc.git] / modules / lua / demux.c
blob70c5fe56bec02e9667dbf227f69ef13e262d3495
1 /*****************************************************************************
2 * demux.c : Lua playlist demux module
3 *****************************************************************************
4 * Copyright (C) 2007-2008 the VideoLAN team
5 * $Id$
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 /*****************************************************************************
25 * Preamble
26 *****************************************************************************/
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
31 #include <assert.h>
32 #include <stdlib.h>
33 #include <string.h>
35 #include <vlc_common.h>
36 #include <vlc_access.h>
38 #include "vlc.h"
39 #include "libs.h"
41 /*****************************************************************************
42 * Demux specific functions
43 *****************************************************************************/
44 struct vlclua_playlist
46 lua_State *L;
47 char *filename;
48 char *access;
49 const char *path;
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);
59 if (val > 0)
60 lua_pushlstring(L, (const char *)p_peek, val);
61 else
62 lua_pushnil( L );
63 return 1;
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);
72 if (buf != NULL)
74 ssize_t val = vlc_stream_Read(s->p_source, buf, n);
75 if (val > 0)
76 lua_pushlstring(L, buf, val);
77 else
78 lua_pushnil( L );
79 free(buf);
81 else
82 lua_pushnil( L );
84 return 1;
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);
92 if (line != NULL)
94 lua_pushstring(L, line);
95 free(line);
97 else
98 lua_pushnil( L );
100 return 1;
103 /*****************************************************************************
105 *****************************************************************************/
106 /* Functions to register */
107 static const luaL_Reg p_reg[] =
109 { "peek", vlclua_demux_peek },
110 { NULL, NULL }
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 },
118 { NULL, NULL }
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();
133 if( !L )
134 return VLC_ENOMEM;
136 sys->L = L;
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 );
143 luaopen_msg( L );
144 luaopen_strings( L );
145 luaopen_stream( L );
146 luaopen_variables( L );
147 luaopen_xml( L );
149 if (sys->path != NULL)
150 lua_pushstring(L, sys->path);
151 else
152 lua_pushnil(L);
153 lua_setfield( L, -2, "path" );
155 if (sys->access != NULL)
156 lua_pushstring(L, sys->access);
157 else
158 lua_pushnil(L);
159 lua_setfield( L, -2, "access" );
161 lua_pop( L, 1 );
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);
167 goto error;
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)));
175 goto error;
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");
183 goto error;
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)));
190 goto error;
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 );
199 lua_pop( L, 1 );
200 sys->filename = strdup(filename);
201 return VLC_SUCCESS;
205 (void) ctx;
206 error:
207 lua_pop( L, 1 );
208 lua_close(sys->L);
209 return VLC_EGENERIC;
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");
225 return VLC_ENOITEM;
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)));
232 return VLC_ENOITEM;
235 if (!lua_gettop(L))
237 msg_Err(s, "script went completely foobar");
238 return VLC_ENOITEM;
241 if (!lua_istable(L, -1))
243 msg_Warn(s, "Playlist should be a table.");
244 return VLC_ENOITEM;
247 lua_pushnil(L);
249 /* playlist nil */
250 while (lua_next(L, -2))
252 input_item_t *item = vlclua_read_input_item(VLC_OBJECT(s), L);
253 if (item != NULL)
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);
260 free(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 */
266 lua_pop(L, 1);
268 /* playlist */
270 return VLC_SUCCESS;
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 ) )
281 return VLC_EGENERIC;
283 struct vlclua_playlist *sys = malloc(sizeof (*sys));
284 if (unlikely(sys == NULL))
285 return VLC_ENOMEM;
287 s->p_sys = sys;
288 sys->access = NULL;
289 sys->path = 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, "://");
295 if (p != NULL)
297 sys->access = strndup(s->psz_url, p - s->psz_url);
298 sys->path = p + 3;
302 int ret = vlclua_scripts_batch_execute(VLC_OBJECT(s), "playlist",
303 probe_luascript, NULL);
304 if (ret != VLC_SUCCESS)
306 free(sys->access);
307 free(sys);
308 return ret;
311 s->pf_readdir = ReadDir;
312 s->pf_control = access_vaDirectoryControlHelper;
313 return VLC_SUCCESS;
316 void Close_LuaPlaylist(vlc_object_t *obj)
318 stream_t *s = (stream_t *)obj;
319 struct vlclua_playlist *sys = s->p_sys;
321 free(sys->filename);
322 assert(sys->L != NULL);
323 lua_close(sys->L);
324 free(sys->access);
325 free(sys);