task_database: prune files referenced from cue/gdi files

Since we use cue/gdi files to find the right track file to
scan, don't bother scanning them separately.
This commit is contained in:
Brian Koropoff 2017-09-17 19:18:50 -07:00
parent 93d05665c2
commit 84edc8ffb0
2 changed files with 133 additions and 0 deletions

View File

@ -71,8 +71,12 @@ typedef struct db_handle
int cue_find_track(const char *cue_path, bool first, size_t *offset, size_t *size,
char *track_path, size_t max_len);
bool cue_next_file(intfstream_t *fd, const char *cue_path, char *path, size_t max_len);
int gdi_find_track(const char *gdi_path, bool first, char *track_path, size_t max_len);
bool gdi_next_file(intfstream_t *fd, const char *gdi_path, char *path, size_t max_len);
int detect_system(intfstream_t *fd, const char** system_name);
int detect_ps1_game(intfstream_t *fd, char *game_id);
@ -180,6 +184,12 @@ static const char *database_info_get_current_element_name(
{
if (!handle || !handle->list)
return NULL;
/* Skip pruned entries */
while (handle->list->elems[handle->list_ptr].data == NULL)
{
if (++handle->list_ptr >= handle->list->size)
return NULL;
}
return handle->list->elems[handle->list_ptr].data;
}
@ -514,6 +524,58 @@ static bool chd_get_crc(const char *name, uint32_t *crc)
return rv;
}
static void cue_prune(database_info_handle_t *db, const char *name)
{
char *path = (char *)malloc(PATH_MAX_LENGTH + 1);
intfstream_t *fd = open_file(name);
size_t i;
if (!fd)
{
free(path);
return;
}
while (cue_next_file(fd, name, path, PATH_MAX_LENGTH))
{
for (i = db->list_ptr; i < db->list->size; ++i)
{
if (db->list->elems[i].data && !strcmp(path, db->list->elems[i].data))
{
RARCH_LOG("Pruning file referenced by cue: %s\n", path);
free(db->list->elems[i].data);
db->list->elems[i].data = NULL;
}
}
}
}
static void gdi_prune(database_info_handle_t *db, const char *name)
{
char *path = (char *)malloc(PATH_MAX_LENGTH + 1);
intfstream_t *fd = open_file(name);
size_t i;
if (!fd)
{
free(path);
return;
}
while (gdi_next_file(fd, name, path, PATH_MAX_LENGTH))
{
for (i = db->list_ptr; i < db->list->size; ++i)
{
if (db->list->elems[i].data && !strcmp(path, db->list->elems[i].data))
{
RARCH_LOG("Pruning file referenced by gdi: %s\n", path);
free(db->list->elems[i].data);
db->list->elems[i].data = NULL;
}
}
}
}
static int task_database_iterate_playlist(
database_state_handle_t *db_state,
database_info_handle_t *db, const char *name)
@ -529,6 +591,7 @@ static int task_database_iterate_playlist(
break;
#endif
case FILE_TYPE_CUE:
cue_prune(db, name);
db_state->serial[0] = '\0';
if (cue_get_serial(name, db_state->serial))
{
@ -541,6 +604,7 @@ static int task_database_iterate_playlist(
}
break;
case FILE_TYPE_GDI:
gdi_prune(db, name);
db_state->serial[0] = '\0';
if (gdi_get_serial(name, db_state->serial))
{

View File

@ -541,6 +541,34 @@ error:
return -errno;
}
bool cue_next_file(intfstream_t *fd, const char *cue_path, char *path, size_t max_len)
{
bool rv = false;
char *tmp_token = malloc(MAX_TOKEN_LEN);
ssize_t volatile file_size = -1;
char *cue_dir = (char*)malloc(PATH_MAX_LENGTH);
cue_dir[0] = '\0';
fill_pathname_basedir(cue_dir, cue_path, PATH_MAX_LENGTH);
tmp_token[0] = '\0';
while (get_token(fd, tmp_token, MAX_TOKEN_LEN) > 0)
{
if (string_is_equal(tmp_token, "FILE"))
{
get_token(fd, tmp_token, MAX_TOKEN_LEN);
fill_pathname_join(path, cue_dir, tmp_token, max_len);
rv = true;
break;
}
}
free(cue_dir);
free(tmp_token);
return rv;
}
int gdi_find_track(const char *gdi_path, bool first, char *track_path, size_t max_len)
{
int rv;
@ -659,3 +687,44 @@ error:
intfstream_close(fd);
return -errno;
}
bool gdi_next_file(intfstream_t *fd, const char *gdi_path, char *path, size_t max_len)
{
bool rv = false;
char *tmp_token = malloc(MAX_TOKEN_LEN);
ssize_t offset = -1;
char *gdi_dir = (char*)malloc(PATH_MAX_LENGTH);
gdi_dir[0] = '\0';
tmp_token[0] = '\0';
fill_pathname_basedir(gdi_dir, gdi_path, PATH_MAX_LENGTH);
/* Skip initial track count */
offset = intfstream_tell(fd);
if (offset == 0)
{
get_token(fd, tmp_token, MAX_TOKEN_LEN);
}
/* Track number */
get_token(fd, tmp_token, MAX_TOKEN_LEN);
/* Offset */
get_token(fd, tmp_token, MAX_TOKEN_LEN);
/* Mode */
get_token(fd, tmp_token, MAX_TOKEN_LEN);
/* Sector size */
get_token(fd, tmp_token, MAX_TOKEN_LEN);
/* File name */
if (get_token(fd, tmp_token, MAX_TOKEN_LEN) > 0)
{
fill_pathname_join(path, gdi_dir, tmp_token, max_len);
rv = true;
/* Disc offset */
get_token(fd, tmp_token, MAX_TOKEN_LEN);
}
free(gdi_dir);
free(tmp_token);
return rv;
}