diff --git a/libretro-common/file/retro_file.c b/libretro-common/file/retro_file.c index 64e89fa497..d3a6b0ae3a 100644 --- a/libretro-common/file/retro_file.c +++ b/libretro-common/file/retro_file.c @@ -37,36 +37,27 @@ #include #endif -struct RFILE +typedef struct RFILE { int fd; -}; +} RFILE; -enum +RFILE *retro_fopen(const char *path, unsigned mode, ssize_t len) { - MODE_READ = 0, - MODE_WRITE, - MODE_READ_WRITE, -}; - -struct RFILE *retro_fopen(const char *path, const char *mode, size_t len) -{ - int flags = 0; - struct RFILE *stream = (struct RFILE*)calloc(1, sizeof(*stream)); + RFILE *stream = (RFILE*)calloc(1, sizeof(*stream)); if (!stream) return NULL; - if (!strcmp(mode, "w+")) - flags = MODE_READ_WRITE; - - switch (flags) + switch (mode) { - case MODE_READ: + case RFILE_MODE_READ: + stream->fd = open(path, O_RDONLY); break; - case MODE_WRITE: + case RFILE_MODE_WRITE: + stream->fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); break; - case MODE_READ_WRITE: + case RFILE_MODE_READ_WRITE: #ifdef _WIN32 stream->fd = open(path, O_RDWR | O_BINARY); #else @@ -78,7 +69,7 @@ struct RFILE *retro_fopen(const char *path, const char *mode, size_t len) return stream; } -ssize_t retro_seek(struct RFILE *stream, ssize_t offset, int whence) +ssize_t retro_fseek(RFILE *stream, ssize_t offset, int whence) { if (!stream) return -1; @@ -86,24 +77,25 @@ ssize_t retro_seek(struct RFILE *stream, ssize_t offset, int whence) return lseek(stream->fd, offset, whence); } -ssize_t retro_read(struct RFILE *stream, void *s, size_t len) +ssize_t retro_fread(RFILE *stream, void *s, size_t len) { if (!stream) return -1; return read(stream->fd, s, len); } -ssize_t retro_write(struct RFILE *stream, const void *s, size_t len) +ssize_t retro_fwrite(RFILE *stream, const void *s, size_t len) { if (!stream) return -1; return write(stream->fd, s, len); } -void retro_fclose(struct RFILE *stream) +void retro_fclose(RFILE *stream) { if (!stream) return; + close(stream->fd); free(stream); } diff --git a/libretro-common/include/retro_file.h b/libretro-common/include/retro_file.h index 06150eddbe..920ebf426c 100644 --- a/libretro-common/include/retro_file.h +++ b/libretro-common/include/retro_file.h @@ -32,17 +32,24 @@ extern "C" { #endif -struct RFILE; +typedef struct RFILE RFILE; -struct RFILE *retro_fopen(const char *path, const char *mode, size_t len); +enum +{ + RFILE_MODE_READ = 0, + RFILE_MODE_WRITE, + RFILE_MODE_READ_WRITE, +}; -ssize_t retro_seek(struct RFILE *stream, ssize_t offset, int whence); +RFILE *retro_fopen(const char *path, unsigned mode, ssize_t len); -ssize_t retro_read(struct RFILE *stream, void *s, size_t len); +ssize_t retro_fseek(RFILE *stream, ssize_t offset, int whence); -ssize_t retro_write(struct RFILE *stream, const void *s, size_t len); +ssize_t retro_fread(RFILE *stream, void *s, size_t len); -void retro_fclose(struct RFILE *stream); +ssize_t retro_fwrite(RFILE *stream, const void *s, size_t len); + +void retro_fclose(RFILE *stream); #ifdef __cplusplus } diff --git a/libretro-db/Makefile b/libretro-db/Makefile index a6d138ae2f..b34558c973 100644 --- a/libretro-db/Makefile +++ b/libretro-db/Makefile @@ -11,6 +11,7 @@ LUA_CONVERTER_C = \ query.c \ lua_converter.c \ $(LIBRETRO_COMMON_DIR)/compat/compat_fnmatch.c \ + $(LIBRETRO_COMMON_DIR)/file/retro_file.c \ $(LIBRETRO_COMMON_DIR)/compat/compat.c LUA_CONVERTER_C_OBJS := $(LUA_CONVERTER_C:.c=.o) @@ -23,6 +24,7 @@ RARCHDB_TOOL_C = \ query.c \ libretrodb.c \ $(LIBRETRO_COMMON_DIR)/compat/compat_fnmatch.c \ + $(LIBRETRO_COMMON_DIR)/file/retro_file.c \ $(LIBRETRO_COMMON_DIR)/compat/compat.c RARCHDB_TOOL_OBJS := $(RARCHDB_TOOL_C:.c=.o) @@ -36,10 +38,18 @@ TESTLIB_C = \ rmsgpack.c \ rmsgpack_dom.c \ $(LIBRETRO_COMMON_DIR)/compat/compat_fnmatch.c \ + $(LIBRETRO_COMMON_DIR)/file/retro_file.c \ $(LIBRETRO_COMMON_DIR)/compat/compat.c TESTLIB_OBJS := $(TESTLIB_C:.c=.o) +RMSGPACK_C = \ + rmsgpack.c \ + rmsgpack_test.c \ + $(LIBRETRO_COMMON_DIR)/file/retro_file.c + +RMSGPACK_OBJS := $(RMSGPACK_C:.c=.o) + LUA_FLAGS = `pkg-config lua --libs` TESTLIB_FLAGS = ${CFLAGS} ${LUA_FLAGS} -shared -fpic @@ -56,8 +66,8 @@ lua_converter: ${LUA_CONVERTER_C_OBJS} libretrodb_tool: ${RARCHDB_TOOL_OBJS} ${CC} $(INCFLAGS) ${RARCHDB_TOOL_OBJS} -o $@ -rmsgpack_test: - ${CC} $(INCFLAGS) rmsgpack.c rmsgpack_test.c -g -o $@ +rmsgpack_test: $(RMSGPACK_OBJS) + ${CC} $(INCFLAGS) ${RMSGPACK_OBJS} -g -o $@ testlib.so: ${TESTLIB_OBJS} ${CC} ${INCFLAGS} ${TESTLIB_FLAGS} ${TESTLIB_OBJS} -o $@ diff --git a/libretro-db/libretrodb.c b/libretro-db/libretrodb.c index 23e8ec92e3..e37207b9e4 100644 --- a/libretro-db/libretrodb.c +++ b/libretro-db/libretrodb.c @@ -14,6 +14,8 @@ #include +#include + #include "rmsgpack_dom.h" #include "rmsgpack.h" #include "bintree.h" @@ -31,7 +33,7 @@ struct node_iter_ctx typedef struct libretrodb { - int fd; + RFILE *fd; uint64_t root; uint64_t count; uint64_t first_index_offset; @@ -59,7 +61,7 @@ typedef struct libretrodb_header typedef struct libretrodb_cursor { int is_valid; - int fd; + RFILE *fd; int eof; libretrodb_query_t *query; libretrodb_t *db; @@ -67,12 +69,12 @@ typedef struct libretrodb_cursor static struct rmsgpack_dom_value sentinal; -static int libretrodb_read_metadata(int fd, libretrodb_metadata_t *md) +static int libretrodb_read_metadata(RFILE *fd, libretrodb_metadata_t *md) { return rmsgpack_dom_read_into(fd, "count", &md->count, NULL); } -static int libretrodb_write_metadata(int fd, libretrodb_metadata_t *md) +static int libretrodb_write_metadata(RFILE *fd, libretrodb_metadata_t *md) { rmsgpack_write_map_header(fd, 1); rmsgpack_write_string(fd, "count", strlen("count")); @@ -113,7 +115,7 @@ static int validate_document(const struct rmsgpack_dom_value *doc) return rv; } -int libretrodb_create(int fd, libretrodb_value_provider value_provider, +int libretrodb_create(RFILE *fd, libretrodb_value_provider value_provider, void *ctx) { int rv; @@ -124,12 +126,12 @@ int libretrodb_create(int fd, libretrodb_value_provider value_provider, libretrodb_header_t header = {{0}}; memcpy(header.magic_number, MAGIC_NUMBER, sizeof(MAGIC_NUMBER)-1); - root = lseek(fd, 0, SEEK_CUR); + root = retro_fseek(fd, 0, SEEK_CUR); /* We write the header in the end because we need to know the size of * the db first */ - lseek(fd, sizeof(libretrodb_header_t), SEEK_CUR); + retro_fseek(fd, sizeof(libretrodb_header_t), SEEK_CUR); while ((rv = value_provider(ctx, &item)) == 0) { @@ -148,17 +150,17 @@ int libretrodb_create(int fd, libretrodb_value_provider value_provider, if ((rv = rmsgpack_dom_write(fd, &sentinal)) < 0) goto clean; - header.metadata_offset = httobe64(lseek(fd, 0, SEEK_CUR)); + header.metadata_offset = httobe64(retro_fseek(fd, 0, SEEK_CUR)); md.count = item_count; libretrodb_write_metadata(fd, &md); - lseek(fd, root, SEEK_SET); - write(fd, &header, sizeof(header)); + retro_fseek(fd, root, SEEK_SET); + retro_fwrite(fd, &header, sizeof(header)); clean: rmsgpack_dom_value_free(&item); return rv; } -static int libretrodb_read_index_header(int fd, libretrodb_index_t *idx) +static int libretrodb_read_index_header(RFILE *fd, libretrodb_index_t *idx) { uint64_t name_len = 50; return rmsgpack_dom_read_into(fd, @@ -167,7 +169,7 @@ static int libretrodb_read_index_header(int fd, libretrodb_index_t *idx) "next", &idx->next, NULL); } -static void libretrodb_write_index_header(int fd, libretrodb_index_t *idx) +static void libretrodb_write_index_header(RFILE *fd, libretrodb_index_t *idx) { rmsgpack_write_map_header(fd, 3); rmsgpack_write_string(fd, "name", strlen("name")); @@ -180,8 +182,9 @@ static void libretrodb_write_index_header(int fd, libretrodb_index_t *idx) void libretrodb_close(libretrodb_t *db) { - close(db->fd); - db->fd = -1; + if (db->fd) + retro_fclose(db->fd); + db->fd = NULL; } int libretrodb_open(const char *path, libretrodb_t *db) @@ -189,19 +192,15 @@ int libretrodb_open(const char *path, libretrodb_t *db) libretrodb_header_t header; libretrodb_metadata_t md; int rv; -#ifdef _WIN32 - int fd = open(path, O_RDWR | O_BINARY); -#else - int fd = open(path, O_RDWR); -#endif + RFILE *fd = retro_fopen(path, RFILE_MODE_READ_WRITE, -1); - if (fd == -1) + if (!fd) return -errno; strcpy(db->path, path); - db->root = lseek(fd, 0, SEEK_CUR); + db->root = retro_fseek(fd, 0, SEEK_CUR); - if ((rv = read(fd, &header, sizeof(header))) == -1) + if ((rv = retro_fread(fd, &header, sizeof(header))) == -1) { rv = -errno; goto error; @@ -214,7 +213,7 @@ int libretrodb_open(const char *path, libretrodb_t *db) } header.metadata_offset = betoht64(header.metadata_offset); - lseek(fd, header.metadata_offset, SEEK_SET); + retro_fseek(fd, header.metadata_offset, SEEK_SET); if (libretrodb_read_metadata(fd, &md) < 0) { @@ -223,20 +222,21 @@ int libretrodb_open(const char *path, libretrodb_t *db) } db->count = md.count; - db->first_index_offset = lseek(fd, 0, SEEK_CUR); + db->first_index_offset = retro_fseek(fd, 0, SEEK_CUR); db->fd = fd; return 0; error: - close(fd); + if (fd) + retro_fclose(fd); return rv; } static int libretrodb_find_index(libretrodb_t *db, const char *index_name, libretrodb_index_t *idx) { - off_t eof = lseek(db->fd, 0, SEEK_END); - off_t offset = lseek(db->fd, db->first_index_offset, SEEK_SET); + off_t eof = retro_fseek(db->fd, 0, SEEK_END); + off_t offset = retro_fseek(db->fd, db->first_index_offset, SEEK_SET); while (offset < eof) { @@ -245,7 +245,7 @@ static int libretrodb_find_index(libretrodb_t *db, const char *index_name, if (strncmp(index_name, idx->name, strlen(idx->name)) == 0) return 0; - offset = lseek(db->fd, idx->next, SEEK_CUR); + offset = retro_fseek(db->fd, idx->next, SEEK_CUR); } return -1; @@ -301,7 +301,7 @@ int libretrodb_find_entry(libretrodb_t *db, const char *index_name, while (nread < bufflen) { void *buff_ = (uint64_t *)buff + nread; - rv = read(db->fd, buff_, bufflen - nread); + rv = retro_fread(db->fd, buff_, bufflen - nread); if (rv <= 0) { @@ -315,7 +315,7 @@ int libretrodb_find_entry(libretrodb_t *db, const char *index_name, free(buff); if (rv == 0) - lseek(db->fd, offset, SEEK_SET); + retro_fseek(db->fd, offset, SEEK_SET); return rmsgpack_dom_read(db->fd, out); } @@ -331,7 +331,7 @@ int libretrodb_find_entry(libretrodb_t *db, const char *index_name, int libretrodb_cursor_reset(libretrodb_cursor_t *cursor) { cursor->eof = 0; - return lseek(cursor->fd, + return retro_fseek(cursor->fd, cursor->db->root + sizeof(libretrodb_header_t), SEEK_SET); } @@ -378,16 +378,17 @@ void libretrodb_cursor_close(libretrodb_cursor_t *cursor) if (!cursor) return; - close(cursor->fd); - cursor->is_valid = 0; - cursor->fd = -1; - cursor->eof = 1; - cursor->db = NULL; + if (cursor->fd) + retro_fclose(cursor->fd); if (cursor->query) libretrodb_query_free(cursor->query); - cursor->query = NULL; + cursor->is_valid = 0; + cursor->eof = 1; + cursor->fd = NULL; + cursor->db = NULL; + cursor->query = NULL; } /** @@ -403,9 +404,9 @@ void libretrodb_cursor_close(libretrodb_cursor_t *cursor) int libretrodb_cursor_open(libretrodb_t *db, libretrodb_cursor_t *cursor, libretrodb_query_t *q) { - cursor->fd = dup(db->fd); + cursor->fd = retro_fopen(db->path, RFILE_MODE_READ, -1); - if (cursor->fd == -1) + if (!cursor->fd) return -errno; cursor->db = db; @@ -423,7 +424,7 @@ static int node_iter(void *value, void *ctx) { struct node_iter_ctx *nictx = (struct node_iter_ctx*)ctx; - if (write(nictx->db->fd, value, + if (retro_fwrite(nictx->db->fd, value, nictx->idx->key_size + sizeof(uint64_t)) > 0) return 0; @@ -432,7 +433,7 @@ static int node_iter(void *value, void *ctx) static uint64_t libretrodb_tell(libretrodb_t *db) { - return lseek(db->fd, 0, SEEK_CUR); + return retro_fseek(db->fd, 0, SEEK_CUR); } int libretrodb_create_index(libretrodb_t *db, @@ -534,7 +535,7 @@ int libretrodb_create_index(libretrodb_t *db, (void)rv; (void)idx_header_offset; - idx_header_offset = lseek(db->fd, 0, SEEK_END); + idx_header_offset = retro_fseek(db->fd, 0, SEEK_END); strncpy(idx.name, name, 50); idx.name[49] = '\0'; diff --git a/libretro-db/libretrodb.h b/libretro-db/libretrodb.h index 1af26d1f2f..45573814c0 100644 --- a/libretro-db/libretrodb.h +++ b/libretro-db/libretrodb.h @@ -23,7 +23,7 @@ typedef struct libretrodb_index libretrodb_index_t; typedef int (*libretrodb_value_provider)(void *ctx, struct rmsgpack_dom_value *out); -int libretrodb_create(int fd, libretrodb_value_provider value_provider, void *ctx); +int libretrodb_create(RFILE *fd, libretrodb_value_provider value_provider, void *ctx); void libretrodb_close(libretrodb_t *db); diff --git a/libretro-db/lua_converter.c b/libretro-db/lua_converter.c index 21c5b0713f..4eec6c2b7d 100644 --- a/libretro-db/lua_converter.c +++ b/libretro-db/lua_converter.c @@ -67,9 +67,10 @@ static int value_provider(void * ctx, struct rmsgpack_dom_value *out) int main(int argc, char ** argv) { - const char * db_file; - const char * lua_file; - int dst = -1; + lua_State *L; + const char *db_file; + const char *lua_file; + RFILE *dst; int rv = 0; if (argc < 3) @@ -78,10 +79,10 @@ int main(int argc, char ** argv) return 1; } - db_file = argv[1]; + db_file = argv[1]; lua_file = argv[2]; + L = luaL_newstate(); - lua_State * L = luaL_newstate(); luaL_openlibs(L); luaL_dostring(L, LUA_COMMON); @@ -90,8 +91,8 @@ int main(int argc, char ** argv) call_init(L, argc - 2, (const char **) argv + 2); - dst = open(db_file, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); - if (dst == -1) + dst = retro_fopen(db_file, RFILE_MODE_WRITE, -1); + if (!dst) { printf( "Could not open destination file '%s': %s\n", @@ -106,8 +107,7 @@ int main(int argc, char ** argv) clean: lua_close(L); - if (dst != -1) - close(dst); + retro_fclose(dst); return rv; } diff --git a/libretro-db/rmsgpack.c b/libretro-db/rmsgpack.c index d795c5234b..da7a09d0ed 100644 --- a/libretro-db/rmsgpack.c +++ b/libretro-db/rmsgpack.c @@ -87,7 +87,7 @@ static const uint8_t MPF_UINT64 = _MPF_UINT64; static const uint8_t MPF_NIL = _MPF_NIL; -int rmsgpack_write_array_header(int fd, uint32_t size) +int rmsgpack_write_array_header(RFILE *fd, uint32_t size) { uint16_t tmp_i16; uint32_t tmp_i32; @@ -95,26 +95,26 @@ int rmsgpack_write_array_header(int fd, uint32_t size) if (size < 16) { size = (size | MPF_FIXARRAY); - if (write(fd, &size, sizeof(int8_t)) == -1) + if (retro_fwrite(fd, &size, sizeof(int8_t)) == -1) goto error; return sizeof(int8_t); } else if (size == (uint16_t)size) { - if (write(fd, &MPF_ARRAY16, sizeof(MPF_ARRAY16)) == -1) + if (retro_fwrite(fd, &MPF_ARRAY16, sizeof(MPF_ARRAY16)) == -1) goto error; tmp_i16 = httobe16(size); - if (write(fd, (void *)(&tmp_i16), sizeof(uint16_t)) == -1) + if (retro_fwrite(fd, (void *)(&tmp_i16), sizeof(uint16_t)) == -1) goto error; return sizeof(int8_t) + sizeof(uint16_t); } - if (write(fd, &MPF_ARRAY32, sizeof(MPF_ARRAY32)) == -1) + if (retro_fwrite(fd, &MPF_ARRAY32, sizeof(MPF_ARRAY32)) == -1) goto error; tmp_i32 = httobe32(size); - if (write(fd, (void *)(&tmp_i32), sizeof(uint32_t)) == -1) + if (retro_fwrite(fd, (void *)(&tmp_i32), sizeof(uint32_t)) == -1) goto error; return sizeof(int8_t) + sizeof(uint32_t); @@ -123,7 +123,7 @@ error: return -errno; } -int rmsgpack_write_map_header(int fd, uint32_t size) +int rmsgpack_write_map_header(RFILE *fd, uint32_t size) { uint16_t tmp_i16; uint32_t tmp_i32; @@ -131,24 +131,24 @@ int rmsgpack_write_map_header(int fd, uint32_t size) if (size < 16) { size = (size | MPF_FIXMAP); - if (write(fd, &size, sizeof(int8_t)) == -1) + if (retro_fwrite(fd, &size, sizeof(int8_t)) == -1) goto error; return sizeof(int8_t); } else if (size < (uint16_t)size) { - if (write(fd, &MPF_MAP16, sizeof(MPF_MAP16)) == -1) + if (retro_fwrite(fd, &MPF_MAP16, sizeof(MPF_MAP16)) == -1) goto error; tmp_i16 = httobe16(size); - if (write(fd, (void *)(&tmp_i16), sizeof(uint16_t)) == -1) + if (retro_fwrite(fd, (void *)(&tmp_i16), sizeof(uint16_t)) == -1) goto error; return sizeof(uint8_t) + sizeof(uint16_t); } tmp_i32 = httobe32(size); - if (write(fd, &MPF_MAP32, sizeof(MPF_MAP32)) == -1) + if (retro_fwrite(fd, &MPF_MAP32, sizeof(MPF_MAP32)) == -1) goto error; - if (write(fd, (void *)(&tmp_i32), sizeof(uint32_t)) == -1) + if (retro_fwrite(fd, (void *)(&tmp_i32), sizeof(uint32_t)) == -1) goto error; return sizeof(int8_t) + sizeof(uint32_t); @@ -157,7 +157,7 @@ error: return -errno; } -int rmsgpack_write_string(int fd, const char *s, uint32_t len) +int rmsgpack_write_string(RFILE *fd, const char *s, uint32_t len) { uint16_t tmp_i16; uint32_t tmp_i32; @@ -167,37 +167,37 @@ int rmsgpack_write_string(int fd, const char *s, uint32_t len) if (len < 32) { fixlen = len | MPF_FIXSTR; - if (write(fd, &fixlen, sizeof(int8_t)) == -1) + if (retro_fwrite(fd, &fixlen, sizeof(int8_t)) == -1) goto error; } else if (len < (1 << 8)) { - if (write(fd, &MPF_STR8, sizeof(MPF_STR8)) == -1) + if (retro_fwrite(fd, &MPF_STR8, sizeof(MPF_STR8)) == -1) goto error; - if (write(fd, &len, sizeof(uint8_t)) == -1) + if (retro_fwrite(fd, &len, sizeof(uint8_t)) == -1) goto error; written += sizeof(uint8_t); } else if (len < (1 << 16)) { - if (write(fd, &MPF_STR16, sizeof(MPF_STR16)) == -1) + if (retro_fwrite(fd, &MPF_STR16, sizeof(MPF_STR16)) == -1) goto error; tmp_i16 = httobe16(len); - if (write(fd, &tmp_i16, sizeof(uint16_t)) == -1) + if (retro_fwrite(fd, &tmp_i16, sizeof(uint16_t)) == -1) goto error; written += sizeof(uint16_t); } else { - if (write(fd, &MPF_STR32, sizeof(MPF_STR32)) == -1) + if (retro_fwrite(fd, &MPF_STR32, sizeof(MPF_STR32)) == -1) goto error; tmp_i32 = httobe32(len); - if (write(fd, &tmp_i32, sizeof(uint32_t)) == -1) + if (retro_fwrite(fd, &tmp_i32, sizeof(uint32_t)) == -1) goto error; written += sizeof(uint32_t); } - if (write(fd, s, len) == -1) + if (retro_fwrite(fd, s, len) == -1) goto error; written += len; @@ -208,7 +208,7 @@ error: return -errno; } -int rmsgpack_write_bin(int fd, const void *s, uint32_t len) +int rmsgpack_write_bin(RFILE *fd, const void *s, uint32_t len) { uint16_t tmp_i16; uint32_t tmp_i32; @@ -216,31 +216,31 @@ int rmsgpack_write_bin(int fd, const void *s, uint32_t len) if (len == (uint8_t)len) { - if (write(fd, &MPF_BIN8, sizeof(MPF_BIN8)) == -1) + if (retro_fwrite(fd, &MPF_BIN8, sizeof(MPF_BIN8)) == -1) goto error; - if (write(fd, &len, sizeof(uint8_t)) == -1) + if (retro_fwrite(fd, &len, sizeof(uint8_t)) == -1) goto error; written += sizeof(uint8_t); } else if (len == (uint16_t)len) { - if (write(fd, &MPF_BIN16, sizeof(MPF_BIN16)) == -1) + if (retro_fwrite(fd, &MPF_BIN16, sizeof(MPF_BIN16)) == -1) goto error; tmp_i16 = httobe16(len); - if (write(fd, &tmp_i16, sizeof(uint16_t)) == -1) + if (retro_fwrite(fd, &tmp_i16, sizeof(uint16_t)) == -1) goto error; written += sizeof(uint16_t); } else { - if (write(fd, &MPF_BIN32, sizeof(MPF_BIN32)) == -1) + if (retro_fwrite(fd, &MPF_BIN32, sizeof(MPF_BIN32)) == -1) goto error; tmp_i32 = httobe32(len); - if (write(fd, &tmp_i32, sizeof(uint32_t)) == -1) + if (retro_fwrite(fd, &tmp_i32, sizeof(uint32_t)) == -1) goto error; written += sizeof(uint32_t); } - if (write(fd, s, len) == -1) + if (retro_fwrite(fd, s, len) == -1) goto error; written += len; @@ -251,22 +251,22 @@ error: return -errno; } -int rmsgpack_write_nil(int fd) +int rmsgpack_write_nil(RFILE *fd) { - if (write(fd, &MPF_NIL, sizeof(MPF_NIL)) == -1) + if (retro_fwrite(fd, &MPF_NIL, sizeof(MPF_NIL)) == -1) return -errno; return sizeof(uint8_t); } -int rmsgpack_write_bool(int fd, int value) +int rmsgpack_write_bool(RFILE *fd, int value) { if (value) { - if (write(fd, &MPF_TRUE, sizeof(MPF_TRUE)) == -1) + if (retro_fwrite(fd, &MPF_TRUE, sizeof(MPF_TRUE)) == -1) goto error; } - if (write(fd, &MPF_FALSE, sizeof(MPF_FALSE)) == -1) + if (retro_fwrite(fd, &MPF_FALSE, sizeof(MPF_FALSE)) == -1) goto error; return sizeof(uint8_t); @@ -275,7 +275,7 @@ error: return -errno; } -int rmsgpack_write_int(int fd, int64_t value) +int rmsgpack_write_int(RFILE *fd, int64_t value) { int16_t tmp_i16; int32_t tmp_i32; @@ -284,51 +284,51 @@ int rmsgpack_write_int(int fd, int64_t value) if (value >=0 && value < 128) { - if (write(fd, &value, sizeof(int8_t)) == -1) + if (retro_fwrite(fd, &value, sizeof(int8_t)) == -1) goto error; } else if (value < 0 && value > -32) { tmpval = (value) | 0xe0; - if (write(fd, &tmpval, sizeof(uint8_t)) == -1) + if (retro_fwrite(fd, &tmpval, sizeof(uint8_t)) == -1) goto error; } else if (value == (int8_t)value) { - if (write(fd, &MPF_INT8, sizeof(MPF_INT8)) == -1) + if (retro_fwrite(fd, &MPF_INT8, sizeof(MPF_INT8)) == -1) goto error; - if (write(fd, &value, sizeof(int8_t)) == -1) + if (retro_fwrite(fd, &value, sizeof(int8_t)) == -1) goto error; written += sizeof(int8_t); } else if (value == (int16_t)value) { - if (write(fd, &MPF_INT16, sizeof(MPF_INT16)) == -1) + if (retro_fwrite(fd, &MPF_INT16, sizeof(MPF_INT16)) == -1) goto error; tmp_i16 = httobe16(value); - if (write(fd, &tmp_i16, sizeof(int16_t)) == -1) + if (retro_fwrite(fd, &tmp_i16, sizeof(int16_t)) == -1) goto error; written += sizeof(int16_t); } else if (value == (int32_t)value) { - if (write(fd, &MPF_INT32, sizeof(MPF_INT32)) == -1) + if (retro_fwrite(fd, &MPF_INT32, sizeof(MPF_INT32)) == -1) goto error; tmp_i32 = httobe32(value); - if (write(fd, &tmp_i32, sizeof(int32_t)) == -1) + if (retro_fwrite(fd, &tmp_i32, sizeof(int32_t)) == -1) goto error; written += sizeof(int32_t); } else { - if (write(fd, &MPF_INT64, sizeof(MPF_INT64)) == -1) + if (retro_fwrite(fd, &MPF_INT64, sizeof(MPF_INT64)) == -1) goto error; value = httobe64(value); - if (write(fd, &value, sizeof(int64_t)) == -1) + if (retro_fwrite(fd, &value, sizeof(int64_t)) == -1) goto error; written += sizeof(int64_t); } @@ -339,7 +339,7 @@ error: return -errno; } -int rmsgpack_write_uint(int fd, uint64_t value) +int rmsgpack_write_uint(RFILE *fd, uint64_t value) { uint16_t tmp_i16; uint32_t tmp_i32; @@ -347,40 +347,40 @@ int rmsgpack_write_uint(int fd, uint64_t value) if (value == (uint8_t)value) { - if (write(fd, &MPF_UINT8, sizeof(MPF_UINT8)) == -1) + if (retro_fwrite(fd, &MPF_UINT8, sizeof(MPF_UINT8)) == -1) goto error; - if (write(fd, &value, sizeof(uint8_t)) == -1) + if (retro_fwrite(fd, &value, sizeof(uint8_t)) == -1) goto error; written += sizeof(uint8_t); } else if (value == (uint16_t)value) { - if (write(fd, &MPF_UINT16, sizeof(MPF_UINT16)) == -1) + if (retro_fwrite(fd, &MPF_UINT16, sizeof(MPF_UINT16)) == -1) goto error; tmp_i16 = httobe16(value); - if (write(fd, &tmp_i16, sizeof(uint16_t)) == -1) + if (retro_fwrite(fd, &tmp_i16, sizeof(uint16_t)) == -1) goto error; written += sizeof(uint16_t); } else if (value == (uint32_t)value) { - if (write(fd, &MPF_UINT32, sizeof(MPF_UINT32)) == -1) + if (retro_fwrite(fd, &MPF_UINT32, sizeof(MPF_UINT32)) == -1) goto error; tmp_i32 = httobe32(value); - if (write(fd, &tmp_i32, sizeof(uint32_t)) == -1) + if (retro_fwrite(fd, &tmp_i32, sizeof(uint32_t)) == -1) goto error; written += sizeof(uint32_t); } else { - if (write(fd, &MPF_UINT64, sizeof(MPF_UINT64)) == -1) + if (retro_fwrite(fd, &MPF_UINT64, sizeof(MPF_UINT64)) == -1) goto error; value = httobe64(value); - if (write(fd, &value, sizeof(uint64_t)) == -1) + if (retro_fwrite(fd, &value, sizeof(uint64_t)) == -1) goto error; written += sizeof(uint64_t); } @@ -390,11 +390,11 @@ error: return -errno; } -static int read_uint(int fd, uint64_t *out, size_t size) +static int read_uint(RFILE *fd, uint64_t *out, size_t size) { uint64_t tmp; - if (read(fd, &tmp, size) == -1) + if (retro_fread(fd, &tmp, size) == -1) return -errno; switch (size) @@ -415,14 +415,14 @@ static int read_uint(int fd, uint64_t *out, size_t size) return 0; } -static int read_int(int fd, int64_t *out, size_t size) +static int read_int(RFILE *fd, int64_t *out, size_t size) { uint8_t tmp8 = 0; uint16_t tmp16; uint32_t tmp32; uint64_t tmp64; - if (read(fd, &tmp64, size) == -1) + if (retro_fread(fd, &tmp64, size) == -1) return -errno; (void)tmp8; @@ -448,7 +448,7 @@ static int read_int(int fd, int64_t *out, size_t size) return 0; } -static int read_buff(int fd, size_t size, char **pbuff, uint64_t *len) +static int read_buff(RFILE *fd, size_t size, char **pbuff, uint64_t *len) { uint64_t tmp_len = 0; @@ -457,7 +457,7 @@ static int read_buff(int fd, size_t size, char **pbuff, uint64_t *len) *pbuff = (char *)calloc(tmp_len + 1, sizeof(char)); - if (read(fd, *pbuff, tmp_len) == -1) + if (retro_fread(fd, *pbuff, tmp_len) == -1) { free(*pbuff); return -errno; @@ -467,7 +467,7 @@ static int read_buff(int fd, size_t size, char **pbuff, uint64_t *len) return 0; } -static int read_map(int fd, uint32_t len, +static int read_map(RFILE *fd, uint32_t len, struct rmsgpack_read_callbacks *callbacks, void *data) { int rv; @@ -488,7 +488,7 @@ static int read_map(int fd, uint32_t len, return 0; } -static int read_array(int fd, uint32_t len, +static int read_array(RFILE *fd, uint32_t len, struct rmsgpack_read_callbacks *callbacks, void *data) { int rv; @@ -507,7 +507,7 @@ static int read_array(int fd, uint32_t len, return 0; } -int rmsgpack_read(int fd, +int rmsgpack_read(RFILE *fd, struct rmsgpack_read_callbacks *callbacks, void *data) { int rv; @@ -517,7 +517,7 @@ int rmsgpack_read(int fd, uint8_t type = 0; char *buff = NULL; - if (read(fd, &type, sizeof(uint8_t)) == -1) + if (retro_fread(fd, &type, sizeof(uint8_t)) == -1) goto error; if (type < MPF_FIXMAP) @@ -542,7 +542,7 @@ int rmsgpack_read(int fd, buff = (char *)calloc(tmp_len + 1, sizeof(char)); if (!buff) return -ENOMEM; - if (read(fd, buff, tmp_len) == -1) + if (retro_fread(fd, buff, tmp_len) == -1) { free(buff); goto error; diff --git a/libretro-db/rmsgpack.h b/libretro-db/rmsgpack.h index 69d60b6145..c802501b82 100644 --- a/libretro-db/rmsgpack.h +++ b/libretro-db/rmsgpack.h @@ -3,6 +3,8 @@ #include +#include + struct rmsgpack_read_callbacks { int (*read_nil )(void *); @@ -15,23 +17,23 @@ struct rmsgpack_read_callbacks int (*read_array_start)(uint32_t, void *); }; -int rmsgpack_write_array_header(int fd, uint32_t size); +int rmsgpack_write_array_header(RFILE *fd, uint32_t size); -int rmsgpack_write_map_header(int fd, uint32_t size); +int rmsgpack_write_map_header(RFILE *fd, uint32_t size); -int rmsgpack_write_string(int fd, const char *s, uint32_t len); +int rmsgpack_write_string(RFILE *fd, const char *s, uint32_t len); -int rmsgpack_write_bin(int fd, const void *s, uint32_t len); +int rmsgpack_write_bin(RFILE *fd, const void *s, uint32_t len); -int rmsgpack_write_nil(int fd); +int rmsgpack_write_nil(RFILE *fd); -int rmsgpack_write_bool(int fd, int value); +int rmsgpack_write_bool(RFILE *fd, int value); -int rmsgpack_write_int(int fd, int64_t value); +int rmsgpack_write_int(RFILE *fd, int64_t value); -int rmsgpack_write_uint(int fd, uint64_t value ); +int rmsgpack_write_uint(RFILE *fd, uint64_t value ); -int rmsgpack_read(int fd, struct rmsgpack_read_callbacks *callbacks, void *data); +int rmsgpack_read(RFILE *fd, struct rmsgpack_read_callbacks *callbacks, void *data); #endif diff --git a/libretro-db/rmsgpack_dom.c b/libretro-db/rmsgpack_dom.c index 11fd05e595..0a9629c862 100644 --- a/libretro-db/rmsgpack_dom.c +++ b/libretro-db/rmsgpack_dom.c @@ -338,7 +338,7 @@ void rmsgpack_dom_value_print(struct rmsgpack_dom_value *obj) printf("]"); } } -int rmsgpack_dom_write(int fd, const struct rmsgpack_dom_value *obj) +int rmsgpack_dom_write(RFILE *fd, const struct rmsgpack_dom_value *obj) { unsigned i; int rv = 0; @@ -388,7 +388,7 @@ int rmsgpack_dom_write(int fd, const struct rmsgpack_dom_value *obj) return written; } -int rmsgpack_dom_read(int fd, struct rmsgpack_dom_value *out) +int rmsgpack_dom_read(RFILE *fd, struct rmsgpack_dom_value *out) { struct dom_reader_state s; int rv = 0; @@ -404,7 +404,7 @@ int rmsgpack_dom_read(int fd, struct rmsgpack_dom_value *out) return rv; } -int rmsgpack_dom_read_into(int fd, ...) +int rmsgpack_dom_read_into(RFILE *fd, ...) { va_list ap; struct rmsgpack_dom_value map; diff --git a/libretro-db/rmsgpack_dom.h b/libretro-db/rmsgpack_dom.h index cfaeb5c617..1773d2e3ef 100644 --- a/libretro-db/rmsgpack_dom.h +++ b/libretro-db/rmsgpack_dom.h @@ -3,6 +3,8 @@ #include +#include + #ifdef __cplusplus extern "C" { #endif @@ -66,11 +68,11 @@ struct rmsgpack_dom_value *rmsgpack_dom_value_map_value( const struct rmsgpack_dom_value *map, const struct rmsgpack_dom_value *key); -int rmsgpack_dom_read(int fd, struct rmsgpack_dom_value *out); +int rmsgpack_dom_read(RFILE *fd, struct rmsgpack_dom_value *out); -int rmsgpack_dom_write(int fd, const struct rmsgpack_dom_value *obj); +int rmsgpack_dom_write(RFILE *fd, const struct rmsgpack_dom_value *obj); -int rmsgpack_dom_read_into(int fd, ...); +int rmsgpack_dom_read_into(RFILE *fd, ...); #ifdef __cplusplus } diff --git a/libretro-db/rmsgpack_test.c b/libretro-db/rmsgpack_test.c index 4fdcfbd4be..b307fe8d88 100644 --- a/libretro-db/rmsgpack_test.c +++ b/libretro-db/rmsgpack_test.c @@ -162,15 +162,16 @@ static struct rmsgpack_read_callbacks stub_callbacks = { int main(void) { - int fd; struct stub_state state; + RFILE *fd = retro_fopen("test.msgpack", RFILE_MODE_READ, 0); state.i = 0; state.stack[0] = 0; - fd = open("test.msgpack", O_RDONLY); + rmsgpack_read(fd, &stub_callbacks, &state); + printf("Test succeeded.\n"); - close(fd); + retro_fclose(fd); return 0; } diff --git a/libretro-db/testlib.c b/libretro-db/testlib.c index 699812d390..bbda2a2e0a 100644 --- a/libretro-db/testlib.c +++ b/libretro-db/testlib.c @@ -13,216 +13,10 @@ #include "libretrodb.h" #include "lua_common.h" -static int create_db (lua_State * L); -static int db_new (lua_State * L); -static int db_close (lua_State * L); -static int db_cursor_open (lua_State * L); -static int db_query (lua_State * L); - -static int cursor_close (lua_State * L); -static int cursor_read (lua_State * L); -static int cursor_iter (lua_State * L); - -static const luaL_Reg testlib[] = { - {"create_db", create_db}, - {"RarchDB", db_new}, - {NULL, NULL} -}; - -static const struct luaL_Reg cursor_mt [] = { - {"__gc", cursor_close}, - {"read", cursor_read}, - {"iter", cursor_iter}, - {NULL, NULL} -}; - -static const struct luaL_Reg libretrodb_mt [] = { - {"__gc", db_close}, - {"list_all", db_cursor_open}, - {"query", db_query}, - {NULL, NULL} -}; - - -LUALIB_API int luaopen_testlib (lua_State * L) -{ - luaL_newmetatable(L, "RarchDB.DB"); - lua_pushstring(L, "__index"); - lua_pushvalue(L, -2); - lua_settable(L, -3); - luaL_openlib(L, NULL, libretrodb_mt, 0); - - luaL_newmetatable(L, "RarchDB.Cursor"); - lua_pushstring(L, "__index"); - lua_pushvalue(L, -2); - lua_settable(L, -3); - luaL_openlib(L, NULL, cursor_mt, 0); - - luaL_register(L, "testlib", testlib); - return 1; -} - -static libretrodb_cursor * checkcursor(lua_State * L) -{ - void * ud = luaL_checkudata(L, 1, "RarchDB.Cursor"); - luaL_argcheck(L, ud != NULL, 1, "`RarchDB.Cursor' expected"); - return ud; -} - -static libretrodb * checkdb(lua_State * L) -{ - void * ud = luaL_checkudata(L, 1, "RarchDB.DB"); - luaL_argcheck(L, ud != NULL, 1, "`RarchDB.DB' expected"); - return ud; -} - -static int value_provider(void * ctx, struct rmsgpack_dom_value * out) -{ - int rv; - lua_State * L = ctx; - - lua_getfield(L, LUA_REGISTRYINDEX, "testlib_get_value"); - - if (lua_pcall(L, 0, 1, 0) != 0) - { - printf( - "error running function `get_value': %s\n", - lua_tostring(L, -1) - ); - } - - if (lua_isnil(L, -1)) - rv = 1; - else if (lua_istable(L, -1)) - rv = libretrodb_lua_to_rmsgpack_value(L, -1, out); - else - printf("function `get_value' must return a table or nil\n"); - - lua_pop(L, 1); - return rv; -} - -static int create_db (lua_State * L) -{ - int dst; - const char * db_file; - int rv; - db_file = luaL_checkstring(L, -2); - if (!lua_isfunction(L, -1)) - { - lua_pushstring(L, "second argument must be a function"); - lua_error(L); - } - lua_setfield(L, LUA_REGISTRYINDEX, "testlib_get_value"); - - dst = open(db_file, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); - if (dst == -1) - { - lua_pushstring(L, "Could not open destination file"); - lua_error(L); - } - - rv = libretrodb_create(dst, &value_provider, L); - close(dst); - return 0; -} - -static int db_new (lua_State * L) -{ - libretrodb_t * db = NULL; - const char * db_file = NULL; - int rv; - db_file = luaL_checkstring(L, -1); - db = lua_newuserdata(L, sizeof(libretrodb_t)); - if ((rv = libretrodb_open(db_file, db)) == 0) - { - luaL_getmetatable(L, "RarchDB.DB"); - lua_setmetatable(L, -2); - lua_pushnil(L); - } - else - { - lua_pop(L, 1); - lua_pushnil(L); - lua_pushstring(L, strerror(-rv)); - } - return 2; -} - -static int db_close (lua_State * L) -{ - libretrodb_t *db = checkdb(L); - libretrodb_close(db); - return 0; -} - -static int db_query (lua_State * L) -{ - int rv; - libretrodb_cursor_t *cursor = NULL; - libretrodb_t *db = checkdb(L); - const char * query = luaL_checkstring(L, -1); - const char * error = NULL; - libretrodb_query_t *q = libretrodb_query_compile( - db, - query, - strlen(query), - &error - ); - if (error) - { - lua_pushnil(L); - lua_pushstring(L, error); - } - else - { - cursor = lua_newuserdata(L, sizeof(libretrodb_t)); - if ((rv = libretrodb_cursor_open(db, cursor, q)) == 0) - { - luaL_getmetatable(L, "RarchDB.Cursor"); - lua_setmetatable(L, -2); - lua_pushnil(L); - } - else - { - lua_pop(L, 1); - lua_pushnil(L); - lua_pushstring(L, strerror(-rv)); - } - libretrodb_query_free(q); - } - return 2; -} -static int db_cursor_open (lua_State * L) -{ - int rv; - libretrodb_cursor_t *cursor = NULL; - libretrodb_t *db = checkdb(L); - cursor = lua_newuserdata(L, sizeof(libretrodb_t)); - if ((rv = libretrodb_cursor_open(db, cursor, NULL)) == 0) - { - luaL_getmetatable(L, "RarchDB.Cursor"); - lua_setmetatable(L, -2); - lua_pushnil(L); - } - else - { - lua_pop(L, 1); - lua_pushnil(L); - lua_pushstring(L, strerror(-rv)); - } - return 2; -} -static int cursor_close (lua_State * L) -{ - libretrodb_cursor_t *cursor = checkcursor(L); - libretrodb_cursor_close(cursor); - return 0; -} - -static void push_rmsgpack_value(lua_State * L, struct rmsgpack_dom_value * value) +static void push_rmsgpack_value(lua_State *L, struct rmsgpack_dom_value *value) { uint32_t i; + switch (value->type) { case RDT_INT: @@ -291,10 +85,167 @@ static void push_rmsgpack_value(lua_State * L, struct rmsgpack_dom_value * value } break; } - } -static int cursor_read (lua_State * L) +static int value_provider(void *ctx, struct rmsgpack_dom_value *out) +{ + int rv; + lua_State *L = ctx; + + lua_getfield(L, LUA_REGISTRYINDEX, "testlib_get_value"); + + if (lua_pcall(L, 0, 1, 0) != 0) + { + printf( + "error running function `get_value': %s\n", + lua_tostring(L, -1) + ); + } + + if (lua_isnil(L, -1)) + rv = 1; + else if (lua_istable(L, -1)) + rv = libretrodb_lua_to_rmsgpack_value(L, -1, out); + else + printf("function `get_value' must return a table or nil\n"); + + lua_pop(L, 1); + return rv; +} + +static int create_db (lua_State *L) +{ + int rv; + RFILE *dst; + const char *db_file = luaL_checkstring(L, -2); + + if (!lua_isfunction(L, -1)) + { + lua_pushstring(L, "second argument must be a function"); + lua_error(L); + } + lua_setfield(L, LUA_REGISTRYINDEX, "testlib_get_value"); + + dst = retro_fopen(db_file, RFILE_MODE_WRITE, -1); + if (!dst) + { + lua_pushstring(L, "Could not open destination file"); + lua_error(L); + } + + rv = libretrodb_create(dst, &value_provider, L); + retro_fclose(dst); + + return 0; +} + +static int db_new (lua_State *L) +{ + libretrodb_t *db = NULL; + const char *db_file = NULL; + int rv; + db_file = luaL_checkstring(L, -1); + db = lua_newuserdata(L, sizeof(libretrodb_t)); + if ((rv = libretrodb_open(db_file, db)) == 0) + { + luaL_getmetatable(L, "RarchDB.DB"); + lua_setmetatable(L, -2); + lua_pushnil(L); + } + else + { + lua_pop(L, 1); + lua_pushnil(L); + lua_pushstring(L, strerror(-rv)); + } + return 2; +} + +static libretrodb *checkdb(lua_State *L) +{ + void *ud = luaL_checkudata(L, 1, "RarchDB.DB"); + luaL_argcheck(L, ud != NULL, 1, "`RarchDB.DB' expected"); + return ud; +} + +static int db_close (lua_State *L) +{ + libretrodb_t *db = checkdb(L); + libretrodb_close(db); + return 0; +} + +static int db_cursor_open (lua_State *L) +{ + int rv; + libretrodb_cursor_t *cursor = NULL; + libretrodb_t *db = checkdb(L); + cursor = lua_newuserdata(L, sizeof(libretrodb_t)); + if ((rv = libretrodb_cursor_open(db, cursor, NULL)) == 0) + { + luaL_getmetatable(L, "RarchDB.Cursor"); + lua_setmetatable(L, -2); + lua_pushnil(L); + } + else + { + lua_pop(L, 1); + lua_pushnil(L); + lua_pushstring(L, strerror(-rv)); + } + return 2; +} + +static int db_query (lua_State *L) +{ + int rv; + libretrodb_cursor_t *cursor = NULL; + libretrodb_t *db = checkdb(L); + const char *query = luaL_checkstring(L, -1); + const char *error = NULL; + libretrodb_query_t *q = libretrodb_query_compile( + db, query, strlen(query), &error); + + if (error) + { + lua_pushnil(L); + lua_pushstring(L, error); + } + else + { + cursor = lua_newuserdata(L, sizeof(libretrodb_t)); + if ((rv = libretrodb_cursor_open(db, cursor, q)) == 0) + { + luaL_getmetatable(L, "RarchDB.Cursor"); + lua_setmetatable(L, -2); + lua_pushnil(L); + } + else + { + lua_pop(L, 1); + lua_pushnil(L); + lua_pushstring(L, strerror(-rv)); + } + libretrodb_query_free(q); + } + return 2; +} + +static libretrodb_cursor *checkcursor(lua_State *L) +{ + void *ud = luaL_checkudata(L, 1, "RarchDB.Cursor"); + luaL_argcheck(L, ud != NULL, 1, "`RarchDB.Cursor' expected"); + return ud; +} + +static int cursor_close (lua_State *L) +{ + libretrodb_cursor_t *cursor = checkcursor(L); + libretrodb_cursor_close(cursor); + return 0; +} + +static int cursor_read (lua_State *L) { libretrodb_cursor_t *cursor = checkcursor(L); struct rmsgpack_dom_value value; @@ -305,10 +256,48 @@ static int cursor_read (lua_State * L) return 1; } -static int cursor_iter (lua_State * L) +static int cursor_iter (lua_State *L) { - libretrodb_cursor_t * cursor = checkcursor(L); + libretrodb_cursor_t *cursor = checkcursor(L); luaL_getmetafield(L, -1, "read"); lua_pushvalue(L, -2); return 2; } + +static const luaL_Reg testlib[] = { + {"create_db", create_db}, + {"RarchDB", db_new}, + {NULL, NULL} +}; + +static const struct luaL_Reg cursor_mt [] = { + {"__gc", cursor_close}, + {"read", cursor_read}, + {"iter", cursor_iter}, + {NULL, NULL} +}; + +static const struct luaL_Reg libretrodb_mt [] = { + {"__gc", db_close}, + {"list_all", db_cursor_open}, + {"query", db_query}, + {NULL, NULL} +}; + +LUALIB_API int luaopen_testlib(lua_State *L) +{ + luaL_newmetatable(L, "RarchDB.DB"); + lua_pushstring(L, "__index"); + lua_pushvalue(L, -2); + lua_settable(L, -3); + luaL_openlib(L, NULL, libretrodb_mt, 0); + + luaL_newmetatable(L, "RarchDB.Cursor"); + lua_pushstring(L, "__index"); + lua_pushvalue(L, -2); + lua_settable(L, -3); + luaL_openlib(L, NULL, cursor_mt, 0); + + luaL_register(L, "testlib", testlib); + return 1; +}