diff --git a/Makefile.common b/Makefile.common
index 5c997e95f6..33ffec60da 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -237,7 +237,8 @@ OBJ += libretro-db/bintree.o \
libretro-db/rmsgpack.o \
libretro-db/rmsgpack_dom.o \
database_info.o \
- tasks/task_database.o
+ tasks/task_database.o \
+ tasks/task_database_cue.o
endif
# Miscellaneous
diff --git a/griffin/griffin.c b/griffin/griffin.c
index 1911a9b623..500f14ccf0 100644
--- a/griffin/griffin.c
+++ b/griffin/griffin.c
@@ -726,6 +726,7 @@ DATA RUNLOOP
#include "../tasks/task_file_transfer.c"
#ifdef HAVE_LIBRETRODB
#include "../tasks/task_database.c"
+#include "../tasks/task_database_cue.c"
#endif
/*============================================================
diff --git a/tasks/task_database.c b/tasks/task_database.c
index ee5e70a4a1..ee90ba5397 100644
--- a/tasks/task_database.c
+++ b/tasks/task_database.c
@@ -13,11 +13,12 @@
* If not, see .
*/
+#include
+#include
+
#include
#include
#include
-#include
-#include
#include "tasks.h"
@@ -40,23 +41,6 @@
#define COLLECTION_SIZE 99999
#endif
-#define MAX_TOKEN_LEN 255
-
-#define MAGIC_LEN 16
-
-struct MagicEntry
-{
- const char* system_name;
- const char* magic;
-};
-
-static struct MagicEntry MAGIC_NUMBERS[] = {
- {"ps1", "\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x02\x00\x02\x00"},
- {"pcecd", "\x82\xb1\x82\xcc\x83\x76\x83\x8d\x83\x4f\x83\x89\x83\x80\x82\xcc\x92"},
- {"scd", "\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x02\x00\x01\x53"},
- {NULL, NULL}
-};
-
typedef struct database_state_handle
{
database_info_list_t *info;
@@ -361,212 +345,6 @@ static int database_info_iterate_playlist_zip(
return 1;
}
-ssize_t get_token(int fd, char *token, size_t max_len)
-{
- char *c = token;
- int rv;
- ssize_t len = 0;
- int in_string = 0;
-
- while (1)
- {
- rv = read(fd, c, 1);
- if (rv == 0)
- return 0;
- else if (rv < 1)
- {
- switch (errno)
- {
- case EINTR:
- case EAGAIN:
- continue;
- default:
- return -errno;
- }
- }
-
- switch (*c)
- {
- case ' ':
- case '\t':
- case '\r':
- case '\n':
- if (c == token)
- continue;
-
- if (!in_string)
- {
- *c = '\0';
- return len;
- }
- break;
- case '\"':
- if (c == token)
- {
- in_string = 1;
- continue;
- }
-
- *c = '\0';
- return len;
- }
-
- len++;
- c++;
- if (len == (ssize_t)max_len)
- {
- *c = '\0';
- return len;
- }
- }
-}
-
-int find_token(int fd, const char *token)
-{
- int tmp_len = strlen(token);
- char *tmp_token = (char*)calloc(tmp_len, 1);
- if (!tmp_token)
- return -1;
- while (strncmp(tmp_token, token, tmp_len) != 0)
- {
- if (get_token(fd, tmp_token, tmp_len) <= 0)
- return -1;
- }
-
- return 0;
-}
-
-static int detect_ps1_game(const char* track_path, char* game_id)
-{
- const char* pattern = "cdrom:";
- const char* pat_c;
- char* c;
- char* id_start;
- int i;
-
- int fd = open(track_path, O_RDONLY);
- if (fd < 0)
- {
- RARCH_LOG("Could not open data track: %s\n", strerror(errno));
- return -errno;
- }
-
- lseek(fd, 0x9340, SEEK_SET);
- if (read(fd, game_id, 10) > 0)
- {
- game_id[10] = '\0';
- game_id[4] = '-';
- }
-
- close(fd);
- return 1;
-}
-
-static int detect_system(const char* track_path, int32_t offset,
- const char** system_name)
-{
- int rv;
- char magic[MAGIC_LEN];
- int fd;
- int i;
-
- fd = open(track_path, O_RDONLY);
- if (fd < 0)
- {
- RARCH_LOG("Could not open data track of file '%s': %s\n",
- track_path, strerror(errno));
- rv = -errno;
- goto clean;
- }
-
- lseek(fd, offset, SEEK_SET);
- if (read(fd, magic, MAGIC_LEN) < MAGIC_LEN)
- {
- RARCH_LOG("Could not read data from file '%s' at offset %d: %s\n",
- track_path, offset, strerror(errno));
- rv = -errno;
- goto clean;
- }
-
- RARCH_LOG("Comparing with known magic numbers...\n");
- for (i = 0; MAGIC_NUMBERS[i].system_name != NULL; i++)
- {
- if (memcmp(MAGIC_NUMBERS[i].magic, magic, MAGIC_LEN) == 0)
- {
- *system_name = MAGIC_NUMBERS[i].system_name;
- rv = 0;
- goto clean;
- }
- }
-
- RARCH_LOG("Could not find compatible system\n");
- rv = -EINVAL;
-clean:
- close(fd);
- return rv;
-}
-
-static int find_first_data_track(const char* cue_path, int32_t* offset,
- char* track_path, size_t max_len)
-{
- int rv;
- int fd = -1;
- char tmp_token[MAX_TOKEN_LEN];
- int m, s, f;
- char cue_dir[PATH_MAX];
- strlcpy(cue_dir, cue_path, PATH_MAX);
- path_basedir(cue_dir);
-
- fd = open(cue_path, O_RDONLY);
- if (fd < 0)
- {
- RARCH_LOG("Could not open CUE file '%s': %s\n", cue_path,
- strerror(errno));
- return -errno;
- }
-
- RARCH_LOG("Parsing CUE file '%s'...\n", cue_path);
-
- while (get_token(fd, tmp_token, MAX_TOKEN_LEN) > 0)
- {
- if (strcmp(tmp_token, "FILE") == 0)
- {
- get_token(fd, tmp_token, MAX_TOKEN_LEN);
- fill_pathname_join(track_path, cue_dir, tmp_token, max_len);
-
- }
- else if (strcasecmp(tmp_token, "TRACK") == 0)
- {
- get_token(fd, tmp_token, MAX_TOKEN_LEN);
- get_token(fd, tmp_token, MAX_TOKEN_LEN);
- if (strcasecmp(tmp_token, "AUDIO") == 0)
- continue;
-
- find_token(fd, "INDEX");
- get_token(fd, tmp_token, MAX_TOKEN_LEN);
- get_token(fd, tmp_token, MAX_TOKEN_LEN);
- if (sscanf(tmp_token, "%02d:%02d:%02d", &m, &s, &f) < 3)
- {
- RARCH_LOG("Error parsing time stamp '%s'\n", tmp_token);
- return -errno;
- }
- *offset = ((m * 60) * (s * 75) * f) * 25;
-
- RARCH_LOG("Found 1st data track on file '%s+%d'\n",
- track_path, *offset);
-
- rv = 0;
- goto clean;
- }
- }
-
- rv = -EINVAL;
-
-clean:
- close(fd);
- return rv;
-}
-
static int database_info_iterate_playlist_cue(
database_state_handle_t *db_state,
database_info_handle_t *db, const char *name)
diff --git a/tasks/task_database_cue.c b/tasks/task_database_cue.c
new file mode 100644
index 0000000000..19b9c1f7d5
--- /dev/null
+++ b/tasks/task_database_cue.c
@@ -0,0 +1,255 @@
+/* RetroArch - A frontend for libretro.
+ * Copyright (C) 2011-2015 - Daniel De Matteis
+ *
+ * RetroArch is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Found-
+ * ation, either version 3 of the License, or (at your option) any later version.
+ *
+ * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with RetroArch.
+ * If not, see .
+ */
+
+#include
+#include
+
+#include
+#include
+#include
+
+#include "tasks.h"
+
+#ifdef HAVE_LIBRETRODB
+#include "../database_info.h"
+#endif
+
+#include "../dir_list_special.h"
+#include "../file_ops.h"
+#include "../msg_hash.h"
+#include "../general.h"
+
+#define MAGIC_LEN 16
+
+struct magic_entry
+{
+ const char *system_name;
+ const char *magic;
+};
+
+static struct magic_entry MAGIC_NUMBERS[] = {
+ {"ps1", "\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x02\x00\x02\x00"},
+ {"pcecd", "\x82\xb1\x82\xcc\x83\x76\x83\x8d\x83\x4f\x83\x89\x83\x80\x82\xcc\x92"},
+ {"scd", "\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x02\x00\x01\x53"},
+ {NULL, NULL}
+};
+
+ssize_t get_token(int fd, char *token, size_t max_len)
+{
+ int rv;
+ char *c = token;
+ ssize_t len = 0;
+ int in_string = 0;
+
+ while (1)
+ {
+ rv = read(fd, c, 1);
+ if (rv == 0)
+ return 0;
+ else if (rv < 1)
+ {
+ switch (errno)
+ {
+ case EINTR:
+ case EAGAIN:
+ continue;
+ default:
+ return -errno;
+ }
+ }
+
+ switch (*c)
+ {
+ case ' ':
+ case '\t':
+ case '\r':
+ case '\n':
+ if (c == token)
+ continue;
+
+ if (!in_string)
+ {
+ *c = '\0';
+ return len;
+ }
+ break;
+ case '\"':
+ if (c == token)
+ {
+ in_string = 1;
+ continue;
+ }
+
+ *c = '\0';
+ return len;
+ }
+
+ len++;
+ c++;
+ if (len == (ssize_t)max_len)
+ {
+ *c = '\0';
+ return len;
+ }
+ }
+}
+
+int find_token(int fd, const char *token)
+{
+ int tmp_len = strlen(token);
+ char *tmp_token = (char*)calloc(tmp_len, 1);
+
+ if (!tmp_token)
+ return -1;
+
+ while (strncmp(tmp_token, token, tmp_len) != 0)
+ {
+ if (get_token(fd, tmp_token, tmp_len) <= 0)
+ return -1;
+ }
+
+ return 0;
+}
+
+int detect_ps1_game(const char *track_path, char *game_id)
+{
+ int i;
+ const char *pat_c;
+ char *c, *id_start;
+ const char *pattern = "cdrom:";
+ int fd = open(track_path, O_RDONLY);
+
+ if (fd < 0)
+ {
+ RARCH_LOG("Could not open data track: %s\n", strerror(errno));
+ return -errno;
+ }
+
+ lseek(fd, 0x9340, SEEK_SET);
+
+ if (read(fd, game_id, 10) > 0)
+ {
+ game_id[10] = '\0';
+ game_id[4] = '-';
+ }
+
+ close(fd);
+ return 1;
+}
+
+int detect_system(const char *track_path, int32_t offset,
+ const char **system_name)
+{
+ int rv;
+ char magic[MAGIC_LEN];
+ int i;
+ int fd = open(track_path, O_RDONLY);
+
+ if (fd < 0)
+ {
+ RARCH_LOG("Could not open data track of file '%s': %s\n",
+ track_path, strerror(errno));
+ rv = -errno;
+ goto clean;
+ }
+
+ lseek(fd, offset, SEEK_SET);
+ if (read(fd, magic, MAGIC_LEN) < MAGIC_LEN)
+ {
+ RARCH_LOG("Could not read data from file '%s' at offset %d: %s\n",
+ track_path, offset, strerror(errno));
+ rv = -errno;
+ goto clean;
+ }
+
+ RARCH_LOG("Comparing with known magic numbers...\n");
+ for (i = 0; MAGIC_NUMBERS[i].system_name != NULL; i++)
+ {
+ if (memcmp(MAGIC_NUMBERS[i].magic, magic, MAGIC_LEN) == 0)
+ {
+ *system_name = MAGIC_NUMBERS[i].system_name;
+ rv = 0;
+ goto clean;
+ }
+ }
+
+ RARCH_LOG("Could not find compatible system\n");
+ rv = -EINVAL;
+clean:
+ close(fd);
+ return rv;
+}
+
+int find_first_data_track(const char *cue_path,
+ int32_t *offset, char *track_path, size_t max_len)
+{
+ int rv;
+ char tmp_token[MAX_TOKEN_LEN];
+ int m, s, f;
+ char cue_dir[PATH_MAX];
+ int fd = -1;
+
+ strlcpy(cue_dir, cue_path, PATH_MAX);
+ path_basedir(cue_dir);
+
+ fd = open(cue_path, O_RDONLY);
+ if (fd < 0)
+ {
+ RARCH_LOG("Could not open CUE file '%s': %s\n", cue_path,
+ strerror(errno));
+ return -errno;
+ }
+
+ RARCH_LOG("Parsing CUE file '%s'...\n", cue_path);
+
+ while (get_token(fd, tmp_token, MAX_TOKEN_LEN) > 0)
+ {
+ if (strcmp(tmp_token, "FILE") == 0)
+ {
+ get_token(fd, tmp_token, MAX_TOKEN_LEN);
+ fill_pathname_join(track_path, cue_dir, tmp_token, max_len);
+
+ }
+ else if (strcasecmp(tmp_token, "TRACK") == 0)
+ {
+ get_token(fd, tmp_token, MAX_TOKEN_LEN);
+ get_token(fd, tmp_token, MAX_TOKEN_LEN);
+ if (strcasecmp(tmp_token, "AUDIO") == 0)
+ continue;
+
+ find_token(fd, "INDEX");
+ get_token(fd, tmp_token, MAX_TOKEN_LEN);
+ get_token(fd, tmp_token, MAX_TOKEN_LEN);
+ if (sscanf(tmp_token, "%02d:%02d:%02d", &m, &s, &f) < 3)
+ {
+ RARCH_LOG("Error parsing time stamp '%s'\n", tmp_token);
+ return -errno;
+ }
+ *offset = ((m * 60) * (s * 75) * f) * 25;
+
+ RARCH_LOG("Found 1st data track on file '%s+%d'\n",
+ track_path, *offset);
+
+ rv = 0;
+ goto clean;
+ }
+ }
+
+ rv = -EINVAL;
+
+clean:
+ close(fd);
+ return rv;
+}
diff --git a/tasks/tasks.h b/tasks/tasks.h
index 3f46225d62..961636ee81 100644
--- a/tasks/tasks.h
+++ b/tasks/tasks.h
@@ -23,6 +23,8 @@
#include "../runloop_data.h"
+#define MAX_TOKEN_LEN 255
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -102,6 +104,14 @@ void rarch_main_data_nbio_iterate(bool is_thread);
void data_runloop_osd_msg(const char *s, size_t len);
+int find_first_data_track(const char* cue_path,
+ int32_t* offset, char* track_path, size_t max_len);
+
+int detect_system(const char* track_path, int32_t offset,
+ const char** system_name);
+
+int detect_ps1_game(const char *track_path, char *game_id);
+
#ifdef __cplusplus
}
#endif