From b32b17f4aef714b277290a01c73fc93a6c0e3634 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Thu, 17 Sep 2015 06:12:57 +0200 Subject: [PATCH] Revert to last working version of libretro-db --- libretro-db/libretrodb.c | 382 +++++++++++++++++----------------- libretro-db/libretrodb.h | 7 +- libretro-db/libretrodb_tool.c | 6 +- libretro-db/lua_common.c | 172 ++++++++------- libretro-db/lua_converter.c | 148 +++++++------ libretro-db/query.c | 363 ++++++++++++++------------------ libretro-db/rmsgpack.c | 202 +++++++++--------- libretro-db/rmsgpack.h | 19 +- libretro-db/rmsgpack_dom.c | 334 +++++++++++++---------------- libretro-db/rmsgpack_dom.h | 25 +-- libretro-db/rmsgpack_test.c | 37 +++- 11 files changed, 807 insertions(+), 888 deletions(-) diff --git a/libretro-db/libretrodb.c b/libretro-db/libretrodb.c index c36bbf2e2f..5651e2bbba 100644 --- a/libretro-db/libretrodb.c +++ b/libretro-db/libretrodb.c @@ -22,52 +22,46 @@ struct node_iter_ctx { - libretrodb_t *db; - libretrodb_index_t *idx; + libretrodb_t *db; + libretrodb_index_t *idx; }; static struct rmsgpack_dom_value sentinal; -static INLINE off_t flseek(FILE *fp, int offset, int whence) +static int libretrodb_read_metadata(int fd, libretrodb_metadata_t *md) { - if (fseek(fp, offset, whence) != 0) - return (off_t)-1; - return (off_t)ftell(fp); + return rmsgpack_dom_read_into(fd, "count", &md->count, NULL); } -static int libretrodb_read_metadata(FILE *fp, libretrodb_metadata_t *md) +static int libretrodb_write_metadata(int fd, libretrodb_metadata_t *md) { - return rmsgpack_dom_read_into(fp, "count", &md->count, NULL); -} - -static int libretrodb_write_metadata(FILE *fp, libretrodb_metadata_t *md) -{ - rmsgpack_write_map_header(fp, 1); - rmsgpack_write_string(fp, "count", strlen("count")); - return rmsgpack_write_uint(fp, md->count); + rmsgpack_write_map_header(fd, 1); + rmsgpack_write_string(fd, "count", strlen("count")); + return rmsgpack_write_uint(fd, md->count); } static int validate_document(const struct rmsgpack_dom_value * doc) { unsigned i; - struct rmsgpack_dom_value key, value; + struct rmsgpack_dom_value key; + struct rmsgpack_dom_value value; int rv = 0; if (doc->type != RDT_MAP) return -EINVAL; - for (i = 0; i < doc->val.map.len; i++) + for (i = 0; i < doc->map.len; i++) { - key = doc->val.map.items[i].key; - value = doc->val.map.items[i].value; + key = doc->map.items[i].key; + value = doc->map.items[i].value; if (key.type != RDT_STRING) return -EINVAL; - if (key.val.string.len <= 0) + if (key.string.len <= 0) return -EINVAL; - if (key.val.string.buff[0] == '$') + if (key.string.buff[0] == '$') return -EINVAL; if (value.type != RDT_MAP) @@ -80,95 +74,91 @@ static int validate_document(const struct rmsgpack_dom_value * doc) return rv; } -int libretrodb_create(FILE *fp, libretrodb_value_provider value_provider, - void * ctx) +int libretrodb_create(int fd, libretrodb_value_provider value_provider, + void * ctx) { int rv; off_t root; libretrodb_metadata_t md; - struct rmsgpack_dom_value item; - uint64_t item_count = 0; - libretrodb_header_t header = {{0}}; + uint64_t item_count = 0; + struct rmsgpack_dom_value item = {}; + libretrodb_header_t header = {}; memcpy(header.magic_number, MAGIC_NUMBER, sizeof(MAGIC_NUMBER)-1); - root = flseek(fp, 0, SEEK_CUR); + root = lseek(fd, 0, SEEK_CUR); /* We write the header in the end because we need to know the size of * the db first */ - flseek(fp, sizeof(libretrodb_header_t), SEEK_CUR); + lseek(fd, sizeof(libretrodb_header_t), SEEK_CUR); while ((rv = value_provider(ctx, &item)) == 0) { if ((rv = validate_document(&item)) < 0) - goto error; + goto clean; - if ((rv = rmsgpack_dom_write(fp, &item)) < 0) - goto error; + if ((rv = rmsgpack_dom_write(fd, &item)) < 0) + goto clean; item_count++; } if (rv < 0) - goto error; + goto clean; - if ((rv = rmsgpack_dom_write(fp, &sentinal)) < 0) - goto error; + if ((rv = rmsgpack_dom_write(fd, &sentinal)) < 0) + goto clean; - header.metadata_offset = httobe64(flseek(fp, 0, SEEK_CUR)); + header.metadata_offset = httobe64(lseek(fd, 0, SEEK_CUR)); md.count = item_count; - libretrodb_write_metadata(fp, &md); - flseek(fp, root, SEEK_SET); - fwrite(&header, 1, sizeof(header), fp); - -error: + libretrodb_write_metadata(fd, &md); + lseek(fd, root, SEEK_SET); + write(fd, &header, sizeof(header)); +clean: rmsgpack_dom_value_free(&item); return rv; } -static int libretrodb_read_index_header(FILE *fp, libretrodb_index_t *idx) +static int libretrodb_read_index_header(int fd, libretrodb_index_t *idx) { uint64_t name_len = 50; - return rmsgpack_dom_read_into(fp, + return rmsgpack_dom_read_into(fd, "name", idx->name, &name_len, "key_size", &idx->key_size, "next", &idx->next, NULL); } -static void libretrodb_write_index_header(FILE *fp, libretrodb_index_t * idx) +static void libretrodb_write_index_header(int fd, libretrodb_index_t * idx) { - rmsgpack_write_map_header(fp, 3); - rmsgpack_write_string(fp, "name", strlen("name")); - rmsgpack_write_string(fp, idx->name, strlen(idx->name)); - rmsgpack_write_string(fp, "key_size", strlen("key_size")); - rmsgpack_write_uint(fp, idx->key_size); - rmsgpack_write_string(fp, "next", strlen("next")); - rmsgpack_write_uint(fp, idx->next); + rmsgpack_write_map_header(fd, 3); + rmsgpack_write_string(fd, "name", strlen("name")); + rmsgpack_write_string(fd, idx->name, strlen(idx->name)); + rmsgpack_write_string(fd, "key_size", strlen("key_size")); + rmsgpack_write_uint(fd, idx->key_size); + rmsgpack_write_string(fd, "next", strlen("next")); + rmsgpack_write_uint(fd, idx->next); } void libretrodb_close(libretrodb_t *db) { - if (!db) - return; - - fclose(db->fp); - db->fp = NULL; + close(db->fd); + db->fd = -1; } int libretrodb_open(const char *path, libretrodb_t *db) { - int rv; libretrodb_header_t header; libretrodb_metadata_t md; - FILE *fp = fopen(path, "rb"); + int rv; + int fd = open(path, O_RDWR); - if (fp == NULL) + if (fd == -1) return -errno; strcpy(db->path, path); - db->root = flseek(fp, 0, SEEK_CUR); + db->root = lseek(fd, 0, SEEK_CUR); - if ((rv = fread(&header, 1, sizeof(header), fp)) != sizeof(header)) + if ((rv = read(fd, &header, sizeof(header))) == -1) { rv = -errno; goto error; @@ -181,37 +171,37 @@ int libretrodb_open(const char *path, libretrodb_t *db) } header.metadata_offset = betoht64(header.metadata_offset); - flseek(fp, (int)header.metadata_offset, SEEK_SET); + lseek(fd, header.metadata_offset, SEEK_SET); - if (libretrodb_read_metadata(fp, &md) < 0) + if (libretrodb_read_metadata(fd, &md) < 0) { rv = -EINVAL; goto error; } - db->count = md.count; - db->first_index_offset = flseek(fp, 0, SEEK_CUR); - db->fp = fp; + db->count = md.count; + db->first_index_offset = lseek(fd, 0, SEEK_CUR); + db->fd = fd; return 0; error: - fclose(fp); + close(fd); return rv; } static int libretrodb_find_index(libretrodb_t *db, const char *index_name, libretrodb_index_t *idx) { - off_t eof = flseek(db->fp, 0, SEEK_END); - off_t offset = flseek(db->fp, (int)db->first_index_offset, SEEK_SET); + off_t eof = lseek(db->fd, 0, SEEK_END); + off_t offset = lseek(db->fd, db->first_index_offset, SEEK_SET); while (offset < eof) { - libretrodb_read_index_header(db->fp, idx); + libretrodb_read_index_header(db->fd, idx); if (strncmp(index_name, idx->name, strlen(idx->name)) == 0) return 0; - offset = flseek(db->fp, (int)idx->next, SEEK_CUR); + offset = lseek(db->fd, idx->next, SEEK_CUR); } return -1; @@ -247,27 +237,27 @@ static int binsearch(const void * buff, const void * item, } int libretrodb_find_entry(libretrodb_t *db, const char *index_name, - const void *key, struct rmsgpack_dom_value *out) + const void *key, struct rmsgpack_dom_value *out) { libretrodb_index_t idx; int rv; + void * buff; uint64_t offset; - void *buff = NULL; ssize_t bufflen, nread = 0; if (libretrodb_find_index(db, index_name, &idx) < 0) return -1; bufflen = idx.next; - buff = malloc(bufflen); + buff = malloc(bufflen); if (!buff) return -ENOMEM; while (nread < bufflen) { - void *buff_ = (uint64_t *)buff + nread; - rv = fread(buff_, 1, bufflen - nread, db->fp); + void * buff_ = (uint64_t *)buff + nread; + rv = read(db->fd, buff_, bufflen - nread); if (rv <= 0) { @@ -277,13 +267,18 @@ int libretrodb_find_entry(libretrodb_t *db, const char *index_name, nread += rv; } - rv = binsearch(buff, key, db->count, (uint8_t)idx.key_size, &offset); + rv = binsearch(buff, key, db->count, idx.key_size, &offset); free(buff); if (rv == 0) - flseek(db->fp, (int)offset, SEEK_SET); + lseek(db->fd, offset, SEEK_SET); - return rmsgpack_dom_read(db->fp, out); + rv = rmsgpack_dom_read(db->fd, out); + + if (rv < 0) + return rv; + + return rv; } /** @@ -296,9 +291,9 @@ int libretrodb_find_entry(libretrodb_t *db, const char *index_name, **/ int libretrodb_cursor_reset(libretrodb_cursor_t *cursor) { - cursor->eof = 0; - return flseek(cursor->fp, - (int)cursor->db->root + sizeof(libretrodb_header_t), + cursor->eof = 0; + return lseek(cursor->fd, + cursor->db->root + sizeof(libretrodb_header_t), SEEK_SET); } @@ -311,7 +306,7 @@ int libretrodb_cursor_read_item(libretrodb_cursor_t *cursor, return EOF; retry: - rv = rmsgpack_dom_read(cursor->fp, out); + rv = rmsgpack_dom_read(cursor->fd, out); if (rv < 0) return rv; @@ -324,10 +319,7 @@ retry: if (cursor->query) { if (!libretrodb_query_filter(cursor->query, out)) - { - rmsgpack_dom_value_free(out); goto retry; - } } return 0; @@ -344,16 +336,16 @@ void libretrodb_cursor_close(libretrodb_cursor_t *cursor) if (!cursor) return; - fclose(cursor->fp); + close(cursor->fd); + cursor->is_valid = 0; + cursor->fd = -1; + cursor->eof = 1; + cursor->db = NULL; - if (cursor->query) - libretrodb_query_free(cursor->query); + if (cursor->query) + libretrodb_query_free(cursor->query); - cursor->is_valid = 0; - cursor->fp = NULL; - cursor->eof = 1; - cursor->db = NULL; - cursor->query = NULL; + cursor->query = NULL; } /** @@ -369,17 +361,15 @@ void libretrodb_cursor_close(libretrodb_cursor_t *cursor) int libretrodb_cursor_open(libretrodb_t *db, libretrodb_cursor_t *cursor, libretrodb_query_t *q) { - cursor->fp = fopen(db->path, "rb"); + cursor->fd = dup(db->fd); - if (cursor->fp == NULL) + if (cursor->fd == -1) return -errno; - cursor->db = db; + cursor->db = db; cursor->is_valid = 1; - libretrodb_cursor_reset(cursor); - - cursor->query = q; + cursor->query = q; if (q) libretrodb_query_inc_ref(q); @@ -389,124 +379,138 @@ int libretrodb_cursor_open(libretrodb_t *db, libretrodb_cursor_t *cursor, static int node_iter(void * value, void * ctx) { - struct node_iter_ctx *nictx = (struct node_iter_ctx*)ctx; - size_t size = nictx->idx->key_size + sizeof(uint64_t); + struct node_iter_ctx *nictx = (struct node_iter_ctx*)ctx; - if (fwrite(value, 1, size, nictx->db->fp) == size) - return 0; + if (write(nictx->db->fd, value, + nictx->idx->key_size + sizeof(uint64_t)) > 0) + return 0; - return -1; + return -1; } static uint64_t libretrodb_tell(libretrodb_t *db) { - return (uint64_t)ftell(db->fp); + return lseek(db->fd, 0, SEEK_CUR); } int libretrodb_create_index(libretrodb_t *db, const char *name, const char *field_name) { - struct node_iter_ctx nictx; - struct rmsgpack_dom_value key; - libretrodb_index_t idx; - struct rmsgpack_dom_value item; - struct rmsgpack_dom_value *field; - struct bintree tree; - libretrodb_cursor_t cur = {0}; - void *buff = NULL; - uint64_t *buff_u64 = NULL; - uint64_t idx_header_offset = 0; - uint8_t field_size = 0; - uint64_t item_loc = libretrodb_tell(db); + int rv; + struct node_iter_ctx nictx; + struct rmsgpack_dom_value key; + libretrodb_index_t idx; + struct rmsgpack_dom_value item; + struct rmsgpack_dom_value * field; + struct bintree tree; + libretrodb_cursor_t cur; + uint64_t idx_header_offset; + void * buff = NULL; + uint64_t * buff_u64 = NULL; + uint8_t field_size = 0; + uint64_t item_loc = libretrodb_tell(db); - bintree_new(&tree, node_compare, &field_size); + bintree_new(&tree, node_compare, &field_size); - if (libretrodb_cursor_open(db, &cur, NULL) != 0) - goto error; - - key.type = RDT_STRING; - key.val.string.len = strlen(field_name); - - /* We know we aren't going to change it */ - key.val.string.buff = (char*)field_name; - - while (libretrodb_cursor_read_item(&cur, &item) == 0) + if (libretrodb_cursor_open(db, &cur, NULL) != 0) { - if (item.type != RDT_MAP) + rv = -1; + goto clean; + } + + key.type = RDT_STRING; + key.string.len = strlen(field_name); + + /* We know we aren't going to change it */ + key.string.buff = (char *) field_name; + + while (libretrodb_cursor_read_item(&cur, &item) == 0) + { + if (item.type != RDT_MAP) { - printf("Only map keys are supported\n"); - goto error; - } + rv = -EINVAL; + printf("Only map keys are supported\n"); + goto clean; + } - field = rmsgpack_dom_value_map_value(&item, &key); + field = rmsgpack_dom_value_map_value(&item, &key); - if (!field) + if (!field) { - printf("field not found in item\n"); - goto error; - } + rv = -EINVAL; + printf("field not found in item\n"); + goto clean; + } - if (field->type != RDT_BINARY) + if (field->type != RDT_BINARY) { - printf("field is not binary\n"); - goto error; - } + rv = -EINVAL; + printf("field is not binary\n"); + goto clean; + } - if (field->val.binary.len == 0) + if (field->binary.len == 0) { - printf("field is empty\n"); - goto error; - } + rv = -EINVAL; + printf("field is empty\n"); + goto clean; + } - if (field_size == 0) - field_size = field->val.binary.len; - else if (field->val.binary.len != field_size) + if (field_size == 0) + field_size = field->binary.len; + else if (field->binary.len != field_size) { - printf("field is not of correct size\n"); - goto error; - } + rv = -EINVAL; + printf("field is not of correct size\n"); + goto clean; + } - buff = malloc(field_size + sizeof(uint64_t)); - if (!buff) - goto error; - - memcpy(buff, field->val.binary.buff, field_size); - - buff_u64 = (uint64_t *)buff + field_size; - - memcpy(buff_u64, &item_loc, sizeof(uint64_t)); - - if (bintree_insert(&tree, buff) != 0) + buff = malloc(field_size + sizeof(uint64_t)); + if (!buff) { - printf("Value is not unique: "); - rmsgpack_dom_value_print(field); - printf("\n"); - goto error; - } - buff = NULL; - rmsgpack_dom_value_free(&item); - item_loc = libretrodb_tell(db); - } + rv = -ENOMEM; + goto clean; + } - idx_header_offset = flseek(db->fp, 0, SEEK_END); - (void)idx_header_offset; - strncpy(idx.name, name, 50); + memcpy(buff, field->binary.buff, field_size); - idx.name[49] = '\0'; - idx.key_size = field_size; - idx.next = db->count * (field_size + sizeof(uint64_t)); - libretrodb_write_index_header(db->fp, &idx); + buff_u64 = (uint64_t *)buff + field_size; - nictx.db = db; - nictx.idx = &idx; - bintree_iterate(&tree, node_iter, &nictx); - bintree_free(&tree); + memcpy(buff_u64, &item_loc, sizeof(uint64_t)); -error: - rmsgpack_dom_value_free(&item); - if (buff) - free(buff); - if (cur.is_valid) - libretrodb_cursor_close(&cur); - return 0; + if (bintree_insert(&tree, buff) != 0) + { + printf("Value is not unique: "); + rmsgpack_dom_value_print(field); + printf("\n"); + rv = -EINVAL; + goto clean; + } + buff = NULL; + rmsgpack_dom_value_free(&item); + item_loc = libretrodb_tell(db); + } + + (void)rv; + (void)idx_header_offset; + + idx_header_offset = lseek(db->fd, 0, SEEK_END); + strncpy(idx.name, name, 50); + + idx.name[49] = '\0'; + idx.key_size = field_size; + idx.next = db->count * (field_size + sizeof(uint64_t)); + libretrodb_write_index_header(db->fd, &idx); + + nictx.db = db; + nictx.idx = &idx; + bintree_iterate(&tree, node_iter, &nictx); + bintree_free(&tree); +clean: + rmsgpack_dom_value_free(&item); + if (buff) + free(buff); + if (cur.is_valid) + libretrodb_cursor_close(&cur); + return 0; } diff --git a/libretro-db/libretrodb.h b/libretro-db/libretrodb.h index d4e0631d24..a9c2b0ce97 100644 --- a/libretro-db/libretrodb.h +++ b/libretro-db/libretrodb.h @@ -1,7 +1,6 @@ #ifndef __LIBRETRODB_H__ #define __LIBRETRODB_H__ -#include #include #ifdef _WIN32 #include @@ -20,7 +19,7 @@ typedef struct libretrodb_query libretrodb_query_t; typedef struct libretrodb { - FILE *fp; + int fd; uint64_t root; uint64_t count; uint64_t first_index_offset; @@ -48,7 +47,7 @@ typedef struct libretrodb_header typedef struct libretrodb_cursor { int is_valid; - FILE *fp; + int fd; int eof; libretrodb_query_t * query; libretrodb_t * db; @@ -57,7 +56,7 @@ typedef struct libretrodb_cursor typedef int (* libretrodb_value_provider)(void * ctx, struct rmsgpack_dom_value * out); -int libretrodb_create(FILE *fp, libretrodb_value_provider value_provider, +int libretrodb_create(int fd, libretrodb_value_provider value_provider, void * ctx); void libretrodb_close(libretrodb_t * db); diff --git a/libretro-db/libretrodb_tool.c b/libretro-db/libretrodb_tool.c index 08ac6be077..4983e29adf 100644 --- a/libretro-db/libretrodb_tool.c +++ b/libretro-db/libretrodb_tool.c @@ -31,7 +31,7 @@ int main(int argc, char ** argv) printf("Could not open db file '%s': %s\n", path, strerror(-rv)); return 1; } - else if (!strcmp(command, "list")) + else if (strcmp(command, "list") == 0) { if ((rv = libretrodb_cursor_open(&db, &cur, NULL)) != 0) { @@ -52,7 +52,7 @@ int main(int argc, char ** argv) rmsgpack_dom_value_free(&item); } } - else if (!strcmp(command, "find")) + else if (strcmp(command, "find") == 0) { if (argc != 4) { @@ -83,7 +83,7 @@ int main(int argc, char ** argv) rmsgpack_dom_value_free(&item); } } - else if (!strcmp(command, "create-index")) + else if (strcmp(command, "create-index") == 0) { const char * index_name, * field_name; diff --git a/libretro-db/lua_common.c b/libretro-db/lua_common.c index 2f28480e59..32b0fe1052 100644 --- a/libretro-db/lua_common.c +++ b/libretro-db/lua_common.c @@ -3,97 +3,91 @@ #include #include -int libretrodb_lua_to_rmsgpack_value(lua_State * L, int index, struct rmsgpack_dom_value * out) -{ - lua_Number tmp_num; - size_t tmp_len; - int i, rv = -1; - const char * tmp_string = NULL; - char * tmp_buff = NULL; - struct rmsgpack_dom_value * tmp_value; - const int key_idx = -2; - const int value_idx = -1; - const int MAX_FIELDS = 100; +int libretrodb_lua_to_rmsgpack_value( + lua_State * L, + int index, + struct rmsgpack_dom_value * out +) { - out->type = RDT_MAP; - out->val.map.len = 0; - out->val.map.items = calloc(MAX_FIELDS, sizeof(struct rmsgpack_dom_pair)); - lua_pushnil(L); + int rv = -1; + int i; + const char * tmp_string = NULL; + char * tmp_buff = NULL; + struct rmsgpack_dom_value * tmp_value; + const int key_idx = -2; + const int value_idx = -1; + const int MAX_FIELDS = 100; + size_t tmp_len; + lua_Number tmp_num; - while (lua_next(L, index - 1) != 0) - { - if (out->val.map.len > MAX_FIELDS) - printf("skipping due to too many keys\n"); - else if (!lua_isstring(L, key_idx)) - printf("skipping non string key\n"); - else if (lua_isnil(L, value_idx)) - { - // Skipping nil value fields to save disk space - } - else - { - i = out->val.map.len; - tmp_buff = strdup(lua_tostring(L, key_idx)); - out->val.map.items[i].key.type = RDT_STRING; - out->val.map.items[i].key.val.string.len = strlen(tmp_buff); - out->val.map.items[i].key.val.string.buff = tmp_buff; + out->type = RDT_MAP; + out->map.len = 0; + out->map.items = calloc(MAX_FIELDS, sizeof(struct rmsgpack_dom_pair)); + lua_pushnil(L); + while (lua_next(L, index - 1) != 0) { + if (out->map.len > MAX_FIELDS) { + printf("skipping due to too many keys\n"); + } else if (!lua_isstring(L, key_idx)) { + printf("skipping non string key\n"); + } else if (lua_isnil(L, value_idx)) { + // Skipping nil value fields to save disk space + } else { + i = out->map.len; + tmp_buff = strdup(lua_tostring(L, key_idx)); + out->map.items[i].key.type = RDT_STRING; + out->map.items[i].key.string.len = strlen(tmp_buff); + out->map.items[i].key.string.buff = tmp_buff; - tmp_value = &out->val.map.items[i].value; - switch (lua_type(L, value_idx)) - { - case LUA_TNUMBER: - tmp_num = lua_tonumber(L, value_idx); - tmp_value->type = RDT_INT; - tmp_value->val.int_ = tmp_num; - break; - case LUA_TBOOLEAN: - tmp_value->type = RDT_BOOL; - tmp_value->val.bool_ = lua_toboolean(L, value_idx); - break; - case LUA_TSTRING: - tmp_buff = strdup(lua_tostring(L, value_idx)); - tmp_value->type = RDT_STRING; - tmp_value->val.string.len = strlen(tmp_buff); - tmp_value->val.string.buff = tmp_buff; - break; - case LUA_TTABLE: - lua_getfield(L, value_idx, "binary"); - if (!lua_isstring(L, -1)) - { - lua_pop(L, 1); - lua_getfield(L, value_idx, "uint"); - if (!lua_isnumber(L, -1)) - { - lua_pop(L, 1); - goto set_nil; - } - else - { - tmp_num = lua_tonumber(L, -1); - tmp_value->type = RDT_UINT; - tmp_value->val.uint_ = tmp_num; - lua_pop(L, 1); - } - } - else - { - tmp_string = lua_tolstring(L, -1, &tmp_len); - tmp_buff = malloc(tmp_len); - memcpy(tmp_buff, tmp_string, tmp_len); - tmp_value->type = RDT_BINARY; - tmp_value->val.binary.len = tmp_len; - tmp_value->val.binary.buff = tmp_buff; - lua_pop(L, 1); - } - break; - default: + tmp_value = &out->map.items[i].value; + switch (lua_type(L, value_idx)) { + case LUA_TNUMBER: + tmp_num = lua_tonumber(L, value_idx); + tmp_value->type = RDT_INT; + tmp_value->int_ = tmp_num; + break; + case LUA_TBOOLEAN: + tmp_value->type = RDT_BOOL; + tmp_value->bool_ = lua_toboolean(L, value_idx); + break; + case LUA_TSTRING: + tmp_buff = strdup(lua_tostring(L, value_idx)); + tmp_value->type = RDT_STRING; + tmp_value->string.len = strlen(tmp_buff); + tmp_value->string.buff = tmp_buff; + break; + case LUA_TTABLE: + lua_getfield(L, value_idx, "binary"); + if (!lua_isstring(L, -1)) { + lua_pop(L, 1); + lua_getfield(L, value_idx, "uint"); + if (!lua_isnumber(L, -1)) { + lua_pop(L, 1); + goto set_nil; + } else { + tmp_num = lua_tonumber(L, -1); + tmp_value->type = RDT_UINT; + tmp_value->uint_ = tmp_num; + lua_pop(L, 1); + } + } else { + tmp_string = lua_tolstring(L, -1, &tmp_len); + tmp_buff = malloc(tmp_len); + memcpy(tmp_buff, tmp_string, tmp_len); + tmp_value->type = RDT_BINARY; + tmp_value->binary.len = tmp_len; + tmp_value->binary.buff = tmp_buff; + lua_pop(L, 1); + } + break; + default: set_nil: - tmp_value->type = RDT_NULL; - } - out->val.map.len++; - } - lua_pop(L, 1); - } - rv = 0; - return rv; + tmp_value->type = RDT_NULL; + } + out->map.len++; + } + lua_pop(L, 1); + } + rv = 0; + return rv; } + diff --git a/libretro-db/lua_converter.c b/libretro-db/lua_converter.c index 4b99a391c1..21c5b0713f 100644 --- a/libretro-db/lua_converter.c +++ b/libretro-db/lua_converter.c @@ -20,100 +20,94 @@ function binary(s) if s ~= nil then return {binary = s} else return nil end end function uint(s) if s ~= nil then return {uint = s} else return nil end end \ "; -static int call_init( - lua_State * L, - int argc, - const char ** argv -) { - int rv = -1; - int i; +static int call_init(lua_State * L, int argc, const char ** argv) +{ + int rv = -1; + int i; - lua_getglobal(L, "init"); - for (i = 0; i < argc; i++) { - lua_pushstring(L, argv[i]); - } + lua_getglobal(L, "init"); + for (i = 0; i < argc; i++) + lua_pushstring(L, argv[i]); - if (lua_pcall(L, argc, 0, 0) != 0) { - printf( - "error running function `init': %s\n", - lua_tostring(L, -1) - ); - } + if (lua_pcall(L, argc, 0, 0) != 0) + { + printf( + "error running function `init': %s\n", + lua_tostring(L, -1) + ); + } - return rv; + return rv; } -static int value_provider( - void * ctx, - struct rmsgpack_dom_value * out -) { - int rv; - lua_State * L = ctx; +static int value_provider(void * ctx, struct rmsgpack_dom_value *out) +{ + int rv; + lua_State * L = ctx; - lua_getglobal(L, "get_value"); + lua_getglobal(L, "get_value"); - if (lua_pcall(L, 0, 1, 0) != 0) { - printf( - "error running function `get_value': %s\n", - lua_tostring(L, -1) - ); - } + 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; + 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; } -int main( - int argc, - char ** argv -){ - const char * db_file; - const char * lua_file; - int dst = -1; - int rv = 0; +int main(int argc, char ** argv) +{ + const char * db_file; + const char * lua_file; + int dst = -1; + int rv = 0; - if (argc < 3) { - printf("usage:\n%s [args ...]\n", argv[0]); - return 1; - } + if (argc < 3) + { + printf("usage:\n%s [args ...]\n", argv[0]); + return 1; + } - db_file = argv[1]; - lua_file = argv[2]; + db_file = argv[1]; + lua_file = argv[2]; - lua_State * L = luaL_newstate(); - luaL_openlibs(L); - luaL_dostring(L, LUA_COMMON); + lua_State * L = luaL_newstate(); + luaL_openlibs(L); + luaL_dostring(L, LUA_COMMON); - if (luaL_dofile(L, lua_file) != 0) { - return 1; - } + if (luaL_dofile(L, lua_file) != 0) + return 1; - call_init(L, argc - 2, (const char **) argv + 2); + 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) { - printf( - "Could not open destination file '%s': %s\n", - db_file, - strerror(errno) - ); - rv = errno; - goto clean; - } + dst = open(db_file, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); + if (dst == -1) + { + printf( + "Could not open destination file '%s': %s\n", + db_file, + strerror(errno) + ); + rv = errno; + goto clean; + } + + rv = libretrodb_create(dst, &value_provider, L); - rv = libretrodb_create(dst, &value_provider, L); clean: - lua_close(L); - if (dst != -1) { - close(dst); - } - return rv; + lua_close(L); + if (dst != -1) + close(dst); + return rv; } diff --git a/libretro-db/query.c b/libretro-db/query.c index 8bf7b3226f..98e36bccf2 100644 --- a/libretro-db/query.c +++ b/libretro-db/query.c @@ -8,32 +8,30 @@ #include #include -#include -#include - #include "libretrodb.h" -#include "query.h" + #include "rmsgpack_dom.h" +#include #define MAX_ERROR_LEN 256 #undef MAX_ARGS #define MAX_ARGS 50 -static char tmp_error_buff [MAX_ERROR_LEN] = {0}; +static char tmp_error_buff [MAX_ERROR_LEN] = {}; struct buffer { - const char *data; - size_t len; - off_t offset; + const char *data; + size_t len; + off_t offset; }; /* Errors */ static void raise_too_many_arguments(const char **error) { - strlcpy(tmp_error_buff, - "Too many arguments in function call.", sizeof(tmp_error_buff)); - *error = tmp_error_buff; + snprintf(tmp_error_buff, MAX_ERROR_LEN, + "Too many arguments in function call."); + *error = tmp_error_buff; } static void raise_expected_number(off_t where, const char **error) @@ -75,12 +73,12 @@ static void raise_unexpected_eof(off_t where, const char ** error) static void raise_enomem(const char **error) { - strlcpy(tmp_error_buff, "Out of memory", sizeof(tmp_error_buff)); + snprintf(tmp_error_buff, MAX_ERROR_LEN, "Out of memory"); *error = tmp_error_buff; } static void raise_unknown_function(off_t where, const char *name, - ssize_t len, const char **error) + size_t len, const char **error) { int n = snprintf(tmp_error_buff, MAX_ERROR_LEN, #ifdef _WIN32 @@ -133,26 +131,26 @@ enum argument_type struct argument; typedef struct rmsgpack_dom_value (*rarch_query_func)( - struct rmsgpack_dom_value input, - unsigned argc, - const struct argument *argv - ); + struct rmsgpack_dom_value input, + unsigned argc, + const struct argument *argv +); struct invocation { - rarch_query_func func; - unsigned argc; - struct argument *argv; + rarch_query_func func; + unsigned argc; + struct argument *argv; }; struct argument { - enum argument_type type; - union + enum argument_type type; + union { - struct rmsgpack_dom_value value; - struct invocation invocation; - } a; + struct rmsgpack_dom_value value; + struct invocation invocation; + }; }; static void argument_free(struct argument *arg) @@ -161,85 +159,82 @@ static void argument_free(struct argument *arg) if (arg->type != AT_FUNCTION) { - rmsgpack_dom_value_free(&arg->a.value); + rmsgpack_dom_value_free(&arg->value); return; } - for (i = 0; i < arg->a.invocation.argc; i++) - argument_free(&arg->a.invocation.argv[i]); + for (i = 0; i < arg->invocation.argc; i++) + argument_free(&arg->invocation.argv[i]); } struct query { - unsigned ref_count; - struct invocation root; + unsigned ref_count; + struct invocation root; }; struct registered_func { - const char *name; - rarch_query_func func; + const char *name; + rarch_query_func func; }; static struct buffer parse_argument(struct buffer buff, struct argument *arg, const char **error); static struct rmsgpack_dom_value is_true(struct rmsgpack_dom_value input, - unsigned argc, const struct argument *argv) + unsigned argc, const struct argument *argv) { struct rmsgpack_dom_value res; - memset(&res, 0, sizeof(res)); - res.type = RDT_BOOL; - res.val.bool_ = 0; + res.type = RDT_BOOL; + res.bool_ = 0; if (argc > 0 || input.type != RDT_BOOL) - res.val.bool_ = 0; + res.bool_ = 0; else - res.val.bool_ = input.val.bool_; + res.bool_ = input.bool_; return res; } static struct rmsgpack_dom_value equals(struct rmsgpack_dom_value input, - unsigned argc, const struct argument * argv) + unsigned argc, const struct argument * argv) { - struct argument arg; struct rmsgpack_dom_value res; - memset(&res, 0, sizeof(res)); + struct argument arg; res.type = RDT_BOOL; if (argc != 1) - res.val.bool_ = 0; + res.bool_ = 0; else { arg = argv[0]; if (arg.type != AT_VALUE) - res.val.bool_ = 0; + res.bool_ = 0; else { - if (input.type == RDT_UINT && arg.a.value.type == RDT_INT) + if (input.type == RDT_UINT && arg.value.type == RDT_INT) { - arg.a.value.type = RDT_UINT; - arg.a.value.val.uint_ = arg.a.value.val.int_; + arg.value.type = RDT_UINT; + arg.value.uint_ = arg.value.int_; } - res.val.bool_ = (rmsgpack_dom_value_cmp(&input, &arg.a.value) == 0); + res.bool_ = (rmsgpack_dom_value_cmp(&input, &arg.value) == 0); } } return res; } static struct rmsgpack_dom_value operator_or(struct rmsgpack_dom_value input, - unsigned argc, const struct argument * argv) + unsigned argc, const struct argument * argv) { - unsigned i; struct rmsgpack_dom_value res; - memset(&res, 0, sizeof(res)); + unsigned i; res.type = RDT_BOOL; - res.val.bool_ = 0; + res.bool_ = 0; for (i = 0; i < argc; i++) { @@ -247,13 +242,13 @@ static struct rmsgpack_dom_value operator_or(struct rmsgpack_dom_value input, res = equals(input, 1, &argv[i]); else { - res = is_true(argv[i].a.invocation.func(input, - argv[i].a.invocation.argc, - argv[i].a.invocation.argv + res = is_true(argv[i].invocation.func(input, + argv[i].invocation.argc, + argv[i].invocation.argv ), 0, NULL); } - if (res.val.bool_) + if (res.bool_) return res; } @@ -264,12 +259,10 @@ static struct rmsgpack_dom_value between(struct rmsgpack_dom_value input, unsigned argc, const struct argument * argv) { struct rmsgpack_dom_value res; - unsigned i = 0; - - memset(&res, 0, sizeof(res)); + unsigned i = 0; res.type = RDT_BOOL; - res.val.bool_ = 0; + res.bool_ = 0; (void)i; @@ -277,16 +270,16 @@ static struct rmsgpack_dom_value between(struct rmsgpack_dom_value input, return res; if (argv[0].type != AT_VALUE || argv[1].type != AT_VALUE) return res; - if (argv[0].a.value.type != RDT_INT || argv[1].a.value.type != RDT_INT) + if (argv[0].value.type != RDT_INT || argv[1].value.type != RDT_INT) return res; switch (input.type) { case RDT_INT: - res.val.bool_ = ((input.val.int_ >= argv[0].a.value.val.int_) && (input.val.int_ <= argv[1].a.value.val.int_)); + res.bool_ = input.int_ >= argv[0].value.int_ && input.int_ <= argv[1].value.int_; break; case RDT_UINT: - res.val.bool_ = (((unsigned)input.val.int_ >= argv[0].a.value.val.uint_) && (input.val.int_ <= argv[1].a.value.val.int_)); + res.bool_ = input.int_ >= argv[0].value.uint_ && input.int_ <= argv[1].value.int_; break; default: return res; @@ -298,12 +291,11 @@ static struct rmsgpack_dom_value between(struct rmsgpack_dom_value input, static struct rmsgpack_dom_value operator_and(struct rmsgpack_dom_value input, unsigned argc, const struct argument * argv) { - unsigned i; struct rmsgpack_dom_value res; - memset(&res, 0, sizeof(res)); + unsigned i; res.type = RDT_BOOL; - res.val.bool_ = 0; + res.bool_ = 0; for (i = 0; i < argc; i++) { @@ -312,14 +304,14 @@ static struct rmsgpack_dom_value operator_and(struct rmsgpack_dom_value input, else { res = is_true( - argv[i].a.invocation.func(input, - argv[i].a.invocation.argc, - argv[i].a.invocation.argv + argv[i].invocation.func(input, + argv[i].invocation.argc, + argv[i].invocation.argv ), 0, NULL); } - if (!res.val.bool_) + if (!res.bool_) return res; } return res; @@ -330,22 +322,21 @@ static struct rmsgpack_dom_value q_glob(struct rmsgpack_dom_value input, { struct rmsgpack_dom_value res; unsigned i = 0; - memset(&res, 0, sizeof(res)); res.type = RDT_BOOL; - res.val.bool_ = 0; + res.bool_ = 0; (void)i; if (argc != 1) return res; - if (argv[0].type != AT_VALUE || argv[0].a.value.type != RDT_STRING) + if (argv[0].type != AT_VALUE || argv[0].value.type != RDT_STRING) return res; if (input.type != RDT_STRING) return res; - res.val.bool_ = rl_fnmatch( - argv[0].a.value.val.string.buff, - input.val.string.buff, + res.bool_ = rl_fnmatch( + argv[0].value.string.buff, + input.string.buff, 0 ) == 0; return res; @@ -354,20 +345,19 @@ static struct rmsgpack_dom_value q_glob(struct rmsgpack_dom_value input, static struct rmsgpack_dom_value all_map(struct rmsgpack_dom_value input, unsigned argc, const struct argument *argv) { - unsigned i; - struct argument arg; struct rmsgpack_dom_value res; - struct rmsgpack_dom_value nil_value; struct rmsgpack_dom_value *value = NULL; - memset(&res, 0, sizeof(res)); + struct argument arg; + struct rmsgpack_dom_value nil_value; + unsigned i; nil_value.type = RDT_NULL; res.type = RDT_BOOL; - res.val.bool_ = 1; + res.bool_ = 1; if (argc % 2 != 0) { - res.val.bool_ = 0; + res.bool_ = 0; return res; } @@ -379,10 +369,10 @@ static struct rmsgpack_dom_value all_map(struct rmsgpack_dom_value input, arg = argv[i]; if (arg.type != AT_VALUE) { - res.val.bool_ = 0; + res.bool_ = 0; goto clean; } - value = rmsgpack_dom_value_map_value(&input, &arg.a.value); + value = rmsgpack_dom_value_map_value(&input, &arg.value); if (!value) /* All missing fields are nil */ value = &nil_value; arg = argv[i + 1]; @@ -390,14 +380,14 @@ static struct rmsgpack_dom_value all_map(struct rmsgpack_dom_value input, res = equals(*value, 1, &arg); else { - res = is_true(arg.a.invocation.func( + res = is_true(arg.invocation.func( *value, - arg.a.invocation.argc, - arg.a.invocation.argv + arg.invocation.argc, + arg.invocation.argv ), 0, NULL); value = NULL; } - if (!res.val.bool_) + if (!res.bool_) break; } clean: @@ -405,24 +395,26 @@ clean: } struct registered_func registered_functions[100] = { - {"is_true", is_true}, - {"or", operator_or}, - {"and", operator_and}, - {"between", between}, - {"glob", q_glob}, - {NULL, NULL} + {"is_true", is_true}, + {"or", operator_or}, + {"and", operator_and}, + {"between", between}, + {"glob", q_glob}, + {NULL, NULL} }; static struct buffer chomp(struct buffer buff) { - for (; (unsigned)buff.offset < buff.len && isspace((int)buff.data[buff.offset]); buff.offset++); + off_t i = 0; + (void)i; + for (; buff.offset < buff.len && isspace(buff.data[buff.offset]); buff.offset++); return buff; } static struct buffer expect_char(struct buffer buff, char c, const char ** error) { - if ((unsigned)buff.offset >= buff.len) + if (buff.offset >= buff.len) raise_unexpected_eof(buff.offset, error); else if (buff.data[buff.offset] != c) raise_unexpected_char( @@ -435,7 +427,7 @@ static struct buffer expect_char(struct buffer buff, static struct buffer expect_eof(struct buffer buff, const char ** error) { buff = chomp(buff); - if ((unsigned)buff.offset < buff.len) + if (buff.offset < buff.len) raise_expected_eof(buff.offset, buff.data[buff.offset], error); return buff; } @@ -453,7 +445,7 @@ static int peek(struct buffer buff, const char * data) static int is_eot(struct buffer buff) { - return ((unsigned)buff.offset >= buff.len); + return (buff.offset >= buff.len); } static void peek_char(struct buffer buff, char *c, const char **error) @@ -470,23 +462,22 @@ static void peek_char(struct buffer buff, char *c, const char **error) static struct buffer get_char(struct buffer buff, char * c, const char ** error) { - if (is_eot(buff)) + if (is_eot(buff)) { - raise_unexpected_eof(buff.offset, error); - return buff; - } - *c = buff.data[buff.offset]; - buff.offset++; - return buff; + raise_unexpected_eof(buff.offset, error); + return buff; + } + *c = buff.data[buff.offset]; + buff.offset++; + return buff; } static struct buffer parse_string(struct buffer buff, struct rmsgpack_dom_value *value, const char **error) { - const char * str_start = NULL; - char terminator = '\0'; - char c = '\0'; - int is_binstr = 0; + const char * str_start; + char terminator = '\0'; + char c = '\0'; (void)c; @@ -495,12 +486,6 @@ static struct buffer parse_string(struct buffer buff, if (*error) return buff; - if (terminator == 'b') - { - is_binstr = 1; - buff = get_char(buff, &terminator, error); - } - if (terminator != '"' && terminator != '\'') { buff.offset--; @@ -519,44 +504,18 @@ static struct buffer parse_string(struct buffer buff, if (!*error) { - size_t count; - value->type = is_binstr ? RDT_BINARY : RDT_STRING; - value->val.string.len = (buff.data + buff.offset) - str_start - 1; + value->type = RDT_STRING; + value->string.len = (buff.data + buff.offset) - str_start - 1; + value->string.buff = (char*)calloc(value->string.len + 1, sizeof(char)); - count = is_binstr ? (value->val.string.len + 1) / 2 : (value->val.string.len + 1); - value->val.string.buff = (char*)calloc(count, sizeof(char)); - - if (!value->val.string.buff) + if (!value->string.buff) raise_enomem(error); - else if (is_binstr) - { - unsigned i; - const char *tok = str_start; - unsigned j = 0; - - for (i = 0; i < value->val.string.len; i += 2) - { - uint8_t hi, lo; - char hic = tok[i]; - char loc = tok[i + 1]; - - if (hic <= '9') - hi = hic - '0'; - else - hi = (hic - 'A') + 10; - - if (loc <= '9') - lo = loc - '0'; - else - lo = (loc - 'A') + 10; - - value->val.string.buff[j++] = hi * 16 + lo; - } - - value->val.string.len = j; - } else - memcpy(value->val.string.buff, str_start, value->val.string.len); + memcpy( + value->string.buff, + str_start, + value->string.len + ); } return buff; } @@ -572,11 +531,11 @@ static struct buffer parse_integer(struct buffer buff, #else "%lld", #endif - (signed long long*)&value->val.int_) == 0) + (signed long long*)&value->int_) == 0) raise_expected_number(buff.offset, error); else { - while (isdigit((int)buff.data[buff.offset])) + while (isdigit(buff.data[buff.offset])) buff.offset++; } return buff; @@ -596,17 +555,17 @@ static struct buffer parse_value(struct buffer buff, { buff.offset += strlen("true"); value->type = RDT_BOOL; - value->val.bool_ = 1; + value->bool_ = 1; } else if (peek(buff, "false")) { buff.offset += strlen("false"); value->type = RDT_BOOL; - value->val.bool_ = 0; + value->bool_ = 0; } - else if (peek(buff, "b") || peek(buff, "\"") || peek(buff, "'")) + else if (peek(buff, "\"") || peek(buff, "'")) buff = parse_string(buff, value, error); - else if (isdigit((int)buff.data[buff.offset])) + else if (isdigit(buff.data[buff.offset])) buff = parse_integer(buff, value, error); return buff; } @@ -617,28 +576,28 @@ static struct buffer get_ident(struct buffer buff, { char c = '\0'; - if (is_eot(buff)) + if (is_eot(buff)) { raise_unexpected_eof(buff.offset, error); return buff; } - *ident = buff.data + buff.offset; - *len = 0; - peek_char(buff, &c, error); + *ident = buff.data + buff.offset; + *len = 0; + peek_char(buff, &c, error); - if (*error) - goto clean; - if (!isalpha((int)c)) - return buff; + if (*error) + goto clean; + if (!isalpha(c)) + return buff; - buff.offset++; - *len = *len + 1; - peek_char(buff, &c, error); + buff.offset++; + *len = *len + 1; + peek_char(buff, &c, error); - while (!*error) + while (!*error) { - if (!(isalpha((int)c) || isdigit((int)c) || c == '_')) + if (!(isalpha(c) || isdigit(c) || c == '_')) break; buff.offset++; *len = *len + 1; @@ -646,18 +605,18 @@ static struct buffer get_ident(struct buffer buff, } clean: - return buff; + return buff; } static struct buffer parse_method_call(struct buffer buff, struct invocation *invocation, const char **error) { + const char *func_name; size_t func_name_len; unsigned i; struct argument args[MAX_ARGS]; unsigned argi = 0; - const char *func_name = NULL; - struct registered_func *rf = registered_functions; + struct registered_func * rf = registered_functions; invocation->func = NULL; @@ -740,12 +699,14 @@ success: static struct buffer parse_table(struct buffer buff, struct invocation *invocation, const char **error) { - unsigned i; - size_t ident_len; struct argument args[MAX_ARGS]; - const char *ident_name = NULL; + unsigned i; + const char *ident_name; + size_t ident_len; unsigned argi = 0; + memset(args, 0, sizeof(struct argument) * MAX_ARGS); + buff = chomp(buff); buff = expect_char(buff, '{', error); @@ -762,31 +723,31 @@ static struct buffer parse_table(struct buffer buff, goto clean; } - if (isalpha((int)buff.data[buff.offset])) + if (isalpha(buff.data[buff.offset])) { buff = get_ident(buff, &ident_name, &ident_len, error); if (!*error) { - args[argi].a.value.type = RDT_STRING; - args[argi].a.value.val.string.len = ident_len; - args[argi].a.value.val.string.buff = (char*)calloc( + args[argi].value.type = RDT_STRING; + args[argi].value.string.len = ident_len; + args[argi].value.string.buff = (char*)calloc( ident_len + 1, sizeof(char) ); - if (!args[argi].a.value.val.string.buff) + if (!args[argi].value.string.buff) goto clean; strncpy( - args[argi].a.value.val.string.buff, + args[argi].value.string.buff, ident_name, ident_len ); } } else - buff = parse_string(buff, &args[argi].a.value, error); + buff = parse_string(buff, &args[argi].value, error); if (*error) goto clean; @@ -855,65 +816,63 @@ static struct buffer parse_argument(struct buffer buff, buff = chomp(buff); if ( - isalpha((int)buff.data[buff.offset]) + isalpha(buff.data[buff.offset]) && !( peek(buff, "nil") || peek(buff, "true") || peek(buff, "false") - || peek(buff, "b\"") || peek(buff, "b'") /* bin string prefix*/ ) ) { arg->type = AT_FUNCTION; - buff = parse_method_call(buff, &arg->a.invocation, error); + buff = parse_method_call(buff, &arg->invocation, error); } else if (peek(buff, "{")) { arg->type = AT_FUNCTION; - buff = parse_table(buff, &arg->a.invocation, error); + buff = parse_table(buff, &arg->invocation, error); } else { arg->type = AT_VALUE; - buff = parse_value(buff, &arg->a.value, error); + buff = parse_value(buff, &arg->value, error); } return buff; } + + void libretrodb_query_free(void *q) { - unsigned i; - struct query *real_q = (struct query*)q; + unsigned i; + struct query * real_q = (struct query*)q; - real_q->ref_count--; - if (real_q->ref_count > 0) - return; + real_q->ref_count--; + if (real_q->ref_count > 0) + return; - for (i = 0; i < real_q->root.argc; i++) - argument_free(&real_q->root.argv[i]); - - free(real_q->root.argv); - real_q->root.argv = NULL; - real_q->root.argc = 0; - free(real_q); + for (i = 0; i < real_q->root.argc; i++) + argument_free(&real_q->root.argv[i]); } 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*)calloc(1, sizeof(*q)); + struct query *q = (struct query*)malloc(sizeof(struct query)); if (!q) goto clean; + memset(q, 0, sizeof(struct query)); + q->ref_count = 1; buff.data = query; buff.len = buff_len; buff.offset = 0; *error = NULL; - buff = chomp(buff); + buff = chomp(buff); if (peek(buff, "{")) { @@ -921,7 +880,7 @@ void *libretrodb_query_compile(libretrodb_t *db, if (*error) goto clean; } - else if (isalpha((int)buff.data[buff.offset])) + else if (isalpha(buff.data[buff.offset])) buff = parse_method_call(buff, &q->root, error); buff = expect_eof(buff, error); @@ -953,5 +912,5 @@ int libretrodb_query_filter(libretrodb_query_t *q, { struct invocation inv = ((struct query *)q)->root; struct rmsgpack_dom_value res = inv.func(*v, inv.argc, inv.argv); - return (res.type == RDT_BOOL && res.val.bool_); + return (res.type == RDT_BOOL && res.bool_); } diff --git a/libretro-db/rmsgpack.c b/libretro-db/rmsgpack.c index ee4dd15220..6cb5d3a747 100644 --- a/libretro-db/rmsgpack.c +++ b/libretro-db/rmsgpack.c @@ -55,18 +55,7 @@ static const uint8_t MPF_UINT64 = 0xcf; static const uint8_t MPF_NIL = 0xc0; -static INLINE ssize_t fpwrite(FILE *fp, const void *buf, size_t count) -{ - return (fwrite(buf, 1, count, fp) != count) ? -1 : (ssize_t)count; -} - -static INLINE ssize_t fpread(FILE *fp, void *buf, size_t count) -{ - size_t num_read = fread(buf, 1, count, fp); - return num_read != count && ferror(fp) ? -1 : (ssize_t)num_read; -} - -int rmsgpack_write_array_header(FILE *fp, uint32_t size) +int rmsgpack_write_array_header(int fd, uint32_t size) { uint16_t tmp_i16; uint32_t tmp_i32; @@ -74,29 +63,29 @@ int rmsgpack_write_array_header(FILE *fp, uint32_t size) if (size < 16) { size = (size | MPF_FIXARRAY); - if (fpwrite(fp, &size, sizeof(int8_t)) == -1) + if (write(fd, &size, sizeof(int8_t)) == -1) return -errno; return sizeof(int8_t); } else if (size == (uint16_t)size) { - if (fpwrite(fp, &MPF_ARRAY16, sizeof(MPF_ARRAY16)) == -1) + if (write(fd, &MPF_ARRAY16, sizeof(MPF_ARRAY16)) == -1) return -errno; tmp_i16 = httobe16(size); - if (fpwrite(fp, (void *)(&tmp_i16), sizeof(uint16_t)) == -1) + if (write(fd, (void *)(&tmp_i16), sizeof(uint16_t)) == -1) return -errno; return sizeof(int8_t) + sizeof(uint16_t); } - if (fpwrite(fp, &MPF_ARRAY32, sizeof(MPF_ARRAY32)) == -1) + if (write(fd, &MPF_ARRAY32, sizeof(MPF_ARRAY32)) == -1) return -errno; tmp_i32 = httobe32(size); - if (fpwrite(fp, (void *)(&tmp_i32), sizeof(uint32_t)) == -1) + if (write(fd, (void *)(&tmp_i32), sizeof(uint32_t)) == -1) return -errno; return sizeof(int8_t) + sizeof(uint32_t); } -int rmsgpack_write_map_header(FILE *fp, uint32_t size) +int rmsgpack_write_map_header(int fd, uint32_t size) { uint16_t tmp_i16; uint32_t tmp_i32; @@ -104,29 +93,29 @@ int rmsgpack_write_map_header(FILE *fp, uint32_t size) if (size < 16) { size = (size | MPF_FIXMAP); - if (fpwrite(fp, &size, sizeof(int8_t)) == -1) + if (write(fd, &size, sizeof(int8_t)) == -1) return -errno; return sizeof(int8_t); } else if (size < (uint16_t)size) { - if (fpwrite(fp, &MPF_MAP16, sizeof(MPF_MAP16)) == -1) + if (write(fd, &MPF_MAP16, sizeof(MPF_MAP16)) == -1) return -errno; tmp_i16 = httobe16(size); - if (fpwrite(fp, (void *)(&tmp_i16), sizeof(uint16_t)) == -1) + if (write(fd, (void *)(&tmp_i16), sizeof(uint16_t)) == -1) return -errno; return sizeof(uint8_t) + sizeof(uint16_t); } tmp_i32 = httobe32(size); - if (fpwrite(fp, &MPF_MAP32, sizeof(MPF_MAP32)) == -1) + if (write(fd, &MPF_MAP32, sizeof(MPF_MAP32)) == -1) return -errno; - if (fpwrite(fp, (void *)(&tmp_i32), sizeof(uint32_t)) == -1) + if (write(fd, (void *)(&tmp_i32), sizeof(uint32_t)) == -1) return -errno; return sizeof(int8_t) + sizeof(uint32_t); } -int rmsgpack_write_string(FILE *fp, const char *s, uint32_t len) +int rmsgpack_write_string(int fd, const char *s, uint32_t len) { int8_t fixlen = 0; uint16_t tmp_i16; @@ -136,43 +125,43 @@ int rmsgpack_write_string(FILE *fp, const char *s, uint32_t len) if (len < 32) { fixlen = len | MPF_FIXSTR; - if (fpwrite(fp, &fixlen, sizeof(int8_t)) == -1) + if (write(fd, &fixlen, sizeof(int8_t)) == -1) return -errno; } else if (len < (1 << 8)) { - if (fpwrite(fp, &MPF_STR8, sizeof(MPF_STR8)) == -1) + if (write(fd, &MPF_STR8, sizeof(MPF_STR8)) == -1) return -errno; - if (fpwrite(fp, &len, sizeof(uint8_t)) == -1) + if (write(fd, &len, sizeof(uint8_t)) == -1) return -errno; written += sizeof(uint8_t); } else if (len < (1 << 16)) { - if (fpwrite(fp, &MPF_STR16, sizeof(MPF_STR16)) == -1) + if (write(fd, &MPF_STR16, sizeof(MPF_STR16)) == -1) return -errno; tmp_i16 = httobe16(len); - if (fpwrite(fp, &tmp_i16, sizeof(uint16_t)) == -1) + if (write(fd, &tmp_i16, sizeof(uint16_t)) == -1) return -errno; written += sizeof(uint16_t); } else { - if (fpwrite(fp, &MPF_STR32, sizeof(MPF_STR32)) == -1) + if (write(fd, &MPF_STR32, sizeof(MPF_STR32)) == -1) return -errno; tmp_i32 = httobe32(len); - if (fpwrite(fp, &tmp_i32, sizeof(uint32_t)) == -1) + if (write(fd, &tmp_i32, sizeof(uint32_t)) == -1) return -errno; written += sizeof(uint32_t); } - if (fpwrite(fp, s, len) == -1) + if (write(fd, s, len) == -1) return -errno; written += len; return written; } -int rmsgpack_write_bin(FILE *fp, const void *s, uint32_t len) +int rmsgpack_write_bin(int fd, const void *s, uint32_t len) { uint16_t tmp_i16; uint32_t tmp_i32; @@ -180,58 +169,58 @@ int rmsgpack_write_bin(FILE *fp, const void *s, uint32_t len) if (len == (uint8_t)len) { - if (fpwrite(fp, &MPF_BIN8, sizeof(MPF_BIN8)) == -1) + if (write(fd, &MPF_BIN8, sizeof(MPF_BIN8)) == -1) return -errno; - if (fpwrite(fp, &len, sizeof(uint8_t)) == -1) + if (write(fd, &len, sizeof(uint8_t)) == -1) return -errno; written += sizeof(uint8_t); } else if (len == (uint16_t)len) { - if (fpwrite(fp, &MPF_BIN16, sizeof(MPF_BIN16)) == -1) + if (write(fd, &MPF_BIN16, sizeof(MPF_BIN16)) == -1) return -errno; tmp_i16 = httobe16(len); - if (fpwrite(fp, &tmp_i16, sizeof(uint16_t)) == -1) + if (write(fd, &tmp_i16, sizeof(uint16_t)) == -1) return -errno; written += sizeof(uint16_t); } else { - if (fpwrite(fp, &MPF_BIN32, sizeof(MPF_BIN32)) == -1) + if (write(fd, &MPF_BIN32, sizeof(MPF_BIN32)) == -1) return -errno; tmp_i32 = httobe32(len); - if (fpwrite(fp, &tmp_i32, sizeof(uint32_t)) == -1) + if (write(fd, &tmp_i32, sizeof(uint32_t)) == -1) return -errno; written += sizeof(uint32_t); } - if (fpwrite(fp, s, len) == -1) + if (write(fd, s, len) == -1) return -errno; written += len; return 0; } -int rmsgpack_write_nil(FILE *fp) +int rmsgpack_write_nil(int fd) { - if (fpwrite(fp, &MPF_NIL, sizeof(MPF_NIL)) == -1) + if (write(fd, &MPF_NIL, sizeof(MPF_NIL)) == -1) return -errno; return sizeof(uint8_t); } -int rmsgpack_write_bool(FILE *fp, int value) +int rmsgpack_write_bool(int fd, int value) { if (value) { - if (fpwrite(fp, &MPF_TRUE, sizeof(MPF_TRUE)) == -1) + if (write(fd, &MPF_TRUE, sizeof(MPF_TRUE)) == -1) return -errno; } - if (fpwrite(fp, &MPF_FALSE, sizeof(MPF_FALSE)) == -1) + if (write(fd, &MPF_FALSE, sizeof(MPF_FALSE)) == -1) return -errno; return sizeof(uint8_t); } -int rmsgpack_write_int(FILE *fp, int64_t value) +int rmsgpack_write_int(int fd, int64_t value) { int16_t tmp_i16; int32_t tmp_i32; @@ -240,58 +229,58 @@ int rmsgpack_write_int(FILE *fp, int64_t value) if (value >=0 && value < 128) { - if (fpwrite(fp, &value, sizeof(int8_t)) == -1) + if (write(fd, &value, sizeof(int8_t)) == -1) return -errno; } else if (value < 0 && value > -32) { tmpval = (value) | 0xe0; - if (fpwrite(fp, &tmpval, sizeof(uint8_t)) == -1) + if (write(fd, &tmpval, sizeof(uint8_t)) == -1) return -errno; } else if (value == (int8_t)value) { - if (fpwrite(fp, &MPF_INT8, sizeof(MPF_INT8)) == -1) + if (write(fd, &MPF_INT8, sizeof(MPF_INT8)) == -1) return -errno; - if (fpwrite(fp, &value, sizeof(int8_t)) == -1) + if (write(fd, &value, sizeof(int8_t)) == -1) return -errno; written += sizeof(int8_t); } else if (value == (int16_t)value) { - if (fpwrite(fp, &MPF_INT16, sizeof(MPF_INT16)) == -1) + if (write(fd, &MPF_INT16, sizeof(MPF_INT16)) == -1) return -errno; tmp_i16 = httobe16(value); - if (fpwrite(fp, &tmp_i16, sizeof(int16_t)) == -1) + if (write(fd, &tmp_i16, sizeof(int16_t)) == -1) return -errno; written += sizeof(int16_t); } else if (value == (int32_t)value) { - if (fpwrite(fp, &MPF_INT32, sizeof(MPF_INT32)) == -1) + if (write(fd, &MPF_INT32, sizeof(MPF_INT32)) == -1) return -errno; tmp_i32 = httobe32(value); - if (fpwrite(fp, &tmp_i32, sizeof(int32_t)) == -1) + if (write(fd, &tmp_i32, sizeof(int32_t)) == -1) return -errno; written += sizeof(int32_t); } else { - if (fpwrite(fp, &MPF_INT64, sizeof(MPF_INT64)) == -1) + if (write(fd, &MPF_INT64, sizeof(MPF_INT64)) == -1) return -errno; value = httobe64(value); - if (fpwrite(fp, &value, sizeof(int64_t)) == -1) + if (write(fd, &value, sizeof(int64_t)) == -1) return -errno; written += sizeof(int64_t); } return written; } -int rmsgpack_write_uint(FILE *fp, uint64_t value) +int rmsgpack_write_uint(int fd, uint64_t value) { uint16_t tmp_i16; uint32_t tmp_i32; @@ -299,51 +288,51 @@ int rmsgpack_write_uint(FILE *fp, uint64_t value) if (value == (uint8_t)value) { - if (fpwrite(fp, &MPF_UINT8, sizeof(MPF_UINT8)) == -1) + if (write(fd, &MPF_UINT8, sizeof(MPF_UINT8)) == -1) return -errno; - if (fpwrite(fp, &value, sizeof(uint8_t)) == -1) + if (write(fd, &value, sizeof(uint8_t)) == -1) return -errno; written += sizeof(uint8_t); } else if (value == (uint16_t)value) { - if (fpwrite(fp, &MPF_UINT16, sizeof(MPF_UINT16)) == -1) + if (write(fd, &MPF_UINT16, sizeof(MPF_UINT16)) == -1) return -errno; tmp_i16 = httobe16(value); - if (fpwrite(fp, &tmp_i16, sizeof(uint16_t)) == -1) + if (write(fd, &tmp_i16, sizeof(uint16_t)) == -1) return -errno; written += sizeof(uint16_t); } else if (value == (uint32_t)value) { - if (fpwrite(fp, &MPF_UINT32, sizeof(MPF_UINT32)) == -1) + if (write(fd, &MPF_UINT32, sizeof(MPF_UINT32)) == -1) return -errno; tmp_i32 = httobe32(value); - if (fpwrite(fp, &tmp_i32, sizeof(uint32_t)) == -1) + if (write(fd, &tmp_i32, sizeof(uint32_t)) == -1) return -errno; written += sizeof(uint32_t); } else { - if (fpwrite(fp, &MPF_UINT64, sizeof(MPF_UINT64)) == -1) + if (write(fd, &MPF_UINT64, sizeof(MPF_UINT64)) == -1) return -errno; value = httobe64(value); - if (fpwrite(fp, &value, sizeof(uint64_t)) == -1) + if (write(fd, &value, sizeof(uint64_t)) == -1) return -errno; written += sizeof(uint64_t); } return written; } -static int read_uint(FILE *fp, uint64_t *out, size_t size) +static int read_uint(int fd, uint64_t *out, size_t size) { uint64_t tmp; - if (fpread(fp, &tmp, size) == -1) + if (read(fd, &tmp, size) == -1) return -errno; switch (size) @@ -364,15 +353,18 @@ static int read_uint(FILE *fp, uint64_t *out, size_t size) return 0; } -static int read_int(FILE *fp, int64_t *out, size_t size) +static int read_int(int fd, int64_t *out, size_t size) { + uint8_t tmp8 = 0; uint16_t tmp16; uint32_t tmp32; uint64_t tmp64; - if (fpread(fp, &tmp64, size) == -1) + if (read(fd, &tmp64, size) == -1) return -errno; + (void)tmp8; + switch (size) { case 1: @@ -391,34 +383,30 @@ static int read_int(FILE *fp, int64_t *out, size_t size) *out = *((int64_t *)(&tmp64)); break; } - return 0; } -static int read_buff(FILE *fp, size_t size, char **pbuff, uint64_t *len) +static int read_buff(int fd, size_t size, char **pbuff, uint64_t *len) { uint64_t tmp_len = 0; - if (read_uint(fp, &tmp_len, size) == -1) - goto error; + if (read_uint(fd, &tmp_len, size) == -1) + return -errno; - *pbuff = (char *)calloc((size_t)tmp_len + 1, sizeof(char)); + *pbuff = (char *)calloc(tmp_len + 1, sizeof(char)); - if (fpread(fp, *pbuff, (size_t)tmp_len) == -1) - goto error; + if (read(fd, *pbuff, tmp_len) == -1) + { + free(*pbuff); + return -errno; + } *len = tmp_len; return 0; - -error: - if (*pbuff) - free(*pbuff); - return -errno; - } -static int read_map(FILE *fp, uint32_t len, - struct rmsgpack_read_callbacks *callbacks, void *data) +static int read_map(int fd, uint32_t len, + struct rmsgpack_read_callbacks *callbacks, void *data) { int rv; unsigned i; @@ -429,16 +417,16 @@ static int read_map(FILE *fp, uint32_t len, for (i = 0; i < len; i++) { - if ((rv = rmsgpack_read(fp, callbacks, data)) < 0) + if ((rv = rmsgpack_read(fd, callbacks, data)) < 0) return rv; - if ((rv = rmsgpack_read(fp, callbacks, data)) < 0) + if ((rv = rmsgpack_read(fd, callbacks, data)) < 0) return rv; } return 0; } -static int read_array(FILE *fp, uint32_t len, +static int read_array(int fd, uint32_t len, struct rmsgpack_read_callbacks *callbacks, void *data) { int rv; @@ -450,14 +438,14 @@ static int read_array(FILE *fp, uint32_t len, for (i = 0; i < len; i++) { - if ((rv = rmsgpack_read(fp, callbacks, data)) < 0) + if ((rv = rmsgpack_read(fd, callbacks, data)) < 0) return rv; } return 0; } -int rmsgpack_read(FILE *fp, +int rmsgpack_read(int fd, struct rmsgpack_read_callbacks *callbacks, void *data) { int rv; @@ -467,7 +455,7 @@ int rmsgpack_read(FILE *fp, uint8_t type = 0; char *buff = NULL; - if (fpread(fp, &type, sizeof(uint8_t)) == -1) + if (read(fd, &type, sizeof(uint8_t)) == -1) return -errno; if (type < MPF_FIXMAP) @@ -479,20 +467,20 @@ int rmsgpack_read(FILE *fp, else if (type < MPF_FIXARRAY) { tmp_len = type - MPF_FIXMAP; - return read_map(fp, (uint32_t)tmp_len, callbacks, data); + return read_map(fd, tmp_len, callbacks, data); } else if (type < MPF_FIXSTR) { tmp_len = type - MPF_FIXARRAY; - return read_array(fp, (size_t)tmp_len, callbacks, data); + return read_array(fd, tmp_len, callbacks, data); } else if (type < MPF_NIL) { tmp_len = type - MPF_FIXSTR; - buff = (char *)calloc((size_t)tmp_len + 1, sizeof(char)); + buff = (char *)calloc(tmp_len + 1, sizeof(char)); if (!buff) return -ENOMEM; - if (fpread(fp, buff, (size_t)tmp_len) == -1) + if (read(fd, buff, tmp_len) == -1) { free(buff); return -errno; @@ -503,7 +491,7 @@ int rmsgpack_read(FILE *fp, free(buff); return 0; } - return callbacks->read_string(buff, (size_t)tmp_len, data); + return callbacks->read_string(buff, tmp_len, data); } else if (type > MPF_MAP32) { @@ -529,20 +517,20 @@ int rmsgpack_read(FILE *fp, case 0xc4: case 0xc5: case 0xc6: - if ((rv = read_buff(fp, 1<<(type - 0xc4), + if ((rv = read_buff(fd, 1<<(type - 0xc4), &buff, &tmp_len)) < 0) return rv; if (callbacks->read_bin) - return callbacks->read_bin(buff, (size_t)tmp_len, data); + return callbacks->read_bin(buff, tmp_len, data); break; case 0xcc: case 0xcd: case 0xce: case 0xcf: - tmp_len = UINT32_C(1) << (type - 0xcc); + tmp_len = 1ULL << (type - 0xcc); tmp_uint = 0; - if (read_uint(fp, &tmp_uint, (size_t)tmp_len) == -1) + if (read_uint(fd, &tmp_uint, tmp_len) == -1) return -errno; if (callbacks->read_uint) @@ -552,9 +540,9 @@ int rmsgpack_read(FILE *fp, case 0xd1: case 0xd2: case 0xd3: - tmp_len = UINT32_C(1) << (type - 0xd0); + tmp_len = 1ULL << (type - 0xd0); tmp_int = 0; - if (read_int(fp, &tmp_int, (size_t)tmp_len) == -1) + if (read_int(fd, &tmp_int, tmp_len) == -1) return -errno; if (callbacks->read_int) @@ -563,24 +551,24 @@ int rmsgpack_read(FILE *fp, case 0xd9: case 0xda: case 0xdb: - if ((rv = read_buff(fp, 1<<(type - 0xd9), &buff, &tmp_len)) < 0) + if ((rv = read_buff(fd, 1<<(type - 0xd9), &buff, &tmp_len)) < 0) return rv; if (callbacks->read_string) - return callbacks->read_string(buff, (size_t)tmp_len, data); + return callbacks->read_string(buff, tmp_len, data); break; case 0xdc: case 0xdd: - if (read_uint(fp, &tmp_len, 2<<(type - 0xdc)) == -1) + if (read_uint(fd, &tmp_len, 2<<(type - 0xdc)) == -1) return -errno; - return read_array(fp, (size_t)tmp_len, callbacks, data); + return read_array(fd, tmp_len, callbacks, data); case 0xde: case 0xdf: - if (read_uint(fp, &tmp_len, 2<<(type - 0xde)) == -1) + if (read_uint(fd, &tmp_len, 2<<(type - 0xde)) == -1) return -errno; - return read_map(fp, (size_t)tmp_len, callbacks, data); + return read_map(fd, tmp_len, callbacks, data); } return 0; diff --git a/libretro-db/rmsgpack.h b/libretro-db/rmsgpack.h index 1a2ef04031..8cebbbecc8 100644 --- a/libretro-db/rmsgpack.h +++ b/libretro-db/rmsgpack.h @@ -1,7 +1,6 @@ #ifndef __RARCHDB_MSGPACK_H__ #define __RARCHDB_MSGPACK_H__ -#include #include struct rmsgpack_read_callbacks { @@ -40,39 +39,39 @@ struct rmsgpack_read_callbacks { int rmsgpack_write_array_header( - FILE *fp, + int fd, uint32_t size ); int rmsgpack_write_map_header( - FILE *fp, + int fd, uint32_t size ); int rmsgpack_write_string( - FILE *fp, + int fd, const char * s, uint32_t len ); int rmsgpack_write_bin( - FILE *fp, + int fd, const void * s, uint32_t len ); -int rmsgpack_write_nil(FILE *fp); +int rmsgpack_write_nil(int fd); int rmsgpack_write_bool( - FILE *fp, + int fd, int value ); int rmsgpack_write_int( - FILE *fp, + int fd, int64_t value ); int rmsgpack_write_uint( - FILE *fp, + int fd, uint64_t value ); int rmsgpack_read( - FILE *fp, + int fd, struct rmsgpack_read_callbacks * callbacks, void * data ); diff --git a/libretro-db/rmsgpack_dom.c b/libretro-db/rmsgpack_dom.c index 41e41b5bc1..e7ae4837b1 100644 --- a/libretro-db/rmsgpack_dom.c +++ b/libretro-db/rmsgpack_dom.c @@ -13,74 +13,24 @@ struct dom_reader_state { - int i; - struct rmsgpack_dom_value *stack[MAX_DEPTH]; + int i; + struct rmsgpack_dom_value *stack[MAX_DEPTH]; }; -static struct rmsgpack_dom_value *dom_reader_state_pop( - struct dom_reader_state *s) +static struct rmsgpack_dom_value *dom_reader_state_pop(struct dom_reader_state *s) { - struct rmsgpack_dom_value *v = s->stack[s->i]; - s->i--; - return v; + struct rmsgpack_dom_value *v = s->stack[s->i]; + s->i--; + return v; } -static void puts_i64(int64_t dec) +static int dom_reader_state_push(struct dom_reader_state *s, struct rmsgpack_dom_value *v) { - unsigned i; - signed j; - signed char digits[19 + 1] = {0}; /* max i64: 9,223,372,036,854,775,807 */ - uint64_t decimal = (dec < 0) ? (uint64_t)-dec : (uint64_t)+dec; - - digits[19] = '\0'; - - for (j = sizeof(digits) - 2; j >= 0; j--) - { - digits[j] = decimal % 10; - decimal /= 10; - } - - for (i = 0; i < sizeof(digits) - 1; i++) - digits[i] += '0'; - - for (i = 0; i < sizeof(digits) - 2; i++) - if (digits[i] != '0') - break; /* Don't print leading zeros to the console. */ - - if (dec < 0) - putchar('-'); - fputs((char *)&digits[i], stdout); -} - -static void puts_u64(uint64_t decimal) -{ - signed j; - unsigned i; - char digits[20 + 1] = {0}; /* max u64: 18,446,744,073,709,551,616 */ - - for (j = sizeof(digits) - 2; j >= 0; j--) - { - digits[j] = decimal % 10; - decimal /= 10; - } - - for (i = 0; i < sizeof(digits) - 1; i++) - digits[i] += '0'; - for (i = 0; i < sizeof(digits) - 2; i++) - if (digits[i] != '0') - break; /* Don't print leading zeros to the console. */ - - fputs(&digits[i], stdout); -} - -static int dom_reader_state_push(struct dom_reader_state *s, - struct rmsgpack_dom_value *v) -{ - if ((s->i + 1) == MAX_DEPTH) - return -ENOMEM; - s->i++; - s->stack[s->i] = v; - return 0; + if ((s->i + 1) == MAX_DEPTH) + return -ENOMEM; + s->i++; + s->stack[s->i] = v; + return 0; } static int dom_read_nil(void *data) @@ -99,7 +49,7 @@ static int dom_read_bool(int value, void *data) (struct rmsgpack_dom_value*)dom_reader_state_pop(dom_state); v->type = RDT_BOOL; - v->val.bool_ = value; + v->bool_ = value; return 0; } @@ -110,7 +60,7 @@ static int dom_read_int(int64_t value, void *data) (struct rmsgpack_dom_value*)dom_reader_state_pop(dom_state); v->type = RDT_INT; - v->val.int_ = value; + v->int_ = value; return 0; } @@ -121,7 +71,7 @@ static int dom_read_uint(uint64_t value, void *data) (struct rmsgpack_dom_value*)dom_reader_state_pop(dom_state); v->type = RDT_UINT; - v->val.uint_ = value; + v->uint_ = value; return 0; } @@ -132,8 +82,8 @@ static int dom_read_string(char *value, uint32_t len, void *data) (struct rmsgpack_dom_value*)dom_reader_state_pop(dom_state); v->type = RDT_STRING; - v->val.string.len = len; - v->val.string.buff = value; + v->string.len = len; + v->string.buff = value; return 0; } @@ -142,10 +92,10 @@ static int dom_read_bin(void *value, uint32_t len, void *data) struct dom_reader_state *dom_state = (struct dom_reader_state *)data; struct rmsgpack_dom_value *v = (struct rmsgpack_dom_value*)dom_reader_state_pop(dom_state); - + v->type = RDT_BINARY; - v->val.binary.len = len; - v->val.binary.buff = (char *)value; + v->binary.len = len; + v->binary.buff = (char *)value; return 0; } @@ -157,8 +107,8 @@ static int dom_read_map_start(uint32_t len, void *data) struct rmsgpack_dom_value *v = dom_reader_state_pop(dom_state); v->type = RDT_MAP; - v->val.map.len = len; - v->val.map.items = NULL; + v->map.len = len; + v->map.items = NULL; items = (struct rmsgpack_dom_pair *)calloc(len, sizeof(struct rmsgpack_dom_pair)); @@ -166,7 +116,7 @@ static int dom_read_map_start(uint32_t len, void *data) if (!items) return -ENOMEM; - v->val.map.items = items; + v->map.items = items; for (i = 0; i < len; i++) { @@ -181,40 +131,40 @@ static int dom_read_map_start(uint32_t len, void *data) static int dom_read_array_start(uint32_t len, void *data) { - unsigned i; - struct dom_reader_state *dom_state = (struct dom_reader_state *)data; - struct rmsgpack_dom_value *v = dom_reader_state_pop(dom_state); - struct rmsgpack_dom_value *items = NULL; + unsigned i; + struct dom_reader_state *dom_state = (struct dom_reader_state *)data; + struct rmsgpack_dom_value *v = dom_reader_state_pop(dom_state); + struct rmsgpack_dom_value *items = NULL; - v->type = RDT_ARRAY; - v->val.array.len = len; - v->val.array.items = NULL; + v->type = RDT_ARRAY; + v->array.len = len; + v->array.items = NULL; - items = (struct rmsgpack_dom_value *)calloc(len, sizeof(struct rmsgpack_dom_pair)); + items = (struct rmsgpack_dom_value *)calloc(len, sizeof(struct rmsgpack_dom_pair)); - if (!items) - return -ENOMEM; + if (!items) + return -ENOMEM; - v->val.array.items = items; + v->array.items = items; - for (i = 0; i < len; i++) + for (i = 0; i < len; i++) { if (dom_reader_state_push(dom_state, &items[i]) < 0) return -ENOMEM; } - return 0; + return 0; } static struct rmsgpack_read_callbacks dom_reader_callbacks = { - dom_read_nil, - dom_read_bool, - dom_read_int, - dom_read_uint, - dom_read_string, - dom_read_bin, - dom_read_map_start, - dom_read_array_start + dom_read_nil, + dom_read_bool, + dom_read_int, + dom_read_uint, + dom_read_string, + dom_read_bin, + dom_read_map_start, + dom_read_array_start }; void rmsgpack_dom_value_free(struct rmsgpack_dom_value *v) @@ -224,33 +174,29 @@ void rmsgpack_dom_value_free(struct rmsgpack_dom_value *v) switch (v->type) { case RDT_STRING: - free(v->val.string.buff); - v->val.string.buff = NULL; + free(v->string.buff); break; case RDT_BINARY: - free(v->val.binary.buff); - v->val.binary.buff = NULL; + free(v->binary.buff); break; case RDT_MAP: - for (i = 0; i < v->val.map.len; i++) + for (i = 0; i < v->map.len; i++) { - rmsgpack_dom_value_free(&v->val.map.items[i].key); - rmsgpack_dom_value_free(&v->val.map.items[i].value); + rmsgpack_dom_value_free(&v->map.items[i].key); + rmsgpack_dom_value_free(&v->map.items[i].value); } - free(v->val.map.items); - v->val.map.items = NULL; + free(v->map.items); break; case RDT_ARRAY: - for (i = 0; i < v->val.array.len; i++) - rmsgpack_dom_value_free(&v->val.array.items[i]); - free(v->val.array.items); - v->val.array.items = NULL; + for (i = 0; i < v->array.len; i++) + rmsgpack_dom_value_free(&v->array.items[i]); + free(v->array.items); break; case RDT_NULL: case RDT_INT: case RDT_BOOL: case RDT_UINT: - /* Do nothing */ + // Do nothing break; } } @@ -263,10 +209,10 @@ struct rmsgpack_dom_value *rmsgpack_dom_value_map_value( if (map->type != RDT_MAP) return NULL; - for (i = 0; i < map->val.map.len; i++) + for (i = 0; i < map->map.len; i++) { - if (rmsgpack_dom_value_cmp(key, &map->val.map.items[i].key) == 0) - return &map->val.map.items[i].value; + if (rmsgpack_dom_value_cmp(key, &map->map.items[i].key) == 0) + return &map->map.items[i].value; } return NULL; } @@ -274,7 +220,7 @@ struct rmsgpack_dom_value *rmsgpack_dom_value_map_value( int rmsgpack_dom_value_cmp( const struct rmsgpack_dom_value *a, const struct rmsgpack_dom_value *b - ) +) { int rv; unsigned i; @@ -290,39 +236,39 @@ int rmsgpack_dom_value_cmp( case RDT_NULL: return 0; case RDT_BOOL: - return (a->val.bool_ == b->val.bool_) ? 0 : 1; + return a->bool_ == b->bool_ ? 0 : 1; case RDT_INT: - return (a->val.int_ == b->val.int_) ? 0 : 1; + return a->int_ == b->int_ ? 0 : 1; case RDT_UINT: - return (a->val.uint_ == b->val.uint_) ? 0 : 1; + return a->uint_ == b->uint_ ? 0 : 1; case RDT_STRING: - if (a->val.string.len != b->val.string.len) + if (a->string.len != b->string.len) return 1; - return strncmp(a->val.string.buff, b->val.string.buff, a->val.string.len); + return strncmp(a->string.buff, b->string.buff, a->string.len); case RDT_BINARY: - if (a->val.binary.len != b->val.binary.len) + if (a->binary.len != b->binary.len) return 1; - return memcmp(a->val.binary.buff, b->val.binary.buff, a->val.binary.len); + return memcmp(a->binary.buff, b->binary.buff, a->binary.len); case RDT_MAP: - if (a->val.map.len != b->val.map.len) + if (a->map.len != b->map.len) return 1; - for (i = 0; i < a->val.map.len; i++) + for (i = 0; i < a->map.len; i++) { - if ((rv = rmsgpack_dom_value_cmp(&a->val.map.items[i].key, - &b->val.map.items[i].key)) != 0) + if ((rv = rmsgpack_dom_value_cmp(&a->map.items[i].key, + &b->map.items[i].key)) != 0) return rv; - if ((rv = rmsgpack_dom_value_cmp(&a->val.map.items[i].value, - &b->val.map.items[i].value)) != 0) + if ((rv = rmsgpack_dom_value_cmp(&a->map.items[i].value, + &b->map.items[i].value)) != 0) return rv; } break; case RDT_ARRAY: - if (a->val.array.len != b->val.array.len) + if (a->array.len != b->array.len) return 1; - for (i = 0; i < a->val.array.len; i++) + for (i = 0; i < a->array.len; i++) { - if ((rv = rmsgpack_dom_value_cmp(&a->val.array.items[i], - &b->val.array.items[i])) != 0) + if ((rv = rmsgpack_dom_value_cmp(&a->array.items[i], + &b->array.items[i])) != 0) return rv; } break; @@ -341,91 +287,100 @@ void rmsgpack_dom_value_print(struct rmsgpack_dom_value *obj) printf("nil"); break; case RDT_BOOL: - if (obj->val.bool_) + if (obj->bool_) printf("true"); else printf("false"); break; case RDT_INT: - puts_i64(obj->val.int_); +#ifdef _WIN32 + printf("%I64d", (signed long long)obj->int_); +#else + printf("%lld", (signed long long)obj->int_); +#endif break; case RDT_UINT: - puts_u64(obj->val.uint_); +#ifdef _WIN32 + printf("%I64u", (unsigned long long)obj->uint_); +#else + printf("%llu", (unsigned long long)obj->uint_); +#endif break; case RDT_STRING: - printf("\"%s\"", obj->val.string.buff); - break; case RDT_BINARY: + printf("\"%s\"", obj->string.buff); + break; + case RDT_BINARY: printf("\""); - for (i = 0; i < obj->val.binary.len; i++) - printf("%02X", (unsigned char) obj->val.binary.buff[i]); + for (i = 0; i < obj->binary.len; i++) + printf("%02X", (unsigned char) obj->binary.buff[i]); printf("\""); break; case RDT_MAP: printf("{"); - for (i = 0; i < obj->val.map.len; i++) + for (i = 0; i < obj->map.len; i++) { - rmsgpack_dom_value_print(&obj->val.map.items[i].key); + rmsgpack_dom_value_print(&obj->map.items[i].key); printf(": "); - rmsgpack_dom_value_print(&obj->val.map.items[i].value); - if (i < (obj->val.map.len - 1)) + rmsgpack_dom_value_print(&obj->map.items[i].value); + if (i < (obj->map.len - 1)) printf(", "); } printf("}"); break; case RDT_ARRAY: printf("["); - for (i = 0; i < obj->val.array.len; i++) + for (i = 0; i < obj->array.len; i++) { - rmsgpack_dom_value_print(&obj->val.array.items[i]); - if (i < (obj->val.array.len - 1)) + rmsgpack_dom_value_print(&obj->array.items[i]); + if (i < (obj->array.len - 1)) printf(", "); } printf("]"); } } -int rmsgpack_dom_write(FILE *fp, const struct rmsgpack_dom_value *obj) +int rmsgpack_dom_write(int fd, const struct rmsgpack_dom_value *obj) { unsigned i; - int rv = 0; + int rv = 0; int written = 0; switch (obj->type) { case RDT_NULL: - return rmsgpack_write_nil(fp); + return rmsgpack_write_nil(fd); case RDT_BOOL: - return rmsgpack_write_bool(fp, obj->val.bool_); + return rmsgpack_write_bool(fd, obj->bool_); case RDT_INT: - return rmsgpack_write_int(fp, obj->val.int_); + return rmsgpack_write_int(fd, obj->int_); case RDT_UINT: - return rmsgpack_write_uint(fp, obj->val.uint_); + return rmsgpack_write_uint(fd, obj->uint_); case RDT_STRING: - return rmsgpack_write_string(fp, obj->val.string.buff, obj->val.string.len); + return rmsgpack_write_string(fd, obj->string.buff, obj->string.len); case RDT_BINARY: - return rmsgpack_write_bin(fp, obj->val.binary.buff, obj->val.binary.len); + return rmsgpack_write_bin(fd, obj->binary.buff, obj->binary.len); case RDT_MAP: - if ((rv = rmsgpack_write_map_header(fp, obj->val.map.len)) < 0) + if ((rv = rmsgpack_write_map_header(fd, obj->map.len)) < 0) return rv; written += rv; - for (i = 0; i < obj->val.map.len; i++) + for (i = 0; i < obj->map.len; i++) { - if ((rv = rmsgpack_dom_write(fp, &obj->val.map.items[i].key)) < 0) + if ((rv = rmsgpack_dom_write(fd, &obj->map.items[i].key)) < 0) return rv; written += rv; - if ((rv = rmsgpack_dom_write(fp, &obj->val.map.items[i].value)) < 0) + if ((rv = rmsgpack_dom_write(fd, &obj->map.items[i].value)) < 0) return rv; written += rv; } break; case RDT_ARRAY: - if ((rv = rmsgpack_write_array_header(fp, obj->val.array.len)) < 0) + if ((rv = rmsgpack_write_array_header(fd, obj->array.len)) < 0) return rv; written += rv; - for (i = 0; i < obj->val.array.len; i++) + for (i = 0; i < obj->array.len; i++) { - if ((rv = rmsgpack_dom_write(fp, &obj->val.array.items[i])) < 0) + if ((rv = rmsgpack_dom_write(fd, &obj->array.items[i])) < 0) return rv; written += rv; } @@ -433,14 +388,15 @@ int rmsgpack_dom_write(FILE *fp, const struct rmsgpack_dom_value *obj) return written; } -int rmsgpack_dom_read(FILE *fp, struct rmsgpack_dom_value *out) +int rmsgpack_dom_read(int fd, struct rmsgpack_dom_value *out) { - struct dom_reader_state s = {0}; - int rv = 0; + struct dom_reader_state s; + int rv = 0; + s.i = 0; s.stack[0] = out; - rv = rmsgpack_read(fp, &dom_reader_callbacks, &s); + rv = rmsgpack_read(fd, &dom_reader_callbacks, &s); if (rv < 0) rmsgpack_dom_value_free(out); @@ -448,23 +404,26 @@ int rmsgpack_dom_read(FILE *fp, struct rmsgpack_dom_value *out) return rv; } -int rmsgpack_dom_read_into(FILE *fp, ...) +int rmsgpack_dom_read_into(int fd, ...) { va_list ap; - int rv; struct rmsgpack_dom_value map; + int rv; + const char *key_name; struct rmsgpack_dom_value key; struct rmsgpack_dom_value *value; int64_t *int_value; uint64_t *uint_value; int *bool_value; + char *buff_value; uint64_t min_len; - char *buff_value = NULL; - const char *key_name = NULL; + int value_type = 0; - va_start(ap, fp); + va_start(ap, fd); - rv = rmsgpack_dom_read(fp, &map); + rv = rmsgpack_dom_read(fd, &map); + + (void)value_type; if (rv < 0) { @@ -473,18 +432,24 @@ int rmsgpack_dom_read_into(FILE *fp, ...) } if (map.type != RDT_MAP) - goto error; + { + rv = -EINVAL; + goto clean; + } while (1) { key_name = va_arg(ap, const char *); if (!key_name) - goto error; + { + rv = 0; + goto clean; + } key.type = RDT_STRING; - key.val.string.len = strlen(key_name); - key.val.string.buff = (char *) key_name; + key.string.len = strlen(key_name); + key.string.buff = (char *) key_name; value = rmsgpack_dom_value_map_value(&map, &key); @@ -492,40 +457,41 @@ int rmsgpack_dom_read_into(FILE *fp, ...) { case RDT_INT: int_value = va_arg(ap, int64_t *); - *int_value = value->val.int_; + *int_value = value->int_; break; case RDT_BOOL: bool_value = va_arg(ap, int *); - *bool_value = value->val.bool_; + *bool_value = value->bool_; break; case RDT_UINT: uint_value = va_arg(ap, uint64_t *); - *uint_value = value->val.uint_; + *uint_value = value->uint_; break; case RDT_BINARY: buff_value = va_arg(ap, char *); uint_value = va_arg(ap, uint64_t *); - *uint_value = value->val.binary.len; - min_len = (value->val.binary.len > *uint_value) ? - *uint_value : value->val.binary.len; + *uint_value = value->binary.len; + min_len = (value->binary.len > *uint_value) ? + *uint_value : value->binary.len; - memcpy(buff_value, value->val.binary.buff, (size_t)min_len); + memcpy(buff_value, value->binary.buff, min_len); break; case RDT_STRING: buff_value = va_arg(ap, char *); uint_value = va_arg(ap, uint64_t *); - min_len = (value->val.string.len + 1 > *uint_value) ? - *uint_value : value->val.string.len + 1; + min_len = (value->string.len + 1 > *uint_value) ? + *uint_value : value->string.len + 1; *uint_value = min_len; - memcpy(buff_value, value->val.string.buff, (size_t)min_len); + memcpy(buff_value, value->string.buff, min_len); break; default: - goto error; + rv = -1; + goto clean; } } -error: +clean: va_end(ap); rmsgpack_dom_value_free(&map); return 0; diff --git a/libretro-db/rmsgpack_dom.h b/libretro-db/rmsgpack_dom.h index 961372cd6b..5f71f9818b 100644 --- a/libretro-db/rmsgpack_dom.h +++ b/libretro-db/rmsgpack_dom.h @@ -1,7 +1,6 @@ #ifndef __RARCHDB_MSGPACK_DOM_H__ #define __RARCHDB_MSGPACK_DOM_H__ -#include #include #ifdef __cplusplus @@ -24,32 +23,24 @@ struct rmsgpack_dom_value { union { uint64_t uint_; int64_t int_; - struct - { + struct { uint32_t len; char * buff; } string; - - struct - { + struct { uint32_t len; char * buff; } binary; - int bool_; - - struct - { + struct { uint32_t len; struct rmsgpack_dom_pair * items; } map; - - struct - { + struct { uint32_t len; struct rmsgpack_dom_value * items; } array; - } val; + }; }; struct rmsgpack_dom_pair { @@ -70,15 +61,15 @@ struct rmsgpack_dom_value * rmsgpack_dom_value_map_value( ); int rmsgpack_dom_read( - FILE *fp, + int fd, struct rmsgpack_dom_value * out ); int rmsgpack_dom_write( - FILE *fp, + int fd, const struct rmsgpack_dom_value * obj ); -int rmsgpack_dom_read_into(FILE *fp, ...); +int rmsgpack_dom_read_into(int fd, ...); #ifdef __cplusplus } diff --git a/libretro-db/rmsgpack_test.c b/libretro-db/rmsgpack_test.c index 528b3b59fa..822bf87b3d 100644 --- a/libretro-db/rmsgpack_test.c +++ b/libretro-db/rmsgpack_test.c @@ -162,17 +162,42 @@ static struct rmsgpack_read_callbacks stub_callbacks = { int main(void) { - FILE *fp; + int fd; + /* + int fd = open("test.msgpack", O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); + int rv = 0; + if (fd == -1) + { + printf("Could not open file: %s", strerror(errno)); + return errno; + } + rmsgpack_write_map_header(fd, 2); + rmsgpack_write_string(fd, "compact", strlen("compact")); + rmsgpack_write_bool(fd, 1); + rmsgpack_write_string(fd, "schema", strlen("schema")); + rmsgpack_write_array_header(fd, 10); + rmsgpack_write_string(fd, "schema", strlen("schema")); + rmsgpack_write_uint(fd, 1<<17); + rmsgpack_write_int(fd, (1<<17) + 1); + rmsgpack_write_int(fd, 4); + rmsgpack_write_int(fd, -3); + rmsgpack_write_int(fd, -22); + rmsgpack_write_int(fd, -35); + rmsgpack_write_int(fd, -421421412); + rmsgpack_write_int(fd, 4214); + rmsgpack_write_int(fd, -4214); + rmsgpack_write_uint(fd, 1<<17); + close(fd); + */ + struct stub_state state; state.i = 0; state.stack[0] = 0; - - fp = fopen("test.msgpack", "rb"); - rmsgpack_read(fp, &stub_callbacks, &state); - + fd = open("test.msgpack", O_RDONLY); + rmsgpack_read(fd, &stub_callbacks, &state); printf("\n"); - fclose(fp); + close(fd); return 0; }