/*****************************************************************************
* net.c: Network related functions
*****************************************************************************
- * Copyright (C) 2007 the VideoLAN team
+ * Copyright (C) 2007-2008 the VideoLAN team
* $Id$
*
* Authors: Antoine Cellerier <dionoea at videolan tod org>
#include <lua.h> /* Low level lua C API */
#include <lauxlib.h> /* Higher level C API */
-#include <lualib.h> /* Lua libs */
-#include "vlc.h"
+#include "../vlc.h"
+#include "../libs.h"
/*****************************************************************************
*
*****************************************************************************/
-int vlclua_url_parse( lua_State *L )
+static int vlclua_url_parse( lua_State *L )
{
const char *psz_url = luaL_checkstring( L, 1 );
const char *psz_option = luaL_optstring( L, 2, NULL );
return 1;
}
-int vlclua_net_listen_tcp( lua_State *L )
+/*****************************************************************************
+ * Net listen
+ *****************************************************************************/
+static int vlclua_net_listen_close( lua_State * );
+static int vlclua_net_accept( lua_State * );
+
+static const luaL_Reg vlclua_net_listen_reg[] = {
+ { "accept", vlclua_net_accept },
+ { NULL, NULL }
+};
+
+static int vlclua_net_listen_tcp( lua_State *L )
{
vlc_object_t *p_this = vlclua_get_this( L );
const char *psz_host = luaL_checkstring( L, 1 );
int *pi_fd = net_ListenTCP( p_this, psz_host, i_port );
if( pi_fd == NULL )
return luaL_error( L, "Cannot listen on %s:%d", psz_host, i_port );
- lua_pushlightuserdata( L, pi_fd );
+
+ int **ppi_fd = lua_newuserdata( L, sizeof( int * ) );
+ *ppi_fd = pi_fd;
+
+ if( luaL_newmetatable( L, "net_listen" ) )
+ {
+ lua_newtable( L );
+ luaL_register( L, NULL, vlclua_net_listen_reg );
+ lua_setfield( L, -2, "__index" );
+ lua_pushcfunction( L, vlclua_net_listen_close );
+ lua_setfield( L, -2, "__gc" );
+ }
+
+ lua_setmetatable( L, -2 );
return 1;
}
-int vlclua_net_listen_close( lua_State *L )
+static int vlclua_net_listen_close( lua_State *L )
{
- int *pi_fd = (int*)luaL_checklightuserdata( L, 1 );
- net_ListenClose( pi_fd );
+ int **ppi_fd = (int**)luaL_checkudata( L, 1, "net_listen" );
+ net_ListenClose( *ppi_fd );
return 0;
}
-int vlclua_net_accept( lua_State *L )
+static int vlclua_net_accept( lua_State *L )
{
vlc_object_t *p_this = vlclua_get_this( L );
- int *pi_fd = (int*)luaL_checklightuserdata( L, 1 );
+ int **ppi_fd = (int**)luaL_checkudata( L, 1, "net_listen" );
mtime_t i_wait = luaL_optint( L, 2, -1 ); /* default to block */
- int i_fd = net_Accept( p_this, pi_fd, i_wait );
+ int i_fd = net_Accept( p_this, *ppi_fd, i_wait );
lua_pushinteger( L, i_fd );
return 1;
}
-int vlclua_net_close( lua_State *L )
+/*****************************************************************************
+ *
+ *****************************************************************************/
+static int vlclua_net_close( lua_State *L )
{
int i_fd = luaL_checkint( L, 1 );
net_Close( i_fd );
return 0;
}
-int vlclua_net_send( lua_State *L )
+static int vlclua_net_send( lua_State *L )
{
int i_fd = luaL_checkint( L, 1 );
size_t i_len;
return 1;
}
-int vlclua_net_recv( lua_State *L )
+static int vlclua_net_recv( lua_State *L )
{
int i_fd = luaL_checkint( L, 1 );
size_t i_len = luaL_optint( L, 2, 1 );
return 1;
}
-int vlclua_net_select( lua_State *L )
+/*****************************************************************************
+ *
+ *****************************************************************************/
+static int vlclua_net_select( lua_State *L )
{
int i_ret;
size_t i_nfds = luaL_checkint( L, 1 );
- fd_set *fds_read = (fd_set*)luaL_checkuserdata( L, 2, sizeof( fd_set ) );
- fd_set *fds_write = (fd_set*)luaL_checkuserdata( L, 3, sizeof( fd_set ) );
+ fd_set *fds_read = (fd_set*)luaL_checkudata( L, 2, "fd_set" );
+ fd_set *fds_write = (fd_set*)luaL_checkudata( L, 3, "fd_set" );
double f_timeout = luaL_checknumber( L, 4 );
struct timeval timeout;
return 2;
}
-int vlclua_fd_set_new( lua_State *L )
+/*****************************************************************************
+ *
+ *****************************************************************************/
+static int vlclua_fd_clr( lua_State * );
+static int vlclua_fd_isset( lua_State * );
+static int vlclua_fd_set( lua_State * );
+static int vlclua_fd_zero( lua_State * );
+
+static const luaL_Reg vlclua_fd_set_reg[] = {
+ { "clr", vlclua_fd_clr },
+ { "isset", vlclua_fd_isset },
+ { "set", vlclua_fd_set },
+ { "zero", vlclua_fd_zero },
+ { NULL, NULL }
+};
+
+static int vlclua_fd_set_new( lua_State *L )
{
fd_set *fds = (fd_set*)lua_newuserdata( L, sizeof( fd_set ) );
FD_ZERO( fds );
+
+ if( luaL_newmetatable( L, "fd_set" ) )
+ {
+ lua_newtable( L );
+ luaL_register( L, NULL, vlclua_fd_set_reg );
+ lua_setfield( L, -2, "__index" );
+ }
+
+ lua_setmetatable( L, -2 );
return 1;
}
-int vlclua_fd_clr( lua_State *L )
+static int vlclua_fd_clr( lua_State *L )
{
- fd_set *fds = (fd_set*)luaL_checkuserdata( L, 1, sizeof( fd_set ) );
+ fd_set *fds = (fd_set*)luaL_checkudata( L, 1, "fd_set" );
int i_fd = luaL_checkint( L, 2 );
FD_CLR( i_fd, fds );
return 0;
}
-int vlclua_fd_isset( lua_State *L )
+
+static int vlclua_fd_isset( lua_State *L )
{
- fd_set *fds = (fd_set*)luaL_checkuserdata( L, 1, sizeof( fd_set ) );
+ fd_set *fds = (fd_set*)luaL_checkudata( L, 1, "fd_set" );
int i_fd = luaL_checkint( L, 2 );
lua_pushboolean( L, FD_ISSET( i_fd, fds ) );
return 1;
}
-int vlclua_fd_set( lua_State *L )
+
+static int vlclua_fd_set( lua_State *L )
{
- fd_set *fds = (fd_set*)luaL_checkuserdata( L, 1, sizeof( fd_set ) );
+ fd_set *fds = (fd_set*)luaL_checkudata( L, 1, "fd_set" );
size_t i_fd = luaL_checkint( L, 2 );
/* FIXME: we should really use poll() instead here, but that breaks the
* VLC/LUA API. On Windows, overflow protection is built-in FD_SET, not
FD_SET( i_fd, fds );
return 0;
}
-int vlclua_fd_zero( lua_State *L )
+
+static int vlclua_fd_zero( lua_State *L )
{
- fd_set *fds = (fd_set*)luaL_checkuserdata( L, 1, sizeof( fd_set ) );
+ fd_set *fds = (fd_set*)luaL_checkudata( L, 1, "fd_set" );
FD_ZERO( fds );
return 0;
}
+/*****************************************************************************
+ *
+ *****************************************************************************/
/*
-int vlclua_fd_open( lua_State *L )
+static int vlclua_fd_open( lua_State *L )
{
}
*/
-int vlclua_fd_write( lua_State *L )
+static int vlclua_fd_write( lua_State *L )
{
int i_fd = luaL_checkint( L, 1 );
size_t i_len;
return 1;
}
-int vlclua_fd_read( lua_State *L )
+static int vlclua_fd_read( lua_State *L )
{
int i_fd = luaL_checkint( L, 1 );
size_t i_len = luaL_optint( L, 2, 1 );
return 1;
}
-int vlclua_stat( lua_State *L )
+/*****************************************************************************
+ *
+ *****************************************************************************/
+static int vlclua_stat( lua_State *L )
{
#ifdef HAVE_SYS_STAT_H
const char *psz_path = luaL_checkstring( L, 1 );
#endif
}
-int vlclua_opendir( lua_State *L )
+static int vlclua_opendir( lua_State *L )
{
const char *psz_dir = luaL_checkstring( L, 1 );
DIR *p_dir;
closedir( p_dir );
return 1;
}
+
+/*****************************************************************************
+ *
+ *****************************************************************************/
+static const luaL_Reg vlclua_net_reg[] = {
+ { "url_parse", vlclua_url_parse },
+ { "listen_tcp", vlclua_net_listen_tcp },
+ { "close", vlclua_net_close },
+ { "send", vlclua_net_send },
+ { "recv", vlclua_net_recv },
+ { "select", vlclua_net_select },
+ { "fd_set_new", vlclua_fd_set_new },
+ { "fd_read", vlclua_fd_read },
+ { "fd_write", vlclua_fd_write },
+ { "stat", vlclua_stat }, /* Not really "net" */
+ { "opendir", vlclua_opendir }, /* Not really "net" */
+ { NULL, NULL }
+};
+
+void luaopen_net( lua_State *L )
+{
+ lua_newtable( L );
+ luaL_register( L, NULL, vlclua_net_reg );
+ lua_setfield( L, -2, "net" );
+}