aboutsummaryrefslogtreecommitdiff
path: root/io
diff options
context:
space:
mode:
authorDeterminant <[email protected]>2015-06-05 16:56:33 +0800
committerDeterminant <[email protected]>2015-06-05 16:56:33 +0800
commiteba6049a82455499c68ee875843b6f44d6164fa5 (patch)
tree318485b878b80bf1ebfe5bcea4eecf014561f97e /io
parentb6b85c02db6a44c17957d7b59cf68494da822a0b (diff)
add close method for ChunkFile, fix #18
Diffstat (limited to 'io')
-rw-r--r--io/chunk_file.c22
-rw-r--r--io/chunk_file.h1
-rw-r--r--io/init.lua3
-rw-r--r--io/sgd_buffer.lua2
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,