diff --git a/Makefile.common b/Makefile.common index c2fddfc264..4de2aa9497 100644 --- a/Makefile.common +++ b/Makefile.common @@ -173,7 +173,7 @@ OBJ += frontend/frontend.o \ ifeq ($(HAVE_LIBRETRODB), 1) OBJ += libretrodb/bintree.o \ - libretrodb/rarchdb.o \ + libretrodb/libretrodb.o \ libretrodb/query.o \ libretrodb/rmsgpack.o \ libretrodb/rmsgpack_dom.o diff --git a/griffin/griffin.c b/griffin/griffin.c index d4b290aeea..26f02b4965 100644 --- a/griffin/griffin.c +++ b/griffin/griffin.c @@ -810,7 +810,7 @@ XML ============================================================ */ #ifdef HAVE_LIBRETRODB #include "../libretrodb/bintree.c" -#include "../libretrodb/rarchdb.c" +#include "../libretrodb/libretrodb.c" #include "../libretrodb/rmsgpack.c" #include "../libretrodb/rmsgpack_dom.c" #include "../libretrodb/query.c" diff --git a/libretrodb/Makefile b/libretrodb/Makefile index b4fc4247b3..aeeec3f7d0 100644 --- a/libretrodb/Makefile +++ b/libretrodb/Makefile @@ -4,7 +4,7 @@ INCFLAGS = -I. -I../libretro-sdk/include LUA_CONVERTER_OBJ = rmsgpack.o \ rmsgpack_dom.o \ lua_common.o \ - rarchdb.o \ + libretrodb.o \ bintree.o \ query.o \ lua_converter.o \ @@ -13,10 +13,10 @@ LUA_CONVERTER_OBJ = rmsgpack.o \ RARCHDB_TOOL_OBJ = rmsgpack.o \ rmsgpack_dom.o \ - rarchdb_tool.o \ + libretrodb_tool.o \ bintree.o \ query.o \ - rarchdb.o \ + libretrodb.o \ compat_fnmatch.c \ $(NULL) @@ -24,7 +24,7 @@ TESTLIB_C = testlib.c \ lua_common.c \ query.c \ compat_fnmatch.c \ - rarchdb.c \ + libretrodb.c \ bintree.c \ rmsgpack.c \ rmsgpack_dom.c \ @@ -35,7 +35,7 @@ TESTLIB_FLAGS = ${CFLAGS} ${LUA_FLAGS} -shared -fpic .PHONY: all clean check -all: rmsgpack_test rarchdb_tool lua_converter +all: rmsgpack_test libretrodb_tool lua_converter %.o: %.c ${CC} $(INCFLAGS) $< -c ${CFLAGS} -o $@ @@ -43,7 +43,7 @@ all: rmsgpack_test rarchdb_tool lua_converter lua_converter: ${LUA_CONVERTER_OBJ} ${CC} $(INCFLAGS) ${LUA_CONVERTER_OBJ} ${LUA_FLAGS} -o $@ -rarchdb_tool: ${RARCHDB_TOOL_OBJ} +libretrodb_tool: ${RARCHDB_TOOL_OBJ} ${CC} $(INCFLAGS) ${RARCHDB_TOOL_OBJ} -o $@ rmsgpack_test: @@ -56,4 +56,4 @@ check: testlib.so tests.lua lua ./tests.lua clean: - rm -rf *.o rmsgpack_test lua_converter rarchdb_tool testlib.so + rm -rf *.o rmsgpack_test lua_converter libretrodb_tool testlib.so diff --git a/libretrodb/README.md b/libretrodb/README.md index 1150b2d788..a08d9257fa 100644 --- a/libretrodb/README.md +++ b/libretrodb/README.md @@ -1,13 +1,13 @@ -# rarchdb +# libretrodb A small read only database Mainly to be used by retroarch # Usage Files specified later in the chain **will override** earlier ones if the same key exists multiple times. -To list out the content of a db `rarchdb_tool list` -To create an index `rarchdb_tool create-index ` -To find an entry with an index `rarchdb_tool find ` +To list out the content of a db `libretrodb_tool list` +To create an index `libretrodb_tool create-index ` +To find an entry with an index `libretrodb_tool find ` # lua converters In order to write you own converter you must have a lua file that implements the following functions: @@ -54,15 +54,15 @@ dat_converter snes.rdb rom.crc snes1.dat snes2.dat ~~~ # Query examples -Some examples of queries you can use with rarchdbtool: +Some examples of queries you can use with libretrodbtool: 1) Glob pattern matching Usecase : Search for all games starting with 'Street Fighter' in the 'name' field (glob pattern matching) -`rarchdb_tool find "{'name':glob('Street Fighter*')}"` +`libretrodb_tool find "{'name':glob('Street Fighter*')}"` 2) Combined number matching query Usecase: Search for all games released on October 1995. -`rarchdb_tool find "{'releasemonth':10,'releaseyear':1995}"` +`libretrodb_tool find "{'releasemonth':10,'releaseyear':1995}"` diff --git a/libretrodb/dat_converter.c b/libretrodb/dat_converter.c new file mode 100644 index 0000000000..b3b849c2f3 --- /dev/null +++ b/libretrodb/dat_converter.c @@ -0,0 +1,291 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rarchdb.h" +#include "db_parser.h" + +#define MAX_TOKEN 256 + +static char *strndup_(const char *s, size_t n) +{ + char* buff = calloc(n, sizeof(char)); + + if (!buff) + return 0; + + strncpy(buff, s, n); + return buff; +} + +static struct rmsgpack_dom_value *get_map_value(const struct rmsgpack_dom_value *m, char* key) +{ + struct rmsgpack_dom_value v; + + v.type = RDT_STRING; + v.string.len = strlen(key); + v.string.buff = key; + return rmsgpack_dom_value_map_value(m, &v); +} + +static int load_string(int fd, struct rmsgpack_dom_value *out) +{ + char tok[MAX_TOKEN]; + ssize_t tok_size; + + if ((tok_size = get_token(fd, tok, MAX_TOKEN)) < 0) + return tok_size; + + out->type = RDT_STRING; + out->string.len = tok_size; + out->string.buff = strndup_(tok, tok_size); + return 0; +} + +static int load_uint(int fd, struct rmsgpack_dom_value *out) +{ + char tok[MAX_TOKEN], *c; + ssize_t tok_size; + uint64_t value = 0; + + if ((tok_size = get_token(fd, tok, MAX_TOKEN)) < 0) + return tok_size; + + for (c = tok; c < tok + tok_size; c++) + { + value *= 10; + value += *c - '0'; + } + + out->type = RDT_UINT; + out->uint_ = value; + return 0; +} + +static int load_bin(int fd, struct rmsgpack_dom_value *out) +{ + char tok[MAX_TOKEN]; + ssize_t tok_size; + uint8_t h; + uint8_t l; + int i; + + if ((tok_size = get_token(fd, tok, MAX_TOKEN)) < 0) + return tok_size; + + out->type = RDT_BINARY; + out->binary.len = tok_size / 2; + + for (i = 0; i < tok_size; i += 2) + { + if (tok[i] <= '9') + h = tok[i] - '0'; + else + h = (tok[i] - 'A') + 10; + if (tok[i+1] <= '9') + l = tok[i+1] - '0'; + else + l = (tok[i+1] - 'A') + 10; + tok[i/2] = h * 16 + l; + } + + out->binary.buff = malloc(out->binary.len); + memcpy(out->binary.buff, tok, out->binary.len); + return 0; +} + +static int dat_value_provider(void *ctx, struct rmsgpack_dom_value *out) +{ + int rv, i; + static const int field_count = 22; + int fd = *((int*)ctx); + char* key; + + out->type = RDT_MAP; + out->map.len = field_count; + out->map.items = calloc(field_count, sizeof(struct rmsgpack_dom_pair)); + + if (find_token(fd, "game") < 0) + return 1; + + for (i = 0; i < field_count; i++) + { + if ((rv = load_string(fd, &out->map.items[i].key)) < 0) + goto failed; + + key = out->map.items[i].key.string.buff; + + if (strncmp(key, "name", sizeof("name")) == 0) + { + if ((rv = load_string(fd, &out->map.items[i].value)) < 0) + goto failed; + } + else if (strncmp(key, "description", sizeof("description")) == 0) + { + if ((rv = load_string(fd, &out->map.items[i].value)) < 0) + goto failed; + } + else if (strncmp(key, "users", sizeof("users")) == 0) + { + if ((rv = load_uint(fd, &out->map.items[i].value)) < 0) + goto failed; + } + else if (strncmp(key, "releasemonth", sizeof("releasemonth")) == 0) + { + if ((rv = load_uint(fd, &out->map.items[i].value)) < 0) + goto failed; + } + else if (strncmp(key, "releaseyear", sizeof("releaseyear")) == 0) + { + if ((rv = load_uint(fd, &out->map.items[i].value)) < 0) + goto failed; + } + else if (strncmp(key, "rumble", sizeof("rumble")) == 0) + { + if ((rv = load_uint(fd, &out->map.items[i].value)) < 0) + goto failed; + } + else if (strncmp(key, "analog", sizeof("analog")) == 0) + { + if ((rv = load_uint(fd, &out->map.items[i].value)) < 0) + goto failed; + } + else if (strncmp(key, "serial", sizeof("serial")) == 0) + { + if ((rv = load_string(fd, &out->map.items[i].value)) < 0) + goto failed; + } + else if (strncmp(key, "esrb_rating", sizeof("esrb_rating")) == 0) + { + if ((rv = load_string(fd, &out->map.items[i].value)) < 0) + goto failed; + } + else if (strncmp(key, "elspa_rating", sizeof("elspa_rating")) == 0) + { + if ((rv = load_string(fd, &out->map.items[i].value)) < 0) + goto failed; + } + else if (strncmp(key, "pegi_rating", sizeof("pegi_rating")) == 0) + { + if ((rv = load_string(fd, &out->map.items[i].value)) < 0) + goto failed; + } + else if (strncmp(key, "cero_rating", sizeof("cero_rating")) == 0) + { + if ((rv = load_string(fd, &out->map.items[i].value)) < 0) + goto failed; + } + else if (strncmp(key, "developers", sizeof("developers")) == 0) + { + if ((rv = load_string(fd, &out->map.items[i].value)) < 0) + goto failed; + } + else if (strncmp(key, "publisher", sizeof("publisher")) == 0) + { + if ((rv = load_string(fd, &out->map.items[i].value)) < 0) + goto failed; + } + else if (strncmp(key, "origin", sizeof("origin")) == 0) + { + if ((rv = load_string(fd, &out->map.items[i].value)) < 0) + goto failed; + } + else if (strncmp(key, "rom", sizeof("rom")) == 0) + { + if (find_token(fd, "name") < 0) + goto failed; + + if ((rv = load_string(fd, &out->map.items[i].value)) < 0) + goto failed; + } + else if (strncmp(key, "size", sizeof("size")) == 0) + { + if ((rv = load_uint(fd, &out->map.items[i].value)) < 0) + goto failed; + } + else if (strncmp(key, "sha1", sizeof("sha1")) == 0) + { + if ((rv = load_bin(fd, &out->map.items[i].value)) < 0) + goto failed; + } + else if (strncmp(key, "crc", sizeof("crc")) == 0) + { + if ((rv = load_bin(fd, &out->map.items[i].value)) < 0) + goto failed; + } + else if (strncmp(key, "md5", sizeof("md5")) == 0) + { + if ((rv = load_bin(fd, &out->map.items[i].value)) < 0) + goto failed; + } + else if (strncmp(key, "serial", sizeof("serial")) == 0) + { + if ((rv = load_string(fd, &out->map.items[i].value)) < 0) + goto failed; + } + else if (strncmp(key, ")", sizeof(")")) == 0) + { + rmsgpack_dom_value_free(&out->map.items[i].key); + out->map.len = i; + printf("Couldn't find all fields for item\n"); + break; + } + else + { + rmsgpack_dom_value_free(&out->map.items[i].key); + i--; + } + } + printf("Inserting '%s' (%02X%02X%02X%02X)...\n", + get_map_value(out, "name")->string.buff, + (unsigned char)get_map_value(out, "crc")->binary.buff[0], + (unsigned char)get_map_value(out, "crc")->binary.buff[1], + (unsigned char)get_map_value(out, "crc")->binary.buff[2], + (unsigned char)get_map_value(out, "crc")->binary.buff[3] + ); + return 0; + +failed: + rmsgpack_dom_value_free(out); + out->type = RDT_NULL; + return rv; +} + +int main(int argc, char **argv) +{ + int rv = 0; + int src = -1; + int dst = -1; + if (argc != 3) + printf("Usage: %s \n", argv[0]); + + src = open(argv[1], O_RDONLY); + if (src == -1) + { + printf("Could not open source file '%s': %s\n", argv[1], strerror(errno)); + rv = errno; + goto clean; + } + + dst = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); + if (dst == -1) + { + printf("Could not open destination file '%s': %s\n", argv[1], strerror(errno)); + rv = errno; + goto clean; + } + + rv = rarchdb_create(dst, &dat_value_provider, &src); + +clean: + if (src != -1) + close(src); + if (dst != -1) + close(dst); + return rv; +} diff --git a/libretrodb/db_parser.c b/libretrodb/db_parser.c new file mode 100644 index 0000000000..4da31a4426 --- /dev/null +++ b/libretrodb/db_parser.c @@ -0,0 +1,80 @@ +#include "db_parser.h" + +#include +#include +#include + +ssize_t get_token(int fd, char *token, size_t max_len) +{ + char *c = token; + int rv; + ssize_t len = 0; + int in_string = 0; + + while (1) + { + rv = read(fd, c, 1); + if (rv == 0) + return 0; + else if (rv < 1) + { + switch (errno) + { + case EINTR: + case EAGAIN: + continue; + default: + return -errno; + } + } + + switch (*c) + { + case ' ': + case '\t': + case '\r': + case '\n': + if (c == token) + continue; + + if (!in_string) + { + *c = '\0'; + return len; + } + break; + case '\"': + if (c == token) + { + in_string = 1; + continue; + } + + *c = '\0'; + return len; + } + + len++; + c++; + if (len == (ssize_t)max_len) + { + *c = '\0'; + return len; + } + } +} + +int find_token(int fd, const char *token) +{ + int tmp_len = strlen(token); + char *tmp_token = (char*)calloc(tmp_len, 1); + if (!tmp_token) + return -1; + while (strncmp(tmp_token, token, tmp_len) != 0) + { + if (get_token(fd, tmp_token, tmp_len) <= 0) + return -1; + } + + return 0; +} diff --git a/libretrodb/rarchdb.c b/libretrodb/libretrodb.c similarity index 74% rename from libretrodb/rarchdb.c rename to libretrodb/libretrodb.c index 3cca39a863..c510d634ec 100644 --- a/libretrodb/rarchdb.c +++ b/libretrodb/libretrodb.c @@ -1,4 +1,4 @@ -#include "rarchdb.h" +#include "libretrodb.h" #include #ifdef _WIN32 @@ -17,43 +17,26 @@ #include "rmsgpack_dom.h" #include "rmsgpack.h" #include "bintree.h" -#include "rarchdb_endian.h" +#include "libretrodb_endian.h" #include "query.h" -#define MAGIC_NUMBER "RARCHDB" - -struct rarchdb_header { - char magic_number[sizeof(MAGIC_NUMBER)-1]; - uint64_t metadata_offset; -}; - -struct rarchdb_metadata { - uint64_t count; -}; - -struct rarchdb_index { - char name[50]; - uint64_t key_size; - uint64_t next; -}; - struct node_iter_ctx { - struct rarchdb * db; - struct rarchdb_index * idx; + libretrodb_t *db; + libretrodb_index_t *idx; }; static struct rmsgpack_dom_value sentinal; -static int rarchdb_read_metadata( +static int libretrodb_read_metadata( int fd, - struct rarchdb_metadata * md + libretrodb_metadata_t *md ){ return rmsgpack_dom_read_into(fd, "count", &md->count, NULL); } -static int rarchdb_write_metadata( +static int libretrodb_write_metadata( int fd, - struct rarchdb_metadata * md + libretrodb_metadata_t *md ){ rmsgpack_write_map_header(fd, 1); rmsgpack_write_string(fd, "count", strlen("count")); @@ -93,24 +76,26 @@ static int validate_document(const struct rmsgpack_dom_value * doc) { return rv; } -int rarchdb_create( +int libretrodb_create( int fd, - rarchdb_value_provider value_provider, + libretrodb_value_provider value_provider, void * ctx ){ int rv; - struct rarchdb_metadata md; - off_t root; + off_t root; uint64_t item_count = 0; + libretrodb_metadata_t md; struct rmsgpack_dom_value item = {}; - struct rarchdb_header header = {}; + libretrodb_header_t header = {}; memcpy(header.magic_number, MAGIC_NUMBER, sizeof(MAGIC_NUMBER)-1); root = lseek(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(struct rarchdb_header), 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); + while ((rv = value_provider(ctx, &item)) == 0) { if ((rv = validate_document(&item)) < 0) @@ -130,7 +115,7 @@ int rarchdb_create( header.metadata_offset = httobe64(lseek(fd, 0, SEEK_CUR)); md.count = item_count; - rarchdb_write_metadata(fd, &md); + libretrodb_write_metadata(fd, &md); lseek(fd, root, SEEK_SET); write(fd, &header, sizeof(header)); clean: @@ -138,10 +123,9 @@ clean: return rv; } -static int rarchdb_read_index_header( - int fd, - struct rarchdb_index * idx -){ +static int libretrodb_read_index_header( + int fd, libretrodb_index_t *idx) +{ uint64_t name_len = 50; return rmsgpack_dom_read_into( fd, @@ -152,10 +136,9 @@ static int rarchdb_read_index_header( ); } -static void rarchdb_write_index_header( - int fd, - struct rarchdb_index * idx -){ +static void libretrodb_write_index_header( + int fd, libretrodb_index_t * idx) +{ rmsgpack_write_map_header(fd, 3); rmsgpack_write_string(fd, "name", strlen("name")); rmsgpack_write_string(fd, idx->name, strlen(idx->name)); @@ -165,20 +148,22 @@ static void rarchdb_write_index_header( rmsgpack_write_uint(fd, idx->next); } -void rarchdb_close(struct rarchdb * db) +void libretrodb_close(libretrodb_t * db) { close(db->fd); db->fd = -1; } -int rarchdb_open( +int libretrodb_open( const char * path, - struct rarchdb * db -){ - struct rarchdb_header header; - struct rarchdb_metadata md; + libretrodb_t * db +) +{ + libretrodb_header_t header; + libretrodb_metadata_t md; int rv; int fd = open(path, O_RDWR); + if (fd == -1) return -errno; @@ -195,7 +180,7 @@ int rarchdb_open( header.metadata_offset = betoht64(header.metadata_offset); lseek(fd, header.metadata_offset, SEEK_SET); - if (rarchdb_read_metadata(fd, &md) < 0) { + if (libretrodb_read_metadata(fd, &md) < 0) { rv = -EINVAL; goto error; } @@ -208,19 +193,22 @@ error: return rv; } -static int rarchdb_find_index( - struct rarchdb * db, - const char * index_name, - struct rarchdb_index * idx +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); - while (offset < eof) { - rarchdb_read_index_header(db->fd, idx); - if (strncmp(index_name, idx->name, strlen(idx->name)) == 0) - return 0; - offset = lseek(db->fd, idx->next, SEEK_CUR); - } + + while (offset < eof) + { + libretrodb_read_index_header(db->fd, idx); + if (strncmp(index_name, idx->name, strlen(idx->name)) == 0) + return 0; + offset = lseek(db->fd, idx->next, SEEK_CUR); + } + return -1; } @@ -255,21 +243,20 @@ static int binsearch( return binsearch(current + item_size, item, count - mid, field_size, offset); } -int rarchdb_find_entry( - struct rarchdb * db, - const char * index_name, - const void * key, +int libretrodb_find_entry( + libretrodb_t *db, + const char *index_name, + const void *key, struct rmsgpack_dom_value * out ) { - struct rarchdb_index idx; + libretrodb_index_t idx; int rv; void * buff; uint64_t offset; ssize_t bufflen, nread = 0; - if (rarchdb_find_index(db, index_name, &idx) < 0) { + if (libretrodb_find_index(db, index_name, &idx) < 0) return -1; - } bufflen = idx.next; buff = malloc(bufflen); @@ -302,25 +289,25 @@ int rarchdb_find_entry( } /** - * rarchdb_cursor_reset: + * libretrodb_cursor_reset: * @cursor : Handle to database cursor. * * Resets cursor. * * Returns: ???. **/ -int rarchdb_cursor_reset(struct rarchdb_cursor * cursor) +int libretrodb_cursor_reset(libretrodb_cursor_t *cursor) { cursor->eof = 0; return lseek( cursor->fd, - cursor->db->root + sizeof(struct rarchdb_header), + cursor->db->root + sizeof(libretrodb_header_t), SEEK_SET ); } -int rarchdb_cursor_read_item( - struct rarchdb_cursor * cursor, +int libretrodb_cursor_read_item( + libretrodb_cursor_t *cursor, struct rmsgpack_dom_value * out ) { int rv; @@ -338,7 +325,7 @@ retry: } if (cursor->query) { - if (!rarchdb_query_filter(cursor->query, out)) { + if (!libretrodb_query_filter(cursor->query, out)) { goto retry; } } @@ -347,12 +334,12 @@ retry: } /** - * rarchdb_cursor_close: + * libretrodb_cursor_close: * @cursor : Handle to database cursor. * * Closes cursor and frees up allocated memory. **/ -void rarchdb_cursor_close(struct rarchdb_cursor * cursor) +void libretrodb_cursor_close(libretrodb_cursor_t *cursor) { close(cursor->fd); cursor->is_valid = 0; @@ -360,12 +347,12 @@ void rarchdb_cursor_close(struct rarchdb_cursor * cursor) cursor->eof = 1; cursor->db = NULL; if (cursor->query) - rarchdb_query_free(cursor->query); + libretrodb_query_free(cursor->query); cursor->query = NULL; } /** - * rarchdb_cursor_open: + * libretrodb_cursor_open: * @db : Handle to database. * @cursor : Handle to database cursor. * @q : Query to execute. @@ -374,10 +361,10 @@ void rarchdb_cursor_close(struct rarchdb_cursor * cursor) * * Returns: 0 if successful, otherwise negative. **/ -int rarchdb_cursor_open( - struct rarchdb * db, - struct rarchdb_cursor * cursor, - rarchdb_query * q +int libretrodb_cursor_open( + libretrodb_t *db, + libretrodb_cursor_t *cursor, + libretrodb_query_t *q ) { cursor->fd = dup(db->fd); @@ -387,11 +374,11 @@ int rarchdb_cursor_open( cursor->db = db; cursor->is_valid = 1; - rarchdb_cursor_reset(cursor); + libretrodb_cursor_reset(cursor); cursor->query = q; if (q) - rarchdb_query_inc_ref(q); + libretrodb_query_inc_ref(q); return 0; } @@ -406,41 +393,41 @@ static int node_iter(void * value, void * ctx) return -1; } -static uint64_t rarchdb_tell(struct rarchdb * db) +static uint64_t libretrodb_tell(libretrodb_t *db) { return lseek(db->fd, 0, SEEK_CUR); } -int rarchdb_create_index( - struct rarchdb * db, - const char * name, - const char * field_name +int libretrodb_create_index( + libretrodb_t *db, + const char *name, + const char *field_name ){ int rv; struct node_iter_ctx nictx; struct rmsgpack_dom_value key; - struct rarchdb_index idx; + libretrodb_index_t idx; struct rmsgpack_dom_value item; struct rmsgpack_dom_value * field; + struct bintree tree; + libretrodb_cursor_t cur; void * buff = NULL; uint64_t * buff_u64 = NULL; uint8_t field_size = 0; - struct bintree tree; - uint64_t item_loc = rarchdb_tell(db); uint64_t idx_header_offset; - struct rarchdb_cursor cur; + uint64_t item_loc = libretrodb_tell(db); bintree_new(&tree, node_compare, &field_size); - if (rarchdb_cursor_open(db, &cur, NULL) != 0) { + if (libretrodb_cursor_open(db, &cur, NULL) != 0) { rv = -1; goto clean; } key.type = RDT_STRING; key.string.len = strlen(field_name); - // We know we aren't going to change it + /* We know we aren't going to change it */ key.string.buff = (char *) field_name; - while (rarchdb_cursor_read_item(&cur, &item) == 0) { + while (libretrodb_cursor_read_item(&cur, &item) == 0) { if (item.type != RDT_MAP) { rv = -EINVAL; printf("Only map keys are supported\n"); @@ -491,7 +478,7 @@ int rarchdb_create_index( } buff = NULL; rmsgpack_dom_value_free(&item); - item_loc = rarchdb_tell(db); + item_loc = libretrodb_tell(db); } (void)rv; @@ -503,7 +490,7 @@ int rarchdb_create_index( idx.name[49] = '\0'; idx.key_size = field_size; idx.next = db->count * (field_size + sizeof(uint64_t)); - rarchdb_write_index_header(db->fd, &idx); + libretrodb_write_index_header(db->fd, &idx); nictx.db = db; nictx.idx = &idx; @@ -514,7 +501,7 @@ clean: if (buff) free(buff); if (cur.is_valid) { - rarchdb_cursor_close(&cur); + libretrodb_cursor_close(&cur); } return 0; } diff --git a/libretrodb/libretrodb.h b/libretrodb/libretrodb.h new file mode 100644 index 0000000000..5998ff9df8 --- /dev/null +++ b/libretrodb/libretrodb.h @@ -0,0 +1,129 @@ +#ifndef __LIBRETRODB_H__ +#define __LIBRETRODB_H__ + +#include +#ifdef _WIN32 +#include +#else +#include +#endif +#include "rmsgpack_dom.h" + +#define MAGIC_NUMBER "RARCHDB" + +typedef struct libretrodb_query libretrodb_query_t; + +typedef struct libretrodb +{ + int fd; + uint64_t root; + uint64_t count; + uint64_t first_index_offset; +} libretrodb_t; + +typedef struct libretrodb_index +{ + char name[50]; + uint64_t key_size; + uint64_t next; +} libretrodb_index_t; + +typedef struct libretrodb_metadata +{ + uint64_t count; +} libretrodb_metadata_t; + +typedef struct libretrodb_header +{ + char magic_number[sizeof(MAGIC_NUMBER)-1]; + uint64_t metadata_offset; +} libretrodb_header_t; + +typedef struct libretrodb_cursor +{ + int is_valid; + int fd; + int eof; + libretrodb_query_t * query; + libretrodb_t * db; +} libretrodb_cursor_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 +); + +void libretrodb_close(libretrodb_t * db); + +int libretrodb_open( + const char * path, + libretrodb_t * db +); + +int libretrodb_create_index( + libretrodb_t * db, + const char * name, + const char * field_name +); +int libretrodb_find_entry( + libretrodb_t * db, + const char * index_name, + const void * key, + struct rmsgpack_dom_value * out +); + +/** + * libretrodb_cursor_open: + * @db : Handle to database. + * @cursor : Handle to database cursor. + * @q : Query to execute. + * + * Opens cursor to database based on query @q. + * + * Returns: 0 if successful, otherwise negative. + **/ +int libretrodb_cursor_open( + libretrodb_t *db, + libretrodb_cursor_t *cursor, + libretrodb_query_t *query +); + +/** + * libretrodb_cursor_reset: + * @cursor : Handle to database cursor. + * + * Resets cursor. + * + * Returns: ???. + **/ +int libretrodb_cursor_reset(libretrodb_cursor_t * cursor); + +/** + * libretrodb_cursor_close: + * @cursor : Handle to database cursor. + * + * Closes cursor and frees up allocated memory. + **/ +void libretrodb_cursor_close(libretrodb_cursor_t * cursor); + +void *libretrodb_query_compile( + libretrodb_t * db, + const char * query, + size_t buff_len, + const char ** error +); + +void libretrodb_query_free(void *q); + +int libretrodb_cursor_read_item( + libretrodb_cursor_t * cursor, + struct rmsgpack_dom_value * out +); + +#endif diff --git a/libretrodb/rarchdb_endian.h b/libretrodb/libretrodb_endian.h similarity index 92% rename from libretrodb/rarchdb_endian.h rename to libretrodb/libretrodb_endian.h index 2ae7e98c3c..c9ade88e83 100644 --- a/libretrodb/rarchdb_endian.h +++ b/libretrodb/libretrodb_endian.h @@ -1,5 +1,5 @@ -#ifndef __RARCHDB_MSGPACK_ENDIAN_H -#define __RARCHDB_MSGPACK_ENDIAN_H +#ifndef __LIBRETRODB_MSGPACK_ENDIAN_H +#define __LIBRETRODB_MSGPACK_ENDIAN_H #include #include diff --git a/libretrodb/rarchdb_tool.c b/libretrodb/libretrodb_tool.c similarity index 69% rename from libretrodb/rarchdb_tool.c rename to libretrodb/libretrodb_tool.c index a10a1bbeeb..3ba6b393a2 100644 --- a/libretrodb/rarchdb_tool.c +++ b/libretrodb/libretrodb_tool.c @@ -1,7 +1,7 @@ #include #include -#include "rarchdb.h" +#include "libretrodb.h" #include "rmsgpack_dom.h" int main( @@ -9,9 +9,12 @@ int main( char ** argv ){ int rv; - struct rarchdb db; - struct rarchdb_cursor cur; + libretrodb_t db; + libretrodb_cursor_t cur; + libretrodb_query_t *q; struct rmsgpack_dom_value item; + const char *command, *path, *query_exp, *error; + if (argc < 3) { printf("Usage: %s [extra args...]\n", argv[0]); printf("Available Commands:\n"); @@ -21,14 +24,14 @@ int main( return 1; } - const char * command = argv[2]; - const char * path = argv[1]; + command = argv[2]; + path = argv[1]; - if ((rv = rarchdb_open(path, &db)) != 0) { + if ((rv = libretrodb_open(path, &db)) != 0) { printf("Could not open db file '%s': %s\n", path, strerror(-rv)); return 1; } else if (strcmp(command, "list") == 0) { - if ((rv = rarchdb_cursor_open(&db, &cur, NULL)) != 0) { + if ((rv = libretrodb_cursor_open(&db, &cur, NULL)) != 0) { printf("Could not open cursor: %s\n", strerror(-rv)); return 1; } @@ -37,7 +40,7 @@ int main( printf("Usage: %s list\n", argv[0]); return 1; } - while (rarchdb_cursor_read_item(&cur, &item) == 0) { + while (libretrodb_cursor_read_item(&cur, &item) == 0) { rmsgpack_dom_value_print(&item); printf("\n"); rmsgpack_dom_value_free(&item); @@ -47,20 +50,23 @@ int main( printf("Usage: %s find \n", argv[0]); return 1; } - const char * query_exp = argv[3]; - const char * error = NULL; - rarchdb_query * q = rarchdb_query_compile(&db, query_exp, strlen(query_exp), &error); + + query_exp = argv[3]; + error = NULL; + q = libretrodb_query_compile(&db, query_exp, strlen(query_exp), &error); if (error) { printf("%s\n", error); return 1; } - if ((rv = rarchdb_cursor_open(&db, &cur, q)) != 0) { + if ((rv = libretrodb_cursor_open(&db, &cur, q)) != 0) + { printf("Could not open cursor: %s\n", strerror(-rv)); return 1; } - while (rarchdb_cursor_read_item(&cur, &item) == 0) { + while (libretrodb_cursor_read_item(&cur, &item) == 0) + { rmsgpack_dom_value_print(&item); printf("\n"); rmsgpack_dom_value_free(&item); @@ -76,10 +82,10 @@ int main( index_name = argv[3]; field_name = argv[4]; - rarchdb_create_index(&db, index_name, field_name); + libretrodb_create_index(&db, index_name, field_name); } else { printf("Unkonwn command %s\n", argv[2]); return 1; } - rarchdb_close(&db); + libretrodb_close(&db); } diff --git a/libretrodb/lua_common.c b/libretrodb/lua_common.c index 24be0bcddb..32b0fe1052 100644 --- a/libretrodb/lua_common.c +++ b/libretrodb/lua_common.c @@ -3,7 +3,7 @@ #include #include -int rarchdb_lua_to_rmsgpack_value( +int libretrodb_lua_to_rmsgpack_value( lua_State * L, int index, struct rmsgpack_dom_value * out diff --git a/libretrodb/lua_common.h b/libretrodb/lua_common.h index 1de762f465..b46c1df365 100644 --- a/libretrodb/lua_common.h +++ b/libretrodb/lua_common.h @@ -7,7 +7,7 @@ #include "rmsgpack_dom.h" -int rarchdb_lua_to_rmsgpack_value( +int libretrodb_lua_to_rmsgpack_value( lua_State * L, int index, struct rmsgpack_dom_value * out diff --git a/libretrodb/lua_converter.c b/libretrodb/lua_converter.c index 5659563adf..4b99a391c1 100644 --- a/libretrodb/lua_converter.c +++ b/libretrodb/lua_converter.c @@ -10,7 +10,7 @@ #include #include -#include "rarchdb.h" +#include "libretrodb.h" #include "lua_common.h" int master_key = 1; @@ -62,7 +62,7 @@ static int value_provider( if (lua_isnil(L, -1)) { rv = 1; } else if (lua_istable(L, -1)) { - rv = rarchdb_lua_to_rmsgpack_value(L, -1, out); + rv = libretrodb_lua_to_rmsgpack_value(L, -1, out); } else { printf("function `get_value' must return a table or nil\n"); } @@ -108,7 +108,7 @@ int main( goto clean; } - rv = rarchdb_create(dst, &value_provider, L); + rv = libretrodb_create(dst, &value_provider, L); clean: lua_close(L); if (dst != -1) { diff --git a/libretrodb/query.c b/libretrodb/query.c index fdfa991ec1..2a222c55d5 100644 --- a/libretrodb/query.c +++ b/libretrodb/query.c @@ -8,7 +8,7 @@ #include #include -#include "rarchdb.h" +#include "libretrodb.h" #include "rmsgpack_dom.h" #include @@ -870,31 +870,30 @@ success: } -void rarchdb_query_free(rarchdb_query * q) { +void libretrodb_query_free(void *q) +{ unsigned i; struct query * real_q = (struct query*)q; real_q->ref_count--; - if (real_q->ref_count > 0) { + if (real_q->ref_count > 0) return; - } - for (i = 0; i < real_q->root.argc; i++) { + for (i = 0; i < real_q->root.argc; i++) argument_free(&real_q->root.argv[i]); - } } -rarchdb_query * rarchdb_query_compile( - struct rarchdb * db, +void *libretrodb_query_compile( + libretrodb_t * db, const char * query, size_t buff_len, const char ** error -) { +) +{ struct buffer buff; struct query *q = (struct query*)malloc(sizeof(struct query)); - if (!q) { + if (!q) goto clean; - } memset(q, 0, sizeof(struct query)); q->ref_count = 1; buff.data = query; @@ -914,9 +913,8 @@ rarchdb_query * rarchdb_query_compile( } buff = expect_eof(buff, error); - if (*error) { + if (*error) goto clean; - } if (q->root.func == NULL) { raise_unexpected_eof(buff.offset, error); @@ -924,20 +922,20 @@ rarchdb_query * rarchdb_query_compile( } goto success; clean: - if (q) { - rarchdb_query_free(q); - } + if (q) + libretrodb_query_free(q); success: return q; } -void rarchdb_query_inc_ref(rarchdb_query * q) { +void libretrodb_query_inc_ref(libretrodb_query_t *q) +{ struct query * rq = (struct query*)q; rq->ref_count += 1; } -int rarchdb_query_filter( - rarchdb_query * q, +int libretrodb_query_filter( + libretrodb_query_t * q, struct rmsgpack_dom_value * v ) { struct invocation inv = ((struct query *)q)->root; diff --git a/libretrodb/query.h b/libretrodb/query.h index 6a3351dda8..8f5cd30a49 100644 --- a/libretrodb/query.h +++ b/libretrodb/query.h @@ -1,12 +1,14 @@ -#ifndef __RARCHDB_QUERY_H__ -#define __RARCHDB_QUERY_H__ +#ifndef __LIBRETRODB_QUERY_H__ +#define __LIBRETRODB_QUERY_H__ -#include "rarchdb.h" +#include "libretrodb.h" -void rarchdb_query_inc_ref(rarchdb_query * q); -void rarchdb_query_dec_ref(rarchdb_query * q); -int rarchdb_query_filter( - rarchdb_query * q, +void libretrodb_query_inc_ref(libretrodb_query_t *q); + +void libretrodb_query_dec_ref(libretrodb_query_t *q); + +int libretrodb_query_filter( + libretrodb_query_t *q, struct rmsgpack_dom_value * v ); diff --git a/libretrodb/rarchdb.h b/libretrodb/rarchdb.h deleted file mode 100644 index 021634fdfb..0000000000 --- a/libretrodb/rarchdb.h +++ /dev/null @@ -1,108 +0,0 @@ -#ifndef __RARCHDB_H__ -#define __RARCHDB_H__ - -#include -#ifdef _WIN32 -#include -#else -#include -#endif -#include "rmsgpack_dom.h" - -typedef void rarchdb_query; - -struct rarchdb -{ - int fd; - uint64_t root; - uint64_t count; - uint64_t first_index_offset; -}; - -struct rarchdb_cursor -{ - int is_valid; - int fd; - int eof; - rarchdb_query * query; - struct rarchdb * db; -}; - -typedef int (* rarchdb_value_provider)( - void * ctx, - struct rmsgpack_dom_value * out -); - -int rarchdb_create( - int fd, - rarchdb_value_provider value_provider, - void * ctx -); - -void rarchdb_close(struct rarchdb * db); - -int rarchdb_open( - const char * path, - struct rarchdb * db -); - -int rarchdb_create_index( - struct rarchdb * db, - const char * name, - const char * field_name -); -int rarchdb_find_entry( - struct rarchdb * db, - const char * index_name, - const void * key, - struct rmsgpack_dom_value * out -); - -/** - * rarchdb_cursor_open: - * @db : Handle to database. - * @cursor : Handle to database cursor. - * @q : Query to execute. - * - * Opens cursor to database based on query @q. - * - * Returns: 0 if successful, otherwise negative. - **/ -int rarchdb_cursor_open( - struct rarchdb * db, - struct rarchdb_cursor * cursor, - rarchdb_query * query -); - -/** - * rarchdb_cursor_reset: - * @cursor : Handle to database cursor. - * - * Resets cursor. - * - * Returns: ???. - **/ -int rarchdb_cursor_reset(struct rarchdb_cursor * cursor); - -/** - * rarchdb_cursor_close: - * @cursor : Handle to database cursor. - * - * Closes cursor and frees up allocated memory. - **/ -void rarchdb_cursor_close(struct rarchdb_cursor * cursor); - -rarchdb_query * rarchdb_query_compile( - struct rarchdb * db, - const char * query, - size_t buff_len, - const char ** error -); -void rarchdb_query_free(rarchdb_query * q); - -int rarchdb_cursor_read_item( - struct rarchdb_cursor * cursor, - struct rmsgpack_dom_value * out -); - -#endif diff --git a/libretrodb/rmsgpack.c b/libretrodb/rmsgpack.c index b609da6082..d8fdac975f 100644 --- a/libretrodb/rmsgpack.c +++ b/libretrodb/rmsgpack.c @@ -21,7 +21,7 @@ #include #include -#include "rarchdb_endian.h" +#include "libretrodb_endian.h" static const uint8_t MPF_FIXMAP = 0x80; static const uint8_t MPF_MAP16 = 0xde; diff --git a/libretrodb/testlib.c b/libretrodb/testlib.c index 7b593402ff..7a65756f98 100644 --- a/libretrodb/testlib.c +++ b/libretrodb/testlib.c @@ -10,7 +10,7 @@ #include "lua.h" #include "lauxlib.h" -#include "rarchdb.h" +#include "libretrodb.h" #include "lua_common.h" static int create_db (lua_State * L); @@ -36,7 +36,7 @@ static const struct luaL_Reg cursor_mt [] = { {NULL, NULL} }; -static const struct luaL_Reg rarchdb_mt [] = { +static const struct luaL_Reg libretrodb_mt [] = { {"__gc", db_close}, {"list_all", db_cursor_open}, {"query", db_query}, @@ -49,7 +49,7 @@ LUALIB_API int luaopen_testlib (lua_State * L) { lua_pushstring(L, "__index"); lua_pushvalue(L, -2); lua_settable(L, -3); - luaL_openlib(L, NULL, rarchdb_mt, 0); + luaL_openlib(L, NULL, libretrodb_mt, 0); luaL_newmetatable(L, "RarchDB.Cursor"); lua_pushstring(L, "__index"); @@ -61,13 +61,13 @@ LUALIB_API int luaopen_testlib (lua_State * L) { return 1; } -static struct rarchdb_cursor * checkcursor(lua_State * L) { +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 struct rarchdb * checkdb(lua_State * L) { +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; @@ -92,7 +92,7 @@ static int value_provider( if (lua_isnil(L, -1)) { rv = 1; } else if (lua_istable(L, -1)) { - rv = rarchdb_lua_to_rmsgpack_value(L, -1, out); + rv = libretrodb_lua_to_rmsgpack_value(L, -1, out); } else { printf("function `get_value' must return a table or nil\n"); } @@ -117,18 +117,18 @@ static int create_db (lua_State * L) { lua_error(L); } - rv = rarchdb_create(dst, &value_provider, L); + rv = libretrodb_create(dst, &value_provider, L); close(dst); return 0; } static int db_new (lua_State * L) { - struct rarchdb * db = NULL; + libretrodb_t * db = NULL; const char * db_file = NULL; int rv; db_file = luaL_checkstring(L, -1); - db = lua_newuserdata(L, sizeof(struct rarchdb)); - if ((rv = rarchdb_open(db_file, db)) == 0) { + 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); @@ -141,18 +141,18 @@ static int db_new (lua_State * L) { } static int db_close (lua_State * L) { - struct rarchdb * db = checkdb(L); - rarchdb_close(db); + libretrodb_t *db = checkdb(L); + libretrodb_close(db); return 0; } static int db_query (lua_State * L) { int rv; - struct rarchdb_cursor * cursor = NULL; - struct rarchdb * db = checkdb(L); + libretrodb_cursor_t *cursor = NULL; + libretrodb_t *db = checkdb(L); const char * query = luaL_checkstring(L, -1); const char * error = NULL; - rarchdb_query * q = rarchdb_query_compile( + libretrodb_query_t *q = libretrodb_query_compile( db, query, strlen(query), @@ -162,8 +162,8 @@ static int db_query (lua_State * L) { lua_pushnil(L); lua_pushstring(L, error); } else { - cursor = lua_newuserdata(L, sizeof(struct rarchdb)); - if ((rv = rarchdb_cursor_open(db, cursor, q)) == 0) { + 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); @@ -172,16 +172,16 @@ static int db_query (lua_State * L) { lua_pushnil(L); lua_pushstring(L, strerror(-rv)); } - rarchdb_query_free(q); + libretrodb_query_free(q); } return 2; } static int db_cursor_open (lua_State * L) { int rv; - struct rarchdb_cursor * cursor = NULL; - struct rarchdb * db = checkdb(L); - cursor = lua_newuserdata(L, sizeof(struct rarchdb)); - if ((rv = rarchdb_cursor_open(db, cursor, NULL)) == 0) { + 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); @@ -193,8 +193,8 @@ static int db_cursor_open (lua_State * L) { return 2; } static int cursor_close (lua_State * L) { - struct rarchdb_cursor * cursor = checkcursor(L); - rarchdb_cursor_close(cursor); + libretrodb_cursor_t *cursor = checkcursor(L); + libretrodb_cursor_close(cursor); return 0; } @@ -272,9 +272,9 @@ static void push_rmsgpack_value( } static int cursor_read (lua_State * L) { - struct rarchdb_cursor * cursor = checkcursor(L); + libretrodb_cursor_t *cursor = checkcursor(L); struct rmsgpack_dom_value value; - if (rarchdb_cursor_read_item(cursor, &value) == 0) { + if (libretrodb_cursor_read_item(cursor, &value) == 0) { push_rmsgpack_value(L, &value); } else { lua_pushnil(L); @@ -283,7 +283,7 @@ static int cursor_read (lua_State * L) { } static int cursor_iter (lua_State * L) { - struct rarchdb_cursor * cursor = checkcursor(L); + libretrodb_cursor_t * cursor = checkcursor(L); luaL_getmetafield(L, -1, "read"); lua_pushvalue(L, -2); return 2; diff --git a/menu/menu_entries_cbs.c b/menu/menu_entries_cbs.c index 8b0d7b02e8..145107f7fc 100644 --- a/menu/menu_entries_cbs.c +++ b/menu/menu_entries_cbs.c @@ -33,7 +33,7 @@ #endif #ifdef HAVE_LIBRETRODB -#include "../libretrodb/rarchdb.h" +#include "../libretrodb/libretrodb.h" #endif #include "../input/input_remapping.h" @@ -1596,8 +1596,8 @@ static int deferred_push_database_manager_list_deferred(void *data, void *userda { #ifdef HAVE_LIBRETRODB int rv; - struct rarchdb db; - struct rarchdb_cursor cur; + libretrodb_t db; + libretrodb_cursor_t cur; struct rmsgpack_dom_value item; #endif unsigned i; @@ -1611,13 +1611,13 @@ static int deferred_push_database_manager_list_deferred(void *data, void *userda menu_list_clear(list); #ifdef HAVE_LIBRETRODB - if ((rv = rarchdb_open(path, &db)) != 0) + if ((rv = libretrodb_open(path, &db)) != 0) return -1; - if ((rv = rarchdb_cursor_open(&db, &cur, NULL)) != 0) + if ((rv = libretrodb_cursor_open(&db, &cur, NULL)) != 0) return -1; - while (rarchdb_cursor_read_item(&cur, &item) == 0) + while (libretrodb_cursor_read_item(&cur, &item) == 0) { if (item.type != RDT_MAP) continue; @@ -1636,8 +1636,8 @@ static int deferred_push_database_manager_list_deferred(void *data, void *userda } } - rarchdb_cursor_close(&cur); - rarchdb_close(&db); + libretrodb_cursor_close(&cur); + libretrodb_close(&db); #endif menu_list_sort_on_alt(list); driver.menu->scroll_indices_size = 0;