naev 0.12.6
nlua_file.c
Go to the documentation of this file.
1/*
2 * See Licensing and Copyright notice in naev.h
3 */
10#include <lauxlib.h>
12
13#include "physfsrwops.h"
14
15#include "nlua_file.h"
16
17#include "nluadef.h"
18#include "physfs.h"
19
20/* File metatable methods. */
21static int fileL_gc( lua_State *L );
22static int fileL_eq( lua_State *L );
23static int fileL_new( lua_State *L );
24static int fileL_open( lua_State *L );
25static int fileL_close( lua_State *L );
26static int fileL_read( lua_State *L );
27static int fileL_write( lua_State *L );
28static int fileL_seek( lua_State *L );
29static int fileL_name( lua_State *L );
30static int fileL_mode( lua_State *L );
31static int fileL_size( lua_State *L );
32static int fileL_isopen( lua_State *L );
33static int fileL_filetype( lua_State *L );
34static int fileL_mkdir( lua_State *L );
35static int fileL_enumerate( lua_State *L );
36static int fileL_remove( lua_State *L );
37
38static const luaL_Reg fileL_methods[] = {
39 { "__gc", fileL_gc },
40 { "__eq", fileL_eq },
41 { "new", fileL_new },
42 { "open", fileL_open },
43 { "close", fileL_close },
44 { "read", fileL_read },
45 { "write", fileL_write },
46 { "seek", fileL_seek },
47 { "getFilename", fileL_name },
48 { "getMode", fileL_mode },
49 { "getSize", fileL_size },
50 { "isOpen", fileL_isopen },
51 { "filetype", fileL_filetype },
52 { "mkdir", fileL_mkdir },
53 { "enumerate", fileL_enumerate },
54 { "remove", fileL_remove },
55 { 0, 0 } };
56
63int nlua_loadFile( nlua_env env )
64{
65 nlua_register( env, FILE_METATABLE, fileL_methods, 1 );
66 return 0;
67}
68
83LuaFile_t *lua_tofile( lua_State *L, int ind )
84{
85 return (LuaFile_t *)lua_touserdata( L, ind );
86}
87
94LuaFile_t *luaL_checkfile( lua_State *L, int ind )
95{
96 if ( lua_isfile( L, ind ) )
97 return lua_tofile( L, ind );
98 luaL_typerror( L, ind, FILE_METATABLE );
99 return NULL;
100}
101
108LuaFile_t *lua_pushfile( lua_State *L, LuaFile_t file )
109{
110 LuaFile_t *c = (LuaFile_t *)lua_newuserdata( L, sizeof( LuaFile_t ) );
111 *c = file;
112 luaL_getmetatable( L, FILE_METATABLE );
113 lua_setmetatable( L, -2 );
114 return c;
115}
116
123int lua_isfile( lua_State *L, int ind )
124{
125 int ret;
126
127 if ( lua_getmetatable( L, ind ) == 0 )
128 return 0;
129 lua_getfield( L, LUA_REGISTRYINDEX, FILE_METATABLE );
130
131 ret = 0;
132 if ( lua_rawequal( L, -1, -2 ) ) /* does it have the correct mt? */
133 ret = 1;
134
135 lua_pop( L, 2 ); /* remove both metatables */
136 return ret;
137}
138
145static int fileL_gc( lua_State *L )
146{
147 LuaFile_t *lf = luaL_checkfile( L, 1 );
148 if ( lf->rw != NULL ) {
149 SDL_RWclose( lf->rw );
150 lf->rw = NULL;
151 }
152 return 0;
153}
154
163static int fileL_eq( lua_State *L )
164{
165 LuaFile_t *f1, *f2;
166 f1 = luaL_checkfile( L, 1 );
167 f2 = luaL_checkfile( L, 2 );
168 lua_pushboolean( L, ( memcmp( f1, f2, sizeof( LuaFile_t ) ) == 0 ) );
169 return 1;
170}
171
179static int fileL_new( lua_State *L )
180{
181 LuaFile_t lf;
182 const char *str = luaL_checkstring( L, 1 );
183 memset( &lf, 0, sizeof( lf ) );
184 strncpy( lf.path, str, sizeof( lf.path ) - 1 );
185 lf.mode = 'c';
186 lf.rw = NULL;
187 lua_pushfile( L, lf );
188 return 1;
189}
190
200static int fileL_open( lua_State *L )
201{
202 LuaFile_t *lf = luaL_checkfile( L, 1 );
203 const char *mode = luaL_optstring( L, 2, "r" );
204
205 /* TODO handle mode. */
206 if ( strcmp( mode, "w" ) == 0 )
207 lf->rw = PHYSFSRWOPS_openWrite( lf->path );
208 else if ( strcmp( mode, "a" ) == 0 )
209 lf->rw = PHYSFSRWOPS_openAppend( lf->path );
210 else
211 lf->rw = PHYSFSRWOPS_openRead( lf->path );
212 if ( lf->rw == NULL ) {
213 lua_pushboolean( L, 0 );
214 lua_pushstring( L, SDL_GetError() );
215 return 2;
216 }
217 lf->mode = mode[0];
218 lf->size = (size_t)SDL_RWsize( lf->rw );
219
220 lua_pushboolean( L, 1 );
221 return 1;
222}
223
231static int fileL_close( lua_State *L )
232{
233 LuaFile_t *lf = luaL_checkfile( L, 1 );
234 if ( lf->rw != NULL ) {
235 SDL_RWclose( lf->rw );
236 lf->rw = NULL;
237 }
238 lf->mode = 'c';
239 lua_pushboolean( L, 1 );
240 return 1;
241}
242
252static int fileL_read( lua_State *L )
253{
254 LuaFile_t *lf = luaL_checkfile( L, 1 );
255 size_t readlen, len;
256 char *buf;
257
258 if ( lf->rw == NULL )
259 return NLUA_ERROR( L, _( "file not open!" ) );
260
261 /* Figure out how much to read. */
262 readlen = luaL_optinteger( L, 2, SDL_RWsize( lf->rw ) );
263
264 /* Create buffer and read into it. */
265 buf = malloc( readlen );
266 len = SDL_RWread( lf->rw, buf, 1, readlen );
267
268 lua_pushlstring( L, buf, len );
269 lua_pushinteger( L, len );
270 free( buf );
271 return 2;
272}
273
282static int fileL_write( lua_State *L )
283{
284 LuaFile_t *lf = luaL_checkfile( L, 1 );
285 size_t write, wrote, len;
286 const char *buf;
287
288 if ( lf->rw == NULL )
289 return NLUA_ERROR( L, _( "file not open!" ) );
290
291 buf = luaL_checklstring( L, 2, &len );
292 write = luaL_optlong( L, 3, len );
293
294 wrote = SDL_RWwrite( lf->rw, buf, 1, write );
295 if ( wrote != write ) {
296 lua_pushboolean( L, 0 );
297 lua_pushstring( L, SDL_GetError() );
298 return 2;
299 }
300
301 lua_pushboolean( L, 1 );
302 return 1;
303}
304
313static int fileL_seek( lua_State *L )
314{
315 LuaFile_t *lf = luaL_checkfile( L, 1 );
316 size_t pos = luaL_checkinteger( L, 2 );
317 Sint64 ret;
318
319 if ( lf->rw == NULL ) {
320 lua_pushboolean( L, 1 );
321 return 1;
322 }
323
324 ret = SDL_RWseek( lf->rw, pos, RW_SEEK_SET );
325
326 lua_pushboolean( L, ret >= 0 );
327 return 1;
328}
329
337static int fileL_name( lua_State *L )
338{
339 LuaFile_t *lf = luaL_checkfile( L, 1 );
340 lua_pushstring( L, lf->path );
341 return 1;
342}
343
351static int fileL_mode( lua_State *L )
352{
353 LuaFile_t *lf = luaL_checkfile( L, 1 );
354 lua_pushlstring( L, &lf->mode, 1 );
355 return 1;
356}
357
365static int fileL_size( lua_State *L )
366{
367 LuaFile_t *lf = luaL_checkfile( L, 1 );
368 lua_pushinteger( L, lf->size );
369 return 1;
370}
371
379static int fileL_isopen( lua_State *L )
380{
381 const LuaFile_t *lf = luaL_checkfile( L, 1 );
382 lua_pushboolean( L, lf->rw != NULL );
383 return 1;
384}
385
393static int fileL_filetype( lua_State *L )
394{
395 const char *path = luaL_checkstring( L, 1 );
396 PHYSFS_Stat path_stat;
397
398 if ( !PHYSFS_stat( path, &path_stat ) ) {
399 /* No need for warning, might not exist. */
400 lua_pushnil( L );
401 return 1;
402 }
403 if ( path_stat.filetype == PHYSFS_FILETYPE_REGULAR )
404 lua_pushstring( L, "file" );
405 else if ( path_stat.filetype == PHYSFS_FILETYPE_DIRECTORY )
406 lua_pushstring( L, "directory" );
407 else
408 lua_pushnil( L );
409 return 1;
410}
411
419static int fileL_mkdir( lua_State *L )
420{
421 const char *path = luaL_checkstring( L, 1 );
422 int ret = PHYSFS_mkdir( path );
423 lua_pushboolean( L, ret );
424 if ( ret == 0 ) {
425 lua_pushstring( L, PHYSFS_getErrorByCode( PHYSFS_getLastErrorCode() ) );
426 return 2;
427 }
428 return 1;
429}
430
439static int fileL_enumerate( lua_State *L )
440{
441 char **items;
442 const char *path = luaL_checkstring( L, 1 );
443
444 lua_newtable( L );
445 items = PHYSFS_enumerateFiles( path );
446 if ( items == NULL )
447 return NLUA_ERROR(
448 L, _( "Directory '%s' enumerate error: %s" ), path,
449 _( PHYSFS_getErrorByCode( PHYSFS_getLastErrorCode() ) ) );
450 for ( int i = 0; items[i] != NULL; i++ ) {
451 lua_pushstring( L, items[i] );
452 lua_rawseti( L, -2, i + 1 );
453 }
454 PHYSFS_freeList( items );
455 return 1;
456}
457
465static int fileL_remove( lua_State *L )
466{
467 const char *path = luaL_checkstring( L, 1 );
468 int ret = PHYSFS_delete( path );
469 lua_pushboolean( L, ret );
470 if ( ret == 0 ) {
471 lua_pushstring( L, PHYSFS_getErrorByCode( PHYSFS_getLastErrorCode() ) );
472 return 2;
473 }
474 return 1;
475}
static int fileL_close(lua_State *L)
Closes a file.
Definition nlua_file.c:231
static const luaL_Reg fileL_methods[]
Definition nlua_file.c:38
static int fileL_seek(lua_State *L)
Seeks in an open file.
Definition nlua_file.c:313
static int fileL_write(lua_State *L)
Reads from an open file.
Definition nlua_file.c:282
LuaFile_t * lua_tofile(lua_State *L, int ind)
Lua bindings to interact with files.
Definition nlua_file.c:83
static int fileL_size(lua_State *L)
Gets the size of a file (must be open).
Definition nlua_file.c:365
static int fileL_enumerate(lua_State *L)
Returns a list of files and subdirectories of a directory.
Definition nlua_file.c:439
static int fileL_new(lua_State *L)
Opens a new file.
Definition nlua_file.c:179
int lua_isfile(lua_State *L, int ind)
Checks to see if ind is a file.
Definition nlua_file.c:123
LuaFile_t * luaL_checkfile(lua_State *L, int ind)
Gets file at index or raises error if there is no file at index.
Definition nlua_file.c:94
LuaFile_t * lua_pushfile(lua_State *L, LuaFile_t file)
Pushes a file on the stack.
Definition nlua_file.c:108
static int fileL_eq(lua_State *L)
Compares two files to see if they are the same.
Definition nlua_file.c:163
static int fileL_isopen(lua_State *L)
Checks to see if a file is open.
Definition nlua_file.c:379
static int fileL_gc(lua_State *L)
Frees a file.
Definition nlua_file.c:145
static int fileL_mkdir(lua_State *L)
Makes a directory.
Definition nlua_file.c:419
static int fileL_open(lua_State *L)
Opens a File object.
Definition nlua_file.c:200
static int fileL_read(lua_State *L)
Reads from an open file.
Definition nlua_file.c:252
static int fileL_remove(lua_State *L)
Removes a file or directory.
Definition nlua_file.c:465
static int fileL_name(lua_State *L)
Gets the name of a file object.
Definition nlua_file.c:337
int nlua_loadFile(nlua_env env)
Loads the file library.
Definition nlua_file.c:63
static int fileL_mode(lua_State *L)
Gets the mode a file is currently in.
Definition nlua_file.c:351
static int fileL_filetype(lua_State *L)
Checks to see the filetype of a path.
Definition nlua_file.c:393
static const double c[]
Definition rng.c:256
Wrapper to files.
Definition nlua_file.h:19
char path[PATH_MAX]
Definition nlua_file.h:20
SDL_RWops * rw
Definition nlua_file.h:23