task_database: support GDI files

This commit is contained in:
Brian Koropoff 2017-09-17 17:39:41 -07:00
parent 70ff0aa0c1
commit 6c1044a699
2 changed files with 197 additions and 5 deletions

View File

@ -68,9 +68,11 @@ typedef struct db_handle
bool scan_started;
} db_handle_t;
int find_track(const char *cue_path, bool first, size_t *offset, size_t *size,
int cue_find_track(const char *cue_path, bool first, size_t *offset, size_t *size,
char *track_path, size_t max_len);
int gdi_find_track(const char *gdi_path, bool first, char *track_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);
@ -304,7 +306,7 @@ static int cue_get_serial(const char *name, char* serial)
track_path[0] = '\0';
rv = find_track(name, true, &offset, &size, track_path, PATH_MAX_LENGTH);
rv = cue_find_track(name, true, &offset, &size, track_path, PATH_MAX_LENGTH);
if (rv < 0)
{
@ -323,6 +325,34 @@ static int cue_get_serial(const char *name, char* serial)
return ret;
}
static int gdi_get_serial(const char *name, char* serial)
{
char *track_path = (char*)malloc(PATH_MAX_LENGTH
* sizeof(char));
int ret = 0;
int rv = 0;
track_path[0] = '\0';
rv = gdi_find_track(name, true, track_path, PATH_MAX_LENGTH);
if (rv < 0)
{
RARCH_LOG("%s: %s\n",
msg_hash_to_str(MSG_COULD_NOT_FIND_VALID_DATA_TRACK),
strerror(-rv));
free(track_path);
return 0;
}
RARCH_LOG("%s\n", msg_hash_to_str(MSG_READING_FIRST_DATA_TRACK));
ret = file_get_serial(track_path, 0, SIZE_MAX, serial);
free(track_path);
return ret;
}
static int chd_get_serial(const char *name, char* serial)
{
intfstream_t *fd = NULL;
@ -412,7 +442,7 @@ static int cue_get_crc(const char *name, uint32_t *crc)
track_path[0] = '\0';
rv = find_track(name, false, &offset, &size, track_path, PATH_MAX_LENGTH);
rv = cue_find_track(name, false, &offset, &size, track_path, PATH_MAX_LENGTH);
if (rv < 0) {
RARCH_LOG("%s: %s\n", msg_hash_to_str(MSG_COULD_NOT_FIND_VALID_DATA_TRACK),
@ -433,6 +463,35 @@ static int cue_get_crc(const char *name, uint32_t *crc)
return rv;
}
static int gdi_get_crc(const char *name, uint32_t *crc)
{
char *track_path = (char *)malloc(PATH_MAX_LENGTH);
int ret = 0;
int rv = 0;
track_path[0] = '\0';
rv = gdi_find_track(name, false, track_path, PATH_MAX_LENGTH);
if (rv < 0) {
RARCH_LOG("%s: %s\n", msg_hash_to_str(MSG_COULD_NOT_FIND_VALID_DATA_TRACK),
strerror(-rv));
free(track_path);
return 0;
}
RARCH_LOG("GDI '%s' primary track: %s\n", name, track_path);
RARCH_LOG("%s\n", msg_hash_to_str(MSG_READING_FIRST_DATA_TRACK));
rv = file_get_crc(track_path, 0, SIZE_MAX, crc);
if (rv == 1) {
RARCH_LOG("GDI '%s' crc: %x\n", name, *crc);
}
free(track_path);
return rv;
}
static bool chd_get_crc(const char *name, uint32_t *crc)
{
intfstream_t *fd = NULL;
@ -481,6 +540,18 @@ static int task_database_iterate_playlist(
return cue_get_crc(name, &db_state->crc);
}
break;
case FILE_TYPE_GDI:
db_state->serial[0] = '\0';
if (gdi_get_serial(name, db_state->serial))
{
database_info_set_type(db, DATABASE_TYPE_SERIAL_LOOKUP);
}
else
{
database_info_set_type(db, DATABASE_TYPE_CRC_LOOKUP);
return gdi_get_crc(name, &db_state->crc);
}
break;
case FILE_TYPE_ISO:
db_state->serial[0] = '\0';
file_get_serial(name, 0, SIZE_MAX, db_state->serial);
@ -488,7 +559,9 @@ static int task_database_iterate_playlist(
break;
case FILE_TYPE_CHD:
db_state->serial[0] = '\0';
if (chd_get_serial(name, db_state->serial))
/* There are no serial databases, so don't bother with
serials at the moment */
if (0 && chd_get_serial(name, db_state->serial))
{
database_info_set_type(db, DATABASE_TYPE_SERIAL_LOOKUP);
}

View File

@ -409,7 +409,7 @@ static bool update_cand(ssize_t *cand_index, ssize_t *last_index,
return false;
}
int find_track(const char *cue_path, bool first,
int cue_find_track(const char *cue_path, bool first,
size_t *offset, size_t *size, char *track_path, size_t max_len)
{
int rv;
@ -536,3 +536,122 @@ error:
intfstream_close(fd);
return -errno;
}
int gdi_find_track(const char *gdi_path, bool first, char *track_path, size_t max_len)
{
int rv;
char *tmp_token = malloc(MAX_TOKEN_LEN);
char *last_file = malloc(PATH_MAX_LENGTH + 1);
intfstream_info_t info;
intfstream_t *fd = NULL;
int32_t track = 0;
size_t largest = 0;
int size = -1;
int mode = -1;
ssize_t file_size = -1;
char *gdi_dir = (char*)malloc(PATH_MAX_LENGTH);
gdi_dir[0] = '\0';
fill_pathname_basedir(gdi_dir, gdi_path, PATH_MAX_LENGTH);
info.type = INTFSTREAM_FILE;
fd = intfstream_init(&info);
if (!fd)
{
goto error;
}
if (!intfstream_open(fd, gdi_path, RFILE_MODE_READ, -1))
{
RARCH_LOG("Could not open GDI file '%s': %s\n", gdi_path,
strerror(errno));
goto error;
}
RARCH_LOG("Parsing GDI file '%s'...\n", gdi_path);
tmp_token[0] = '\0';
rv = -EINVAL;
/* Skip track count */
get_token(fd, tmp_token, MAX_TOKEN_LEN);
/* Track number */
while (get_token(fd, tmp_token, MAX_TOKEN_LEN) > 0)
{
/* Offset */
if (get_token(fd, tmp_token, MAX_TOKEN_LEN) <= 0)
{
errno = EINVAL;
goto error;
}
/* Mode */
if (get_token(fd, tmp_token, MAX_TOKEN_LEN) <= 0)
{
errno = EINVAL;
goto error;
}
mode = atoi(tmp_token);
/* Sector size */
if (get_token(fd, tmp_token, MAX_TOKEN_LEN) <= 0)
{
errno = EINVAL;
goto error;
}
size = atoi(tmp_token);
/* File name */
if (get_token(fd, tmp_token, MAX_TOKEN_LEN) <= 0)
{
errno = EINVAL;
goto error;
}
/* Check for data track */
if (!(mode == 0 && size == 2352))
{
fill_pathname_join(last_file, gdi_dir, tmp_token, PATH_MAX_LENGTH);
file_size = get_file_size(last_file);
if (file_size < 0)
{
goto error;
}
if (file_size > largest)
{
strlcpy(track_path, last_file, max_len);
rv = 0;
largest = file_size;
if (first)
{
goto clean;
}
}
}
/* Disc offset (not used?) */
if (get_token(fd, tmp_token, MAX_TOKEN_LEN) <= 0)
{
errno = EINVAL;
goto error;
}
}
clean:
free(gdi_dir);
free(tmp_token);
free(last_file);
intfstream_close(fd);
return rv;
error:
free(gdi_dir);
free(tmp_token);
free(last_file);
if (fd)
intfstream_close(fd);
return -errno;
}