diff options
author | Determinant <[email protected]> | 2015-06-05 16:56:33 +0800 |
---|---|---|
committer | Determinant <[email protected]> | 2015-06-05 16:56:33 +0800 |
commit | eba6049a82455499c68ee875843b6f44d6164fa5 (patch) | |
tree | 318485b878b80bf1ebfe5bcea4eecf014561f97e /io | |
parent | b6b85c02db6a44c17957d7b59cf68494da822a0b (diff) |
add close method for ChunkFile, fix #18
Diffstat (limited to 'io')
-rw-r--r-- | io/chunk_file.c | 22 | ||||
-rw-r--r-- | io/chunk_file.h | 1 | ||||
-rw-r--r-- | io/init.lua | 3 | ||||
-rw-r--r-- | io/sgd_buffer.lua | 2 |
4 files changed, 26 insertions, 2 deletions
diff --git a/io/chunk_file.c b/io/chunk_file.c index 4e987b7..aa7dd1c 100644 --- a/io/chunk_file.c +++ b/io/chunk_file.c @@ -10,6 +10,11 @@ do { \ if ((exp) != (ret)) INVALID_FORMAT_ERROR(fn); \ } while (0) +#define CHECK_FILE_OPEN(pfh) \ + do { \ + if ((pfh)->closed) \ + nerv_error(L, "operations on a closed file"); \ + } while (0) const char *nerv_chunk_file_tname = "nerv.ChunkFile"; const char *nerv_chunk_file_handle_tname = "nerv.ChunkFileHandle"; @@ -109,6 +114,7 @@ int nerv_chunk_file_open_write(lua_State *L, const char *fn) { if (!fp) nerv_error(L, "Error while opening chunk file: %s", fn); lfp = (ChunkFileHandle *)malloc(sizeof(ChunkFileHandle)); lfp->fp = fp; + lfp->closed = 0; luaT_pushudata(L, lfp, nerv_chunk_file_handle_tname); lua_setfield(L, -2, "handle"); luaT_pushmetatable(L, nerv_chunk_file_tname); @@ -174,6 +180,7 @@ int nerv_chunk_file_open_read(lua_State *L, const char *fn) { lua_setfield(L, -2, "metadata"); lfp = (ChunkFileHandle *)malloc(sizeof(ChunkFileHandle)); lfp->fp = fp; + lfp->closed = 0; luaT_pushudata(L, lfp, nerv_chunk_file_handle_tname); lua_setfield(L, -2, "handle"); luaT_pushmetatable(L, nerv_chunk_file_tname); @@ -215,6 +222,7 @@ int nerv_chunk_file_write_chunkdata(lua_State *L) { const char *metadata_str = lua_tolstring(L, 2, NULL); lua_getfield(L, 1, "handle"); pfh = luaT_checkudata(L, -1, nerv_chunk_file_handle_tname); + CHECK_FILE_OPEN(pfh); start = ftello(pfh->fp); write_chunk_header_plain(pfh->fp, 0, &status); /* fill zeros */ CHECK_WRITE(status); @@ -245,6 +253,7 @@ int nerv_chunk_file_get_chunkdata(lua_State *L) { lua_getfield(L, 1, "handle"); pfh = luaT_checkudata(L, -1, nerv_chunk_file_handle_tname); + CHECK_FILE_OPEN(pfh); lua_pop(L, 1); /* pop handle */ lua_getfield(L, 1, "metadata"); /* now stack: self, k, metadata */ @@ -260,10 +269,20 @@ int nerv_chunk_file_get_chunkdata(lua_State *L) { return 1; } +int nerv_chunk_file_close(lua_State *L) { + ChunkFileHandle *pfh; + lua_getfield(L, 1, "handle"); + pfh = luaT_checkudata(L, -1, nerv_chunk_file_handle_tname); + CHECK_FILE_OPEN(pfh); + fclose(pfh->fp); + pfh->closed = 1; + return 0; +} + int nerv_chunk_file_handle_destroy(lua_State *L) { ChunkFileHandle *pfh = luaT_checkudata(L, 1, nerv_chunk_file_handle_tname); - fclose(pfh->fp); + if (!pfh->closed) fclose(pfh->fp); free(pfh); return 0; } @@ -285,6 +304,7 @@ static int nerv_chunk_data_destroy(lua_State *L) { static const luaL_Reg nerv_chunk_file_methods[] = { {"get_chunkdata", nerv_chunk_file_get_chunkdata}, {"_write_chunkdata", nerv_chunk_file_write_chunkdata}, + {"close", nerv_chunk_file_close}, {"__init", nerv_chunk_file___init}, {NULL, NULL} }; diff --git a/io/chunk_file.h b/io/chunk_file.h index 9ece117..9bae59d 100644 --- a/io/chunk_file.h +++ b/io/chunk_file.h @@ -8,6 +8,7 @@ extern const char *nerv_chunk_data_tname; typedef struct ChunkFileHandle { FILE *fp; + int closed; } ChunkFileHandle; typedef struct ChunkInfo { diff --git a/io/init.lua b/io/init.lua index c151804..b722a81 100644 --- a/io/init.lua +++ b/io/init.lua @@ -18,6 +18,9 @@ function nerv.ChunkFile:write_chunk(chunk) end function nerv.ChunkFile:read_chunk(id, global_conf) + if self.metadata == nil then + nerv.error("wrong file opening mode") + end local metadata = self.metadata[id] if metadata == nil then nerv.error("chunk with id %s does not exist", id) diff --git a/io/sgd_buffer.lua b/io/sgd_buffer.lua index bf72744..381b863 100644 --- a/io/sgd_buffer.lua +++ b/io/sgd_buffer.lua @@ -15,7 +15,7 @@ function SGDBuffer:__init(global_conf, buffer_conf) local buffs = {} for id, width in pairs(reader_spec.data) do buffs[id] = {data = global_conf.mmat_type(self.buffer_size, width), - leftover = {}, + leftover = nil, width = width} end table.insert(self.readers, {buffs = buffs, |