naev 0.10.4
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 const luaL_Reg fileL_methods[] = {
40 { "__gc", fileL_gc },
41 { "__eq", fileL_eq },
42 { "new", fileL_new },
43 { "open", fileL_open },
44 { "close", fileL_close },
45 { "read", fileL_read },
46 { "write", fileL_write },
47 { "seek", fileL_seek },
48 { "getFilename", fileL_name },
49 { "getMode", fileL_mode },
50 { "getSize", fileL_size },
51 { "isOpen", fileL_isopen },
52 { "filetype", fileL_filetype },
53 { "mkdir", fileL_mkdir },
54 { "enumerate", fileL_enumerate },
55 {0,0}
56};
64int nlua_loadFile( nlua_env env )
65{
66 nlua_register(env, FILE_METATABLE, fileL_methods, 1);
67 return 0;
68}
69
84LuaFile_t* lua_tofile( lua_State *L, int ind )
85{
86 return (LuaFile_t*) lua_touserdata(L,ind);
87}
95LuaFile_t* luaL_checkfile( lua_State *L, int ind )
96{
97 if (lua_isfile(L,ind))
98 return lua_tofile(L,ind);
99 luaL_typerror(L, ind, FILE_METATABLE);
100 return NULL;
101}
109LuaFile_t* lua_pushfile( lua_State *L, LuaFile_t file )
110{
111 LuaFile_t *c = (LuaFile_t*) lua_newuserdata(L, sizeof(LuaFile_t));
112 *c = file;
113 luaL_getmetatable(L, FILE_METATABLE);
114 lua_setmetatable(L, -2);
115 return c;
116}
124int lua_isfile( lua_State *L, int ind )
125{
126 int ret;
127
128 if (lua_getmetatable(L,ind)==0)
129 return 0;
130 lua_getfield(L, LUA_REGISTRYINDEX, FILE_METATABLE);
131
132 ret = 0;
133 if (lua_rawequal(L, -1, -2)) /* does it have the correct mt? */
134 ret = 1;
135
136 lua_pop(L, 2); /* remove both metatables */
137 return ret;
138}
139
146static int fileL_gc( lua_State *L )
147{
148 LuaFile_t *lf = luaL_checkfile(L,1);
149 if (lf->rw != NULL) {
150 SDL_RWclose(lf->rw);
151 lf->rw = NULL;
152 }
153 return 0;
154}
155
164static int fileL_eq( lua_State *L )
165{
166 LuaFile_t *f1, *f2;
167 f1 = luaL_checkfile(L,1);
168 f2 = luaL_checkfile(L,2);
169 lua_pushboolean( L, (memcmp( f1, f2, sizeof(LuaFile_t) )==0) );
170 return 1;
171}
172
180static int fileL_new( lua_State *L )
181{
182 LuaFile_t lf;
183 const char *str = luaL_checkstring(L,1);
184 strncpy( lf.path, str, sizeof(lf.path)-1 );
185
186 lf.mode = 'c';
187 lf.rw = NULL;
188 lua_pushfile( L, lf );
189 return 1;
190}
191
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 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
289 if (lf->rw == NULL)
290 NLUA_ERROR(L, _("file not open!"));
291
292 buf = luaL_checklstring(L,2,&len);
293 write = luaL_optlong(L,3,len);
294
295 wrote = SDL_RWwrite( lf->rw, buf, 1, write );
296 if (wrote != write) {
297 lua_pushboolean(L,0);
298 lua_pushstring(L, SDL_GetError());
299 return 2;
300 }
301
302 lua_pushboolean(L,1);
303 return 1;
304}
305
314static int fileL_seek( lua_State *L )
315{
316 LuaFile_t *lf = luaL_checkfile(L,1);
317 size_t pos = luaL_checkinteger(L,2);
318 Sint64 ret;
319
320 if (lf->rw == NULL) {
321 lua_pushboolean(L,1);
322 return 1;
323 }
324
325 ret = SDL_RWseek( lf->rw, pos, RW_SEEK_SET );
326
327 lua_pushboolean(L, ret>=0);
328 return 1;
329}
330
338static int fileL_name( lua_State *L )
339{
340 LuaFile_t *lf = luaL_checkfile(L,1);
341 lua_pushstring(L, lf->path);
342 return 1;
343}
344
352static int fileL_mode( lua_State *L )
353{
354 LuaFile_t *lf = luaL_checkfile(L,1);
355 lua_pushlstring(L, &lf->mode, 1);
356 return 1;
357}
358
366static int fileL_size( lua_State *L )
367{
368 LuaFile_t *lf = luaL_checkfile(L,1);
369 lua_pushinteger(L, lf->size);
370 return 1;
371}
372
380static int fileL_isopen( lua_State *L )
381{
382 LuaFile_t *lf = luaL_checkfile(L,1);
383 lua_pushboolean(L, lf->rw!=NULL);
384 return 1;
385}
386
394static int fileL_filetype( lua_State *L )
395{
396 const char *path = luaL_checkstring(L,1);
397 PHYSFS_Stat path_stat;
398
399 if (!PHYSFS_stat( path, &path_stat )) {
400 /* No need for warning, might not exist. */
401 lua_pushnil(L);
402 return 1;
403 }
404 if (path_stat.filetype == PHYSFS_FILETYPE_REGULAR)
405 lua_pushstring(L, "file");
406 else if (path_stat.filetype == PHYSFS_FILETYPE_DIRECTORY)
407 lua_pushstring(L, "directory");
408 else
409 lua_pushnil(L);
410 return 1;
411}
412
420static int fileL_mkdir( lua_State *L )
421{
422 const char *path = luaL_checkstring(L,1);
423 int ret = PHYSFS_mkdir( path );
424 lua_pushboolean(L,ret==0);
425 return 1;
426}
427
435static int fileL_enumerate( lua_State *L )
436{
437 char **items;
438 const char *path = luaL_checkstring(L,1);
439
440 lua_newtable(L);
441 items = PHYSFS_enumerateFiles( path );
442 if (items==NULL)
443 NLUA_ERROR(L,_("Directory '%s' enumerate error: %s"), path,
444 _(PHYSFS_getErrorByCode( PHYSFS_getLastErrorCode() ) ) );
445 for (int i=0; items[i]!=NULL; i++) {
446 lua_pushstring(L,items[i]);
447 lua_rawseti(L,-2,i+1);
448 }
449 PHYSFS_freeList( items );
450 return 1;
451}
Header file with generic functions and naev-specifics.
static char buf[NEWS_MAX_LENGTH]
Definition: news.c:45
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:39
static int fileL_seek(lua_State *L)
Seeks in an open file.
Definition: nlua_file.c:314
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:84
static int fileL_size(lua_State *L)
Gets the size of a file (must be open).
Definition: nlua_file.c:366
static int fileL_enumerate(lua_State *L)
Returns a list of files and subdirectories of a directory.
Definition: nlua_file.c:435
static int fileL_new(lua_State *L)
Opens a new file.
Definition: nlua_file.c:180
int lua_isfile(lua_State *L, int ind)
Checks to see if ind is a file.
Definition: nlua_file.c:124
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:95
LuaFile_t * lua_pushfile(lua_State *L, LuaFile_t file)
Pushes a file on the stack.
Definition: nlua_file.c:109
static int fileL_eq(lua_State *L)
Compares two files to see if they are the same.
Definition: nlua_file.c:164
static int fileL_isopen(lua_State *L)
Checks to see if a file is open.
Definition: nlua_file.c:380
static int fileL_gc(lua_State *L)
Frees a file.
Definition: nlua_file.c:146
static int fileL_mkdir(lua_State *L)
Makes a directory.
Definition: nlua_file.c:420
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_name(lua_State *L)
Gets the name of a file object.
Definition: nlua_file.c:338
int nlua_loadFile(nlua_env env)
Loads the file library.
Definition: nlua_file.c:64
static int fileL_mode(lua_State *L)
Gets the mode a file is currently in.
Definition: nlua_file.c:352
static int fileL_filetype(lua_State *L)
Checks to see the filetype of a path.
Definition: nlua_file.c:394
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