From fb8fe84684b72111f833feae720a7c98c309e906 Mon Sep 17 00:00:00 2001 From: Aaron Oneal Date: Mon, 18 Sep 2017 23:15:28 -0700 Subject: [PATCH] Fix archive scanning Archive scans were broken for cores like Atari 5200 and Commodore 64 because archive contents were skipped if a core reported it supported compressed files. The problem is, it's a false assumption that just because a core supports compressed files that the content database contains CRCs for compressed files. Instead of adding the contents of every compressed file to the scan list ahead of time, the patched logic now checks for the CRC of the archive itself as it always has but then adds the archive contents to the scan list if the archive itself is no match. This maintains the logic of adding only the archive if the core supports compressed files and the archive CRC matches but also allows for deeper content scans when there is no match. The patch also removes `core_info_unsupported_content_path` as it was redundant with existing `core_info_database_supports_content_path` logic. --- core_info.c | 64 ------------------------------ database_info.c | 91 ------------------------------------------- tasks/task_database.c | 64 +++++++++++++++++++++++++----- 3 files changed, 54 insertions(+), 165 deletions(-) diff --git a/core_info.c b/core_info.c index d48b35189a..a815d2dd31 100644 --- a/core_info.c +++ b/core_info.c @@ -825,45 +825,6 @@ size_t core_info_list_num_info_files(core_info_list_t *core_info_list) return num; } -bool core_info_unsupported_content_path(const char *path) -{ - size_t i; - const char *archive_path = NULL; - const char *delim = path_get_archive_delim(path); - - if (delim) - archive_path = delim - 1; - - if (!core_info_curr_list) - return false; - - /* if the path contains a compressed file and the core supports archives, - * we don't want to look at this file */ - if (archive_path) - { - for (i = 0; i < core_info_curr_list->count; i++) - { - const core_info_t *info = &core_info_curr_list->list[i]; - - if ( !string_list_find_elem(info->supported_extensions_list, "zip") - && !string_list_find_elem(info->supported_extensions_list, "7z")) - continue; - - return false; - } - } - - for (i = 0; i < core_info_curr_list->count; i++) - { - const core_info_t *info = &core_info_curr_list->list[i]; - - if (string_list_find_elem(info->supported_extensions_list, path_get_extension(path))) - return false; - } - - return true; -} - bool core_info_database_supports_content_path(const char *database_path, const char *path) { char *database = NULL; @@ -882,31 +843,6 @@ bool core_info_database_supports_content_path(const char *database_path, const c if (core_info_curr_list) { size_t i; - const char *delim = path_get_archive_delim(path); - - if (delim) - { - const char *archive_path = delim - 1; - - /* if the path contains a compressed file and the core supports archives, - * we don't want to look at this file */ - if (archive_path) - { - for (i = 0; i < core_info_curr_list->count; i++) - { - const core_info_t *info = &core_info_curr_list->list[i]; - - if (!string_list_find_elem(info->databases_list, database)) - continue; - - if ( !string_list_find_elem(info->supported_extensions_list, "zip") - && !string_list_find_elem(info->supported_extensions_list, "7z")) - continue; - - goto error; - } - } - } for (i = 0; i < core_info_curr_list->count; i++) { diff --git a/database_info.c b/database_info.c index b4ed7a12ac..ad694b66a5 100644 --- a/database_info.c +++ b/database_info.c @@ -417,56 +417,6 @@ database_info_handle_t *database_info_dir_init(const char *dir, db->status = DATABASE_STATUS_ITERATE; db->type = type; - if (db->list->size > 0) - { - for (i = 0; i < db->list->size; i++) - { - const char *path = db->list->elems[i].data; - - if (task) - task_set_progress(task, (i / (float)db->list->size) * 100); - - if (path_is_compressed_file(path) && !path_contains_compressed_file(path)) - { - struct string_list *archive_list = path_is_compressed_file(path) ? - file_archive_get_file_list(path, NULL) : NULL; - - if (archive_list && archive_list->size > 0) - { - unsigned i; - - for (i = 0; i < archive_list->size; i++) - { - char *new_path = (char*)malloc( - PATH_MAX_LENGTH * sizeof(char)); - size_t path_size = PATH_MAX_LENGTH * sizeof(char); - size_t path_len = strlen(path); - - new_path[0] = '\0'; - - strlcpy(new_path, path, path_size); - - if (path_len + strlen(archive_list->elems[i].data) - + 1 < PATH_MAX_LENGTH) - { - new_path[path_len] = '#'; - strlcpy(new_path + path_len + 1, - archive_list->elems[i].data, - path_size - path_len); - } - - string_list_append(db->list, new_path, - archive_list->elems[i].attr); - - free(new_path); - } - - string_list_free(archive_list); - } - } - } - } - return db; error: @@ -494,47 +444,6 @@ database_info_handle_t *database_info_file_init(const char *path, string_list_append(db->list, path, attr); - if (path_is_compressed_file(path)) - { - struct string_list *archive_list =path_is_compressed_file(path) ? - file_archive_get_file_list(path, NULL) : NULL; - - if (archive_list && archive_list->size > 0) - { - unsigned i; - - for (i = 0; i < archive_list->size; i++) - { - char *new_path = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); - size_t path_size = PATH_MAX_LENGTH * sizeof(char); - size_t path_len = strlen(path); - - if (task) - task_set_progress(task, - (i / (float)archive_list->size) * 100); - - new_path[0] = '\0'; - - strlcpy(new_path, path, path_size); - - if (path_len + strlen(archive_list->elems[i].data) - + 1 < PATH_MAX_LENGTH) - { - new_path[path_len] = '#'; - strlcpy(new_path + path_len + 1, - archive_list->elems[i].data, - path_size - path_len); - } - - string_list_append(db->list, new_path, - archive_list->elems[i].attr); - free(new_path); - } - - string_list_free(archive_list); - } - } - db->list_ptr = 0; db->status = DATABASE_STATUS_ITERATE; db->type = type; diff --git a/tasks/task_database.c b/tasks/task_database.c index ae8697c8ca..ea7f6037a4 100644 --- a/tasks/task_database.c +++ b/tasks/task_database.c @@ -390,10 +390,55 @@ static int task_database_iterate_playlist( } static int database_info_list_iterate_end_no_match( - database_state_handle_t *db_state) + database_info_handle_t *db, + database_state_handle_t *db_state, + const char *path) { /* Reached end of database list, * CRC match probably didn't succeed. */ + + /* If this was a compressed file and no match in the database + * list was found then expand the search list to include the + * archive's contents. */ + if (path_is_compressed_file(path) && !path_contains_compressed_file(path)) + { + struct string_list *archive_list = + file_archive_get_file_list(path, NULL); + + if (archive_list && archive_list->size > 0) + { + unsigned i; + + for (i = 0; i < archive_list->size; i++) + { + char *new_path = (char*)malloc( + PATH_MAX_LENGTH * sizeof(char)); + size_t path_size = PATH_MAX_LENGTH * sizeof(char); + size_t path_len = strlen(path); + + new_path[0] = '\0'; + + strlcpy(new_path, path, path_size); + + if (path_len + strlen(archive_list->elems[i].data) + + 1 < PATH_MAX_LENGTH) + { + new_path[path_len] = '#'; + strlcpy(new_path + path_len + 1, + archive_list->elems[i].data, + path_size - path_len); + } + + string_list_append(db->list, new_path, + archive_list->elems[i].attr); + + free(new_path); + } + + string_list_free(archive_list); + } + } + db_state->list_index = 0; db_state->entry_index = 0; @@ -539,8 +584,9 @@ static int task_database_iterate_crc_lookup( { if (!db_state->list || - (unsigned)db_state->list_index == (unsigned)db_state->list->size) - return database_info_list_iterate_end_no_match(db_state); + (unsigned)db_state->list_index == (unsigned)db_state->list->size) { + return database_info_list_iterate_end_no_match(db, db_state, name); + } if (db_state->entry_index == 0) { @@ -550,12 +596,9 @@ static int task_database_iterate_crc_lookup( query[0] = '\0'; - db_supports_content = core_info_database_supports_content_path( - db_state->list->elems[db_state->list_index].data, name); - unsupported_content = core_info_unsupported_content_path(name); - /* don't scan files that can't be in this database */ - if(!db_supports_content || unsupported_content) + if(!core_info_database_supports_content_path( + db_state->list->elems[db_state->list_index].data, name)) return database_info_list_iterate_next(db_state); snprintf(query, sizeof(query), @@ -677,8 +720,9 @@ static int task_database_iterate_serial_lookup( database_info_handle_t *db, const char *name) { if (!db_state->list || - (unsigned)db_state->list_index == (unsigned)db_state->list->size) - return database_info_list_iterate_end_no_match(db_state); + (unsigned)db_state->list_index == (unsigned)db_state->list->size) { + return database_info_list_iterate_end_no_match(db, db_state, name); + } if (db_state->entry_index == 0) {