[vlc-devel] [vlc-commits] lua: libs: Provide a basic io module replacement
Hugo Beauzée-Luyssen
hugo at beauzee.fr
Mon Apr 9 18:24:59 CEST 2018
On Mon, Apr 9, 2018, at 5:02 PM, Hugo Beauzée-Luyssen wrote:
> vlc | branch: master | Hugo Beauzée-Luyssen <hugo at beauzee.fr> | Fri Apr
> 6 17:11:19 2018 +0200| [e6d9d25ef9f144ac661453324e1e143048f9e035] |
> committer: Hugo Beauzée-Luyssen
>
> lua: libs: Provide a basic io module replacement
>
> > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=e6d9d25ef9f144ac661453324e1e143048f9e035
> ---
>
> modules/lua/libs/io.c | 158 ++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 158 insertions(+)
>
> diff --git a/modules/lua/libs/io.c b/modules/lua/libs/io.c
> index f3bbefe4c0..67b92f36b5 100644
> --- a/modules/lua/libs/io.c
> +++ b/modules/lua/libs/io.c
> @@ -24,6 +24,7 @@
> # include "config.h"
> #endif
>
> +#include <stdio.h>
> #include <errno.h>
>
> #include <vlc_common.h>
> @@ -32,6 +33,162 @@
> #include "../vlc.h"
> #include "../libs.h"
>
> +static int vlclua_io_file_read_line( lua_State *L, FILE* p_file )
> +{
> + char* psz_line = NULL;
> + size_t i_buffer;
> + ssize_t i_len = getline( &psz_line, &i_buffer, p_file );
> + if ( i_len == -1 )
> + return 0;
> + if( psz_line[i_len - 1] == '\n' )
> + psz_line[--i_len] = 0;
> + lua_pushstring( L, psz_line );
> + free( psz_line );
> + return 1;
> +}
> +
> +static int vlclua_io_file_read_number( lua_State *L, FILE* p_file )
> +{
> + lua_Number num;
> + if ( fscanf( p_file, LUA_NUMBER_SCAN, &num ) != 1 )
> + return 0;
> + lua_pushnumber( L, num );
> + return 1;
> +}
> +
> +static int vlclua_io_file_read_chars( lua_State *L, size_t i_len, FILE*
> p_file )
> +{
> + size_t i_toread = LUAL_BUFFERSIZE;
> + size_t i_read;
> + luaL_Buffer b;
> + luaL_buffinit( L, &b );
> + do {
> + char *p = luaL_prepbuffer(&b);
> + if (i_toread > i_len)
> + i_toread = i_len;
> + i_read = fread(p, sizeof(char), i_toread, p_file);
> + luaL_addsize(&b, i_read);
> + i_len -= i_read;
> + } while (i_len > 0 && i_read == i_toread);
> + luaL_pushresult(&b);
> + return (i_len == 0 || lua_objlen(L, -1) > 0);
> +}
> +
> +static int vlclua_io_file_read( lua_State *L )
> +{
> + FILE **pp_file = (FILE**)luaL_checkudata( L, 1, "io_file" );
> + if( lua_type( L, 2 ) == LUA_TNUMBER )
> + {
> + return vlclua_io_file_read_chars( L, (size_t)lua_tointeger( L,
> 2 ),
> + *pp_file );
> + }
> + const char* psz_mode = luaL_optstring( L, 2, "*l" );
> + if ( *psz_mode != '*' )
> + return luaL_error( L, "Invalid file:read() format: %s",
> psz_mode );
> + switch ( psz_mode[1] )
> + {
> + case 'l':
> + return vlclua_io_file_read_line( L, *pp_file );
> + case 'n':
> + return vlclua_io_file_read_number( L, *pp_file );
> + case 'a':
> + return vlclua_io_file_read_chars( L, SIZE_MAX, *pp_file );
> + default:
> + break;
> + }
> + return luaL_error( L, "Invalid file:read() format: %s", psz_mode );
> +}
> +
> +static int vlclua_io_file_write( lua_State *L )
> +{
> + FILE **pp_file = (FILE**)luaL_checkudata( L, 1, "io_file" );
> + int i_nb_args = lua_gettop( L );
> + bool b_success = true;
> + for ( int i = 2; i <= i_nb_args; ++i )
> + {
> + bool i_res;
> + if ( lua_type( L, i ) == LUA_TNUMBER )
> + i_res = fprintf(*pp_file, LUA_NUMBER_FMT, lua_tonumber( L,
> i ) ) > 0;
> + else
> + {
> + size_t i_len;
> + const char* psz_value = luaL_checklstring( L, i, &i_len );
> + i_res = fwrite(psz_value, sizeof(*psz_value), i_len,
> *pp_file ) > 0;
> + }
> + b_success = b_success && i_res;
> + }
> + lua_pushboolean( L, b_success );
> + return 1;
> +}
> +
> +static int vlclua_io_file_seek( lua_State *L )
> +{
> + FILE **pp_file = (FILE**)luaL_checkudata( L, 1, "io_file" );
> + const char* psz_mode = luaL_optstring( L, 2, NULL );
> + if ( psz_mode != NULL )
> + {
> + long i_offset = luaL_optlong( L, 3, 0 );
> + int i_mode;
> + if ( !strcmp( psz_mode, "set" ) )
> + i_mode = SEEK_SET;
> + else if ( !strcmp( psz_mode, "end" ) )
> + i_mode = SEEK_END;
> + else
> + i_mode = SEEK_CUR;
> + if( fseek( *pp_file, i_offset, i_mode ) != 0 )
> + return luaL_error( L, "Failed to seek" );
> + }
> + lua_pushinteger( L, ftell( *pp_file ) );
> + return 1;
> +}
> +
> +static int vlclua_io_file_flush( lua_State *L )
> +{
> + FILE **pp_file = (FILE**)luaL_checkudata( L, 1, "io_file" );
> + fflush( *pp_file );
> + return 0;
> +}
> +
> +static int vlclua_io_file_close( lua_State *L )
> +{
> + FILE **pp_file = (FILE**)luaL_checkudata( L, 1, "io_file" );
> + fclose( *pp_file );
> + return 0;
> +}
> +
> +static const luaL_Reg vlclua_io_file_reg[] = {
> + { "read", vlclua_io_file_read },
> + { "write", vlclua_io_file_write },
> + { "seek", vlclua_io_file_seek },
> + { "flush", vlclua_io_file_flush },
> + { NULL, NULL }
> +};
> +
> +static int vlclua_io_open( lua_State *L )
> +{
> + if( lua_gettop( L ) < 1 )
> + return luaL_error( L, "Usage: vlc.io.open(file_path [,
> mode])" );
> + const char* psz_path = luaL_checkstring( L, 1 );
> + const char* psz_mode = luaL_optstring( L, 2, "r" );
> + FILE *p_f = vlc_fopen( psz_path, psz_mode );
> + if ( p_f == NULL )
> + return 0;
> +
> + FILE** pp_f = lua_newuserdata( L, sizeof( p_f ) );
> + *pp_f = p_f;
> +
> + if( luaL_newmetatable( L, "io_file" ) )
> + {
> + lua_newtable( L );
> + luaL_register( L, NULL, vlclua_io_file_reg );
> + lua_setfield( L, -2, "__index" );
> + lua_pushcfunction( L, vlclua_io_file_close );
> + lua_setfield( L, -2, "__gc" );
> + }
> + lua_setmetatable( L, -2 );
> + return 1;
> +}
> +
> static int vlclua_mkdir( lua_State *L )
> {
> if( lua_gettop( L ) < 2 ) return vlclua_error( L );
> @@ -47,6 +204,7 @@ static int vlclua_mkdir( lua_State *L )
>
> static const luaL_Reg vlclua_io_reg[] = {
> { "mkdir", vlclua_mkdir },
> + { "open", vlclua_io_open },
>
> { NULL, NULL }
> };
>
> _______________________________________________
> vlc-commits mailing list
> vlc-commits at videolan.org
> https://mailman.videolan.org/listinfo/vlc-commits
Hi,
This commit (along with the related serie) fixes quite a few issues for VLSub. Mainly, it wouldn't have worked properly if you'd have any non-ascii character in your name.
We have a lot of reports related to that, and I'd like to backport this to the 3.0 branch.
I agree that it adds a few function to a public API and that it's usually not a good idea to do so in a stable branch, but I'm not entirely sure how to fix this properly otherwise.
Opinions are welcome!
Regards,
--
Hugo Beauzée-Luyssen
hugo at beauzee.fr
More information about the vlc-devel
mailing list