mirror of
https://github.com/libretro/RetroArch
synced 2025-02-28 22:13:51 +00:00
(libretro-db) c_converter: simplify value_provider:
- use hash-key based lookups. - allow direct editing of the the dat<->rdb mappings.
This commit is contained in:
parent
46dc864258
commit
35e54b9777
@ -390,12 +390,12 @@ static dat_converter_match_key_t* dat_converter_match_key_create(const char* for
|
|||||||
|
|
||||||
static void dat_converter_match_key_free(dat_converter_match_key_t* match_key)
|
static void dat_converter_match_key_free(dat_converter_match_key_t* match_key)
|
||||||
{
|
{
|
||||||
if(!match_key)
|
if (!match_key)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
free(match_key->value);
|
free(match_key->value);
|
||||||
|
|
||||||
while(match_key)
|
while (match_key)
|
||||||
{
|
{
|
||||||
dat_converter_match_key_t* next = match_key->next;
|
dat_converter_match_key_t* next = match_key->next;
|
||||||
free(match_key);
|
free(match_key);
|
||||||
@ -414,11 +414,11 @@ static const char* dat_converter_get_match(dat_converter_list_t* list, dat_conve
|
|||||||
|
|
||||||
for (i = 0; i < list->count; i++)
|
for (i = 0; i < list->count; i++)
|
||||||
{
|
{
|
||||||
if(list->values[i].map.hash == match_key->hash)
|
if (list->values[i].map.hash == match_key->hash)
|
||||||
{
|
{
|
||||||
assert(!strcmp(list->values[i].map.key, match_key->value));
|
assert(!strcmp(list->values[i].map.key, match_key->value));
|
||||||
|
|
||||||
if(match_key->next)
|
if (match_key->next)
|
||||||
return dat_converter_get_match(list->values[i].map.value.list, match_key->next);
|
return dat_converter_get_match(list->values[i].map.value.list, match_key->next);
|
||||||
else if ((list->values[i].map.type == DAT_CONVERTER_STRING_MAP))
|
else if ((list->values[i].map.type == DAT_CONVERTER_STRING_MAP))
|
||||||
return list->values[i].map.value.string;
|
return list->values[i].map.value.string;
|
||||||
@ -473,7 +473,7 @@ static dat_converter_list_t* dat_converter_parser(dat_converter_list_t* target,
|
|||||||
if (!map.key)
|
if (!map.key)
|
||||||
{
|
{
|
||||||
printf("missing match key '");
|
printf("missing match key '");
|
||||||
while(match_key->next)
|
while (match_key->next)
|
||||||
{
|
{
|
||||||
printf("%s.", match_key->value);
|
printf("%s.", match_key->value);
|
||||||
match_key = match_key->next;
|
match_key = match_key->next;
|
||||||
@ -507,49 +507,80 @@ static dat_converter_list_t* dat_converter_parser(dat_converter_list_t* target,
|
|||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef enum
|
||||||
static int value_provider(dat_converter_list_item_t** current_item, struct rmsgpack_dom_value* out)
|
|
||||||
{
|
{
|
||||||
int i, j;
|
DAT_CONVERTER_RDB_TYPE_STRING,
|
||||||
#if 1
|
DAT_CONVERTER_RDB_TYPE_UINT,
|
||||||
const char* ordered_keys[] =
|
DAT_CONVERTER_RDB_TYPE_BINARY,
|
||||||
|
DAT_CONVERTER_RDB_TYPE_HEX
|
||||||
|
} dat_converter_rdb_format_enum;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
const char* dat_key;
|
||||||
|
const char* rdb_key;
|
||||||
|
dat_converter_rdb_format_enum format;
|
||||||
|
} dat_converter_rdb_mappings_t;
|
||||||
|
|
||||||
|
dat_converter_rdb_mappings_t rdb_mappings[] =
|
||||||
|
{
|
||||||
|
{"name", "name", DAT_CONVERTER_RDB_TYPE_STRING},
|
||||||
|
{"description", "description", DAT_CONVERTER_RDB_TYPE_STRING},
|
||||||
|
{"rom.name", "rom_name", DAT_CONVERTER_RDB_TYPE_STRING},
|
||||||
|
{"rom.size", "size", DAT_CONVERTER_RDB_TYPE_UINT},
|
||||||
|
{"users", "users", DAT_CONVERTER_RDB_TYPE_UINT},
|
||||||
|
{"releasemonth", "releasemonth", DAT_CONVERTER_RDB_TYPE_UINT},
|
||||||
|
{"releaseyear", "releaseyear", DAT_CONVERTER_RDB_TYPE_UINT},
|
||||||
|
{"rumble", "rumble", DAT_CONVERTER_RDB_TYPE_UINT},
|
||||||
|
{"analog", "analog", DAT_CONVERTER_RDB_TYPE_UINT},
|
||||||
|
|
||||||
|
{"famitsu_rating", "famitsu_rating", DAT_CONVERTER_RDB_TYPE_UINT},
|
||||||
|
{"edge_rating", "edge_rating", DAT_CONVERTER_RDB_TYPE_UINT},
|
||||||
|
{"edge_issue", "edge_issue", DAT_CONVERTER_RDB_TYPE_UINT},
|
||||||
|
{"edge_review", "edge_review", DAT_CONVERTER_RDB_TYPE_STRING},
|
||||||
|
|
||||||
|
{"enhancement_hw", "enhancement_hw", DAT_CONVERTER_RDB_TYPE_STRING},
|
||||||
|
{"barcode", "barcode", DAT_CONVERTER_RDB_TYPE_STRING},
|
||||||
|
{"esrb_rating", "esrb_rating", DAT_CONVERTER_RDB_TYPE_STRING},
|
||||||
|
{"elspa_rating", "elspa_rating", DAT_CONVERTER_RDB_TYPE_STRING},
|
||||||
|
{"pegi_rating", "pegi_rating", DAT_CONVERTER_RDB_TYPE_STRING},
|
||||||
|
{"cero_rating", "cero_rating", DAT_CONVERTER_RDB_TYPE_STRING},
|
||||||
|
{"franchise", "franchise", DAT_CONVERTER_RDB_TYPE_STRING},
|
||||||
|
|
||||||
|
{"developer", "developer", DAT_CONVERTER_RDB_TYPE_STRING},
|
||||||
|
{"publisher", "publisher", DAT_CONVERTER_RDB_TYPE_STRING},
|
||||||
|
{"origin", "origin", DAT_CONVERTER_RDB_TYPE_STRING},
|
||||||
|
|
||||||
|
{"rom.crc", "crc", DAT_CONVERTER_RDB_TYPE_HEX},
|
||||||
|
{"rom.md5", "md5", DAT_CONVERTER_RDB_TYPE_HEX},
|
||||||
|
{"rom.sha1", "sha1", DAT_CONVERTER_RDB_TYPE_HEX},
|
||||||
|
{"serial", "serial", DAT_CONVERTER_RDB_TYPE_BINARY},
|
||||||
|
{"rom.serial", "serial", DAT_CONVERTER_RDB_TYPE_BINARY}
|
||||||
|
};
|
||||||
|
|
||||||
|
dat_converter_match_key_t* rdb_mappings_mk[(sizeof(rdb_mappings) / sizeof(*rdb_mappings))] = {0};
|
||||||
|
|
||||||
|
static void dat_converter_value_provider_init(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < (sizeof(rdb_mappings) / sizeof(*rdb_mappings)); i++)
|
||||||
|
rdb_mappings_mk[i] = dat_converter_match_key_create(rdb_mappings[i].dat_key);
|
||||||
|
}
|
||||||
|
static void dat_converter_value_provider_free(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < (sizeof(rdb_mappings) / sizeof(*rdb_mappings)); i++)
|
||||||
{
|
{
|
||||||
"name",
|
dat_converter_match_key_free(rdb_mappings_mk[i]);
|
||||||
"description",
|
rdb_mappings_mk[i] = NULL;
|
||||||
"rom_name",
|
}
|
||||||
"size",
|
}
|
||||||
"users",
|
static int dat_converter_value_provider(dat_converter_list_item_t** current_item, struct rmsgpack_dom_value* out)
|
||||||
"releasemonth",
|
{
|
||||||
"releaseyear",
|
int i;
|
||||||
"rumble",
|
|
||||||
"analog",
|
|
||||||
|
|
||||||
"famitsu_rating",
|
|
||||||
"edge_rating",
|
|
||||||
"edge_issue",
|
|
||||||
"edge_review",
|
|
||||||
|
|
||||||
"enhancement_hw",
|
|
||||||
"barcode",
|
|
||||||
"esrb_rating",
|
|
||||||
"elspa_rating",
|
|
||||||
"pegi_rating",
|
|
||||||
"cero_rating",
|
|
||||||
"franchise",
|
|
||||||
|
|
||||||
"developer",
|
|
||||||
"publisher",
|
|
||||||
"origin",
|
|
||||||
|
|
||||||
"crc",
|
|
||||||
"md5",
|
|
||||||
"sha1",
|
|
||||||
"serial"
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
out->type = RDT_MAP;
|
out->type = RDT_MAP;
|
||||||
out->val.map.len = 0;
|
out->val.map.len = 0;
|
||||||
out->val.map.items = calloc(sizeof(ordered_keys) / sizeof(char*), sizeof(struct rmsgpack_dom_pair));
|
out->val.map.items = calloc((sizeof(rdb_mappings) / sizeof(*rdb_mappings)), sizeof(struct rmsgpack_dom_pair));
|
||||||
|
|
||||||
(*current_item)--;
|
(*current_item)--;
|
||||||
|
|
||||||
@ -564,90 +595,42 @@ static int value_provider(dat_converter_list_item_t** current_item, struct rmsgp
|
|||||||
|
|
||||||
struct rmsgpack_dom_pair* current = out->val.map.items;
|
struct rmsgpack_dom_pair* current = out->val.map.items;
|
||||||
|
|
||||||
for (i = 0; i < list->count; i++)
|
for (i = 0; i < (sizeof(rdb_mappings) / sizeof(*rdb_mappings)); i++)
|
||||||
{
|
{
|
||||||
dat_converter_map_t* pair = &list->values[i].map;
|
const char* value = dat_converter_get_match(list, rdb_mappings_mk[i]);
|
||||||
|
if (!value)
|
||||||
if (pair->type == DAT_CONVERTER_STRING_MAP)
|
|
||||||
{
|
|
||||||
current->key.type = RDT_STRING;
|
|
||||||
current->key.val.string.len = strlen(pair->key);
|
|
||||||
current->key.val.string.buff = strdup(pair->key);
|
|
||||||
|
|
||||||
if (!strcmp(pair->key, "users") ||
|
|
||||||
!strcmp(pair->key, "releasemonth") ||
|
|
||||||
!strcmp(pair->key, "releaseyear") ||
|
|
||||||
!strcmp(pair->key, "rumble") ||
|
|
||||||
!strcmp(pair->key, "analog") ||
|
|
||||||
!strcmp(pair->key, "famitsu_rating") ||
|
|
||||||
!strcmp(pair->key, "edge_rating") ||
|
|
||||||
!strcmp(pair->key, "edge_issue"))
|
|
||||||
{
|
|
||||||
current->value.type = RDT_UINT;
|
|
||||||
if (pair->value.string[strlen(pair->value.string) - 1] == '\?')
|
|
||||||
continue;
|
continue;
|
||||||
current->value.val.uint_ = (uint64_t)atoll(pair->value.string);
|
|
||||||
}
|
|
||||||
else if (!strcmp(pair->key, "serial"))
|
|
||||||
{
|
|
||||||
current->value.type = RDT_BINARY;
|
|
||||||
current->value.val.binary.len = strlen(pair->value.string);
|
|
||||||
current->value.val.binary.buff = strdup(pair->value.string);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
current->value.type = RDT_STRING;
|
|
||||||
current->value.val.string.len = strlen(pair->value.string);
|
|
||||||
current->value.val.string.buff = strdup(pair->value.string);
|
|
||||||
}
|
|
||||||
|
|
||||||
current++;
|
|
||||||
}
|
|
||||||
else if ((pair->type == DAT_CONVERTER_LIST_MAP) && (!strcmp(pair->key, "rom")))
|
|
||||||
{
|
|
||||||
assert(pair->value.list->type == DAT_CONVERTER_MAP_LIST);
|
|
||||||
|
|
||||||
for (j = 0; j < pair->value.list->count; j++)
|
|
||||||
{
|
|
||||||
dat_converter_map_t* rom_pair = &pair->value.list->values[j].map;
|
|
||||||
assert(rom_pair->type == DAT_CONVERTER_STRING_MAP);
|
|
||||||
|
|
||||||
if (!strcmp(rom_pair->key, "name"))
|
|
||||||
{
|
|
||||||
current->key.type = RDT_STRING;
|
current->key.type = RDT_STRING;
|
||||||
current->key.val.string.len = strlen("rom_name");
|
current->key.val.string.len = strlen(rdb_mappings[i].rdb_key);
|
||||||
current->key.val.string.buff = strdup("rom_name");
|
current->key.val.string.buff = strdup(rdb_mappings[i].rdb_key);
|
||||||
|
|
||||||
|
switch (rdb_mappings[i].format)
|
||||||
|
{
|
||||||
|
case DAT_CONVERTER_RDB_TYPE_STRING:
|
||||||
current->value.type = RDT_STRING;
|
current->value.type = RDT_STRING;
|
||||||
current->value.val.string.len = strlen(rom_pair->value.string);
|
current->value.val.string.len = strlen(value);
|
||||||
current->value.val.string.buff = strdup(rom_pair->value.string);
|
current->value.val.string.buff = strdup(value);
|
||||||
}
|
break;
|
||||||
else
|
case DAT_CONVERTER_RDB_TYPE_UINT:
|
||||||
{
|
|
||||||
current->key.type = RDT_STRING;
|
|
||||||
current->key.val.string.len = strlen(rom_pair->key);
|
|
||||||
current->key.val.string.buff = strdup(rom_pair->key);
|
|
||||||
|
|
||||||
if (!strcmp(rom_pair->key, "size"))
|
|
||||||
{
|
|
||||||
current->value.type = RDT_UINT;
|
current->value.type = RDT_UINT;
|
||||||
current->value.val.uint_ = (uint64_t)atoll(rom_pair->value.string);
|
if (value[strlen(value) - 1] == '\?')
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
|
free(current->key.val.string.buff);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
current->value.val.uint_ = (uint64_t)atoll(value);
|
||||||
|
break;
|
||||||
|
case DAT_CONVERTER_RDB_TYPE_BINARY:
|
||||||
current->value.type = RDT_BINARY;
|
current->value.type = RDT_BINARY;
|
||||||
|
current->value.val.binary.len = strlen(value);
|
||||||
if (!strcmp(rom_pair->key, "serial"))
|
current->value.val.binary.buff = strdup(value);
|
||||||
{
|
break;
|
||||||
current->value.val.binary.len = strlen(rom_pair->value.string);
|
case DAT_CONVERTER_RDB_TYPE_HEX:
|
||||||
current->value.val.binary.buff = strdup(rom_pair->value.string);
|
current->value.type = RDT_BINARY;
|
||||||
}
|
current->value.val.binary.len = strlen(value) / 2;
|
||||||
else
|
|
||||||
{
|
|
||||||
current->value.val.binary.len = strlen(rom_pair->value.string) / 2;
|
|
||||||
current->value.val.binary.buff = malloc(current->value.val.binary.len);
|
current->value.val.binary.buff = malloc(current->value.val.binary.len);
|
||||||
const char* hex_char = rom_pair->value.string;
|
const char* hex_char = value;
|
||||||
char* out_buff = current->value.val.binary.buff;
|
char* out_buff = current->value.val.binary.buff;
|
||||||
while (*hex_char && *(hex_char + 1))
|
while (*hex_char && *(hex_char + 1))
|
||||||
{
|
{
|
||||||
@ -672,39 +655,15 @@ static int value_provider(dat_converter_list_item_t** current_item, struct rmsgp
|
|||||||
*out_buff++ = val;
|
*out_buff++ = val;
|
||||||
hex_char++;
|
hex_char++;
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
}
|
default:
|
||||||
|
assert(0);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
current++;
|
current++;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
out->val.map.len = current - out->val.map.items;
|
out->val.map.len = current - out->val.map.items;
|
||||||
#if 1
|
|
||||||
/* re-order to match lua_converter */
|
|
||||||
struct rmsgpack_dom_pair* ordered_pairs = calloc(out->val.map.len, sizeof(struct rmsgpack_dom_pair));
|
|
||||||
struct rmsgpack_dom_pair* ordered_pairs_outp = ordered_pairs;
|
|
||||||
for (i = 0; i < (sizeof(ordered_keys) / sizeof(char*)); i++)
|
|
||||||
{
|
|
||||||
int j;
|
|
||||||
for (j = 0; j < out->val.map.len; j++)
|
|
||||||
{
|
|
||||||
if (!strcmp(ordered_keys[i], out->val.map.items[j].key.val.string.buff))
|
|
||||||
{
|
|
||||||
*ordered_pairs_outp++ = out->val.map.items[j];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
free(out->val.map.items);
|
|
||||||
out->val.map.items = ordered_pairs;
|
|
||||||
out->val.map.len = ordered_pairs_outp - ordered_pairs;
|
|
||||||
#endif
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -726,7 +685,7 @@ int main(int argc, char** argv)
|
|||||||
argc--;
|
argc--;
|
||||||
argv++;
|
argv++;
|
||||||
|
|
||||||
if (argc > 1 && **argv)
|
if (argc > 1 &&** argv)
|
||||||
{
|
{
|
||||||
match_key = dat_converter_match_key_create(*argv);
|
match_key = dat_converter_match_key_create(*argv);
|
||||||
argc--;
|
argc--;
|
||||||
@ -781,7 +740,9 @@ int main(int argc, char** argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
dat_converter_list_item_t* current_item = &dat_parser_list->values[dat_parser_list->count];
|
dat_converter_list_item_t* current_item = &dat_parser_list->values[dat_parser_list->count];
|
||||||
libretrodb_create(rdb_file, (libretrodb_value_provider)&value_provider, ¤t_item);
|
dat_converter_value_provider_init();
|
||||||
|
libretrodb_create(rdb_file, (libretrodb_value_provider)&dat_converter_value_provider, ¤t_item);
|
||||||
|
dat_converter_value_provider_free();
|
||||||
|
|
||||||
retro_fclose(rdb_file);
|
retro_fclose(rdb_file);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user