naev 0.11.5
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>
11
12#include "naev.h"
15#include "physfsrwops.h"
16
17#include "nlua_file.h"
18
19#include "log.h"
20#include "nluadef.h"
21#include "physfs.h"
22
23/* File metatable methods. */
24static int fileL_gc( lua_State *L );
25static int fileL_eq( lua_State *L );
26static int fileL_new( lua_State *L );
27static int fileL_open( lua_State *L );
28static int fileL_close( lua_State *L );
29static int fileL_read( lua_State *L );
30static int fileL_write( lua_State *L );
31static int fileL_seek( lua_State *L );
32static int fileL_name( lua_State *L );
33static int fileL_mode( lua_State *L );
34static int fileL_size( lua_State *L );
35static int fileL_isopen( lua_State *L );
36static int fileL_filetype( lua_State *L );
37static int fileL_mkdir( lua_State *L );
38static int fileL_enumerate( lua_State *L );
39static int fileL_remove( lua_State *L );
40static const luaL_Reg fileL_methods[] = {
41 { "__gc", fileL_gc },
42 { "__eq", fileL_eq },
43 { "new", fileL_new },
44 { "open", fileL_open },
45 { "close", fileL_close },
46 { "read", fileL_read },
47 { "write", fileL_write },
48 { "seek", fileL_seek },
49 { "getFilename", fileL_name },
50 { "getMode", fileL_mode },
51 { "getSize", fileL_size },
52 { "isOpen", fileL_isopen },
53 { "filetype", fileL_filetype },
54 { "mkdir", fileL_mkdir },
55 { "enumerate", fileL_enumerate },
56 { "remove", fileL_remove },
57 {0,0}
58};
66int nlua_loadFile( nlua_env env )
67{
68 nlua_register(env, FILE_METATABLE, fileL_methods, 1);
69 return 0;
70}
71
86LuaFile_t* lua_tofile( lua_State *L, int ind )
87{
88 return (LuaFile_t*) lua_touserdata(L,ind);
89}
97LuaFile_t* luaL_checkfile( lua_State *L, int ind )
98{
99 if (lua_isfile(L,ind))
100 return lua_tofile(L,ind);
101 luaL_typerror(L, ind, FILE_METATABLE);
102 return NULL;
103}
111LuaFile_t* lua_pushfile( lua_State *L, LuaFile_t file )
112{
113 LuaFile_t *c = (LuaFile_t*) lua_newuserdata(L, sizeof(LuaFile_t));
114 *c = file;
115 luaL_getmetatable(L, FILE_METATABLE);
116 lua_setmetatable(L, -2);
117 return c;
118}
126int lua_isfile( lua_State *L, int ind )
127{
128 int ret;
129
130 if (lua_getmetatable(L,ind)==0)
131 return 0;
132 lua_getfield(L, LUA_REGISTRYINDEX, FILE_METATABLE);
133
134 ret = 0;
135 if (lua_rawequal(L, -1, -2)) /* does it have the correct mt? */
136 ret = 1;
137
138 lua_pop(L, 2); /* remove both metatables */
139 return ret;
140}
141
148static int fileL_gc( lua_State *L )
149{
150 LuaFile_t *lf = luaL_checkfile(L,1);
151 if (lf->rw != NULL) {
152 SDL_RWclose(lf->rw);
153 lf->rw = NULL;
154 }
155 return 0;
156}
157
166static int fileL_eq( lua_State *L )
167{
168 LuaFile_t *f1, *f2;
169 f1 = luaL_checkfile(L,1);
170 f2 = luaL_checkfile(L,2);
171 lua_pushboolean( L, (memcmp( f1, f2, sizeof(LuaFile_t) )==0) );
172 return 1;
173}
174
182static int fileL_new( lua_State *L )
183{
184 LuaFile_t lf;
185 const char *str = luaL_checkstring(L,1);
186 memset( &lf, 0, sizeof(lf) );
187 strncpy( lf.path, str, sizeof(lf.path)-1 );
188 lf.mode = 'c';
189 lf.rw = NULL;
190 lua_pushfile( L, lf );
191 return 1;
192}
193
202static int fileL_open( lua_State *L )
203{
204 LuaFile_t *lf = luaL_checkfile(L,1);
205 const char *mode = luaL_optstring(L,2,"r");
206
207 /* TODO handle mode. */
208 if (strcmp(mode,"w")==0)
209 lf->rw = PHYSFSRWOPS_openWrite( lf->path );
210 else if (strcmp(mode,"a")==0)
211 lf->rw = PHYSFSRWOPS_openAppend( lf->path );
212 else
213 lf->rw = PHYSFSRWOPS_openRead( lf->path );
214 if (lf->rw == NULL) {
215 lua_pushboolean(L,0);
216 lua_pushstring(L, SDL_GetError());
217 return 2;
218 }
219 lf->mode = mode[0];
220 lf->size = (size_t)SDL_RWsize(lf->rw);
221
222 lua_pushboolean(L,1);
223 return 1;
224}
225
233static int fileL_close( lua_State *L )
234{
235 LuaFile_t *lf = luaL_checkfile(L,1);
236 if (lf->rw != NULL) {
237 SDL_RWclose(lf->rw);
238 lf->rw = NULL;
239 }
240 lf->mode = 'c';
241 lua_pushboolean(L,1);
242 return 1;
243}
244
254static int fileL_read( lua_State *L )
255{
256 LuaFile_t *lf = luaL_checkfile(L,1);
257 size_t readlen, len;
258 char *buf;
259
260 if (lf->rw == NULL)
261 return NLUA_ERROR(L, _("file not open!"));
262
263 /* Figure out how much to read. */
264 readlen = luaL_optinteger(L,2,SDL_RWsize(lf->rw));
265
266 /* Create buffer and read into it. */
267 buf = malloc( readlen );
268 len = SDL_RWread( lf->rw, buf, 1, readlen );
269
270 lua_pushlstring(L, buf, len);
271 lua_pushinteger(L,len);
272 free( buf );
273 return 2;
274}
275
284static int fileL_write( lua_State *L )
285{
286 LuaFile_t *lf = luaL_checkfile(L,1);
287 size_t write, wrote, len;
288 const char *buf;
289
290
291 if (lf->rw == NULL)
292 return NLUA_ERROR(L, _("file not open!"));
293
294 buf = luaL_checklstring(L,2,&len);
295 write = luaL_optlong(L,3,len);
296
297 wrote = SDL_RWwrite( lf->rw, buf, 1, write );
298 if (wrote != write) {
299 lua_pushboolean(L,0);
300 lua_pushstring(L, SDL_GetError());
301 return 2;
302 }
303
304 lua_pushboolean(L,1);
305 return 1;
306}
307
316static int fileL_seek( lua_State *L )
317{
318 LuaFile_t *lf = luaL_checkfile(L,1);
319 size_t pos = luaL_checkinteger(L,2);
320 Sint64 ret;
321
322 if (lf->rw == NULL) {
323 lua_pushboolean(L,1);
324 return 1;
325 }
326
327 ret = SDL_RWseek( lf->rw, pos, RW_SEEK_SET );
328
329 lua_pushboolean(L, ret>=0);
330 return 1;
331}
332
340static int fileL_name( lua_State *L )
341{
342 LuaFile_t *lf = luaL_checkfile(L,1);
343 lua_pushstring(L, lf->path);
344 return 1;
345}
346
354static int fileL_mode( lua_State *L )
355{
356 LuaFile_t *lf = luaL_checkfile(L,1);
357 lua_pushlstring(L, &lf->mode, 1);
358 return 1;
359}
360
368static int fileL_size( lua_State *L )
369{
370 LuaFile_t *lf = luaL_checkfile(L,1);
371 lua_pushinteger(L, lf->size);
372 return 1;
373}
374
382static int fileL_isopen( lua_State *L )
383{
384 const LuaFile_t *lf = luaL_checkfile(L,1);
385 lua_pushboolean(L, lf->rw!=NULL);
386 return 1;
387}
388
396static int fileL_filetype( lua_State *L )
397{
398 const char *path = luaL_checkstring(L,1);
399 PHYSFS_Stat path_stat;
400
401 if (!PHYSFS_stat( path, &path_stat )) {
402 /* No need for warning, might not exist. */
403 lua_pushnil(L);
404 return 1;
405 }
406 if (path_stat.filetype == PHYSFS_FILETYPE_REGULAR)
407 lua_pushstring(L, "file");
408 else if (path_stat.filetype == PHYSFS_FILETYPE_DIRECTORY)
409 lua_pushstring(L, "directory");
410 else
411 lua_pushnil(L);
412 return 1;
413}
414
422static int fileL_mkdir( lua_State *L )
423{
424 const char *path = luaL_checkstring(L,1);
425 int ret = PHYSFS_mkdir( path );
426 lua_pushboolean(L,ret);
427 if (ret==0) {
428 lua_pushstring(L, PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()) );
429 return 2;
430 }
431 return 1;
432}
433
441static int fileL_enumerate( lua_State *L )
442{
443 char **items;
444 const char *path = luaL_checkstring(L,1);
445
446 lua_newtable(L);
447 items = PHYSFS_enumerateFiles( path );
448 if (items==NULL)
449 return NLUA_ERROR(L,_("Directory '%s' enumerate error: %s"), path,
450 _(PHYSFS_getErrorByCode( PHYSFS_getLastErrorCode() ) ) );
451 for (int i=0; items[i]!=NULL; i++) {
452 lua_pushstring(L,items[i]);
453 lua_rawseti(L,-2,i+1);
454 }
455 PHYSFS_freeList( items );
456 return 1;
457}
458
466static int fileL_remove( lua_State *L )
467{
468 const char *path = luaL_checkstring(L,1);
469 int ret = PHYSFS_delete( path );
470 lua_pushboolean(L,ret);
471 if (ret==0) {
472 lua_pushstring(L, PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()) );
473 return 2;
474 }
475 return 1;
476}
Header file with generic functions and naev-specifics.
static int fileL_close(lua_State *L)
Closes a file.
Definition nlua_file.c:233
static const luaL_Reg fileL_methods[]
Definition nlua_file.c:40
static int fileL_seek(lua_State *L)
Seeks in an open file.
Definition nlua_file.c:316
static int fileL_write(lua_State *L)
Reads from an open file.
Definition nlua_file.c:284
LuaFile_t * lua_tofile(lua_State *L, int ind)
Lua bindings to interact with files.
Definition nlua_file.c:86
static int fileL_size(lua_State *L)
Gets the size of a file (must be open).
Definition nlua_file.c:368
static int fileL_enumerate(lua_State *L)
Returns a list of files and subdirectories of a directory.
Definition nlua_file.c:441
static int fileL_new(lua_State *L)
Opens a new file.
Definition nlua_file.c:182
int lua_isfile(lua_State *L, int ind)
Checks to see if ind is a file.
Definition nlua_file.c:126
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:97
LuaFile_t * lua_pushfile(lua_State *L, LuaFile_t file)
Pushes a file on the stack.
Definition nlua_file.c:111
static int fileL_eq(lua_State *L)
Compares two files to see if they are the same.
Definition nlua_file.c:166
static int fileL_isopen(lua_State *L)
Checks to see if a file is open.
Definition nlua_file.c:382
static int fileL_gc(lua_State *L)
Frees a file.
Definition nlua_file.c:148
static int fileL_mkdir(lua_State *L)
Makes a directory.
Definition nlua_file.c:422
static int fileL_open(lua_State *L)
Opens a File object.
Definition nlua_file.c:202
static int fileL_read(lua_State *L)
Reads from an open file.
Definition nlua_file.c:254
static int fileL_remove(lua_State *L)
Removes a file or directory.
Definition nlua_file.c:466
static int fileL_name(lua_State *L)
Gets the name of a file object.
Definition nlua_file.c:340
int nlua_loadFile(nlua_env env)
Loads the file library.
Definition nlua_file.c:66
static int fileL_mode(lua_State *L)
Gets the mode a file is currently in.
Definition nlua_file.c:354
static int fileL_filetype(lua_State *L)
Checks to see the filetype of a path.
Definition nlua_file.c:396
static const double c[]
Definition rng.c:264
Wrapper to files.
Definition nlua_file.h:17
char path[PATH_MAX]
Definition nlua_file.h:18
SDL_RWops * rw
Definition nlua_file.h:21