From 0dd7ea2d712944b21ede9f57bebd1009b03932e6 Mon Sep 17 00:00:00 2001 From: Miika Pekkarinen Date: Fri, 10 Nov 2006 08:03:33 +0000 Subject: [PATCH] Support building tagcache db natively on PC using the core of the Rockbox tagcache database engine. Only host endian support at the moment and no command line parameters. Mainly for developers for debugging at the moment. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11497 a1c6a512-1295-4272-9138-f99709370657 --- apps/settings.h | 6 + apps/tagcache.c | 270 ++++++++++++++++++++++-------------- apps/tagcache.h | 9 +- firmware/common/dircache.c | 23 +-- firmware/export/config.h | 2 + firmware/export/debug.h | 2 +- firmware/export/logf.h | 10 +- firmware/id3.c | 12 +- firmware/include/dir.h | 2 +- firmware/include/dircache.h | 2 +- firmware/logf.c | 17 ++- firmware/mp3data.c | 5 + tools/Makefile | 9 +- tools/database.c | 13 ++ uisimulator/common/io.c | 53 ++++++- 15 files changed, 298 insertions(+), 137 deletions(-) create mode 100644 tools/database.c diff --git a/apps/settings.h b/apps/settings.h index 079fd29649..7b70ab748c 100644 --- a/apps/settings.h +++ b/apps/settings.h @@ -37,8 +37,14 @@ #include "backlight.h" /* for [MIN|MAX]_BRIGHTNESS_SETTING */ #endif +#ifdef __PCTOOL__ +#define ROCKBOX_DIR "." +#define ROCKBOX_DIR_LEN 1 +#else #define ROCKBOX_DIR "/.rockbox" #define ROCKBOX_DIR_LEN 9 +#endif + #define FONT_DIR ROCKBOX_DIR "/fonts" #define LANG_DIR ROCKBOX_DIR "/langs" #define WPS_DIR ROCKBOX_DIR "/wps" diff --git a/apps/tagcache.c b/apps/tagcache.c index d8684bd989..4739291aa8 100644 --- a/apps/tagcache.c +++ b/apps/tagcache.c @@ -61,26 +61,37 @@ #include "logf.h" #include "string.h" #include "usb.h" -#include "dircache.h" #include "metadata.h" #include "id3.h" -#include "settings.h" -#include "splash.h" -#include "lang.h" #include "tagcache.h" #include "buffer.h" -#include "atoi.h" #include "crc32.h" -#include "eeprom_settings.h" #include "misc.h" +#include "settings.h" +#include "dircache.h" +#ifndef __PCTOOL__ +#include "atoi.h" +#include "splash.h" +#include "lang.h" +#include "eeprom_settings.h" +#endif +#ifdef __PCTOOL__ +#include +#define yield() do { } while(0) +#define sim_sleep(timeout) do { } while(0) +#endif + + +#ifndef __PCTOOL__ /* Tag Cache thread. */ static struct event_queue tagcache_queue; static long tagcache_stack[(DEFAULT_STACK_SIZE + 0x4000)/sizeof(long)]; static const char tagcache_thread_name[] = "tagcache"; +#endif /* Previous path when scanning directory tree recursively. */ -static char curpath[MAX_PATH*2]; +static char curpath[TAG_MAXLEN+32]; static long curpath_size = sizeof(curpath); /* Used when removing duplicates. */ @@ -105,7 +116,7 @@ static const char *tags_str[] = { "artist", "album", "genre", "title", "playcount", "playtime", "lastplayed" }; /* Status information of the tagcache. */ -static struct tagcache_stat stat; +static struct tagcache_stat tc_stat; /* Queue commands. */ enum tagcache_queue { @@ -158,7 +169,7 @@ struct ramcache_header { # ifdef HAVE_EEPROM_SETTINGS struct statefile_header { struct ramcache_header *hdr; - struct tagcache_stat stat; + struct tagcache_stat tc_stat; }; # endif @@ -275,8 +286,8 @@ static int open_tag_fd(struct tagcache_header *hdr, int tag, bool write) fd = open(buf, write ? O_RDWR : O_RDONLY); if (fd < 0) { - logf("tag file open failed: %d", tag); - stat.ready = false; + logf("tag file open failed: tag=%d write=%d file=%s", tag, write, buf); + tc_stat.ready = false; return fd; } @@ -285,7 +296,7 @@ static int open_tag_fd(struct tagcache_header *hdr, int tag, bool write) if (hdr->magic != TAGCACHE_MAGIC || rc != sizeof(struct tagcache_header)) { logf("header error"); - stat.ready = false; + tc_stat.ready = false; close(fd); return -2; } @@ -302,7 +313,7 @@ static long find_entry_ram(const char *filename, int i; /* Check if we tagcache is loaded into ram. */ - if (!stat.ramcache) + if (!tc_stat.ramcache) return -1; if (dc == NULL) @@ -355,11 +366,11 @@ static long find_entry_disk(const char *filename) bool found = false; struct tagfile_entry tfe; int fd; - char buf[MAX_PATH]; + char buf[TAG_MAXLEN+32]; int i; int pos = -1; - if (!stat.ready) + if (!tc_stat.ready) return -2; fd = filenametag_fd; @@ -443,7 +454,7 @@ static int find_index(const char *filename) long idx_id = -1; #if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE) - if (stat.ramcache && dircache_is_enabled()) + if (tc_stat.ramcache && dircache_is_enabled()) idx_id = find_entry_ram(filename, NULL); #endif @@ -457,7 +468,7 @@ bool tagcache_find_index(struct tagcache_search *tcs, const char *filename) { int idx_id; - if (!stat.ready) + if (!tc_stat.ready) return false; idx_id = find_index(filename); @@ -483,7 +494,7 @@ static bool get_index(int masterfd, int idxid, } #ifdef HAVE_TC_RAMCACHE - if (stat.ramcache && use_ram) + if (tc_stat.ramcache && use_ram) { if (hdr->indices[idxid].flag & FLAG_DELETED) return false; @@ -520,7 +531,7 @@ static bool write_index(int masterfd, int idxid, struct index_entry *idx) } #ifdef HAVE_TC_RAMCACHE - if (stat.ramcache) + if (tc_stat.ramcache) { memcpy(&hdr->indices[idxid], idx, sizeof(struct index_entry)); } @@ -660,7 +671,7 @@ long tagcache_get_numeric(const struct tagcache_search *tcs, int tag) { struct index_entry idx; - if (!stat.ready) + if (!tc_stat.ready) return false; if (!tagcache_is_numeric_tag(tag)) @@ -852,7 +863,7 @@ bool tagcache_check_clauses(struct tagcache_search *tcs, return check_clauses(tcs, &idx, clause, count); } -static bool add_uniqbuf(struct tagcache_search *tcs, long id) +static bool add_uniqbuf(struct tagcache_search *tcs, unsigned long id) { int i; @@ -984,8 +995,8 @@ static void remove_files(void) int i; char buf[MAX_PATH]; - stat.ready = false; - stat.ramcache = false; + tc_stat.ready = false; + tc_stat.ramcache = false; remove(TAGCACHE_FILE_MASTER); for (i = 0; i < TAG_COUNT; i++) { @@ -1007,7 +1018,7 @@ static int open_master_fd(struct master_header *hdr, bool write) if (fd < 0) { logf("master file open failed for R/W"); - stat.ready = false; + tc_stat.ready = false; return fd; } @@ -1016,7 +1027,7 @@ static int open_master_fd(struct master_header *hdr, bool write) if (hdr->tch.magic != TAGCACHE_MAGIC || rc != sizeof(struct master_header)) { logf("header error"); - stat.ready = false; + tc_stat.ready = false; close(fd); return -2; } @@ -1037,7 +1048,7 @@ bool tagcache_search(struct tagcache_search *tcs, int tag) sleep(1); memset(tcs, 0, sizeof(struct tagcache_search)); - if (stat.commit_step > 0 || !stat.ready) + if (tc_stat.commit_step > 0 || !tc_stat.ready) return false; tcs->position = sizeof(struct tagcache_header); @@ -1053,7 +1064,7 @@ bool tagcache_search(struct tagcache_search *tcs, int tag) #ifndef HAVE_TC_RAMCACHE tcs->ramsearch = false; #else - tcs->ramsearch = stat.ramcache; + tcs->ramsearch = tc_stat.ramcache; if (tcs->ramsearch) { tcs->entry_count = hdr->entry_count[tcs->type]; @@ -1146,11 +1157,11 @@ bool tagcache_search_add_clause(struct tagcache_search *tcs, static bool get_next(struct tagcache_search *tcs) { - static char buf[MAX_PATH]; + static char buf[TAG_MAXLEN+32]; struct tagfile_entry entry; long flag = 0; - if (!tcs->valid || !stat.ready) + if (!tcs->valid || !tc_stat.ready) return false; if (tcs->idxfd[tcs->type] < 0 && !tagcache_is_numeric_tag(tcs->type) @@ -1367,12 +1378,12 @@ bool tagcache_fill_tags(struct mp3entry *id3, const char *filename) struct index_entry *entry; int idx_id; - if (!stat.ready) + if (!tc_stat.ready) return false; /* Find the corresponding entry in tagcache. */ idx_id = find_entry_ram(filename, NULL); - if (idx_id < 0 || !stat.ramcache) + if (idx_id < 0 || !tc_stat.ramcache) return false; entry = &hdr->indices[idx_id]; @@ -1411,11 +1422,11 @@ static int check_if_empty(char **tag) } length = strlen(*tag); - if (length >= MAX_PATH-32) + if (length > TAG_MAXLEN) { logf("over length tag: %s", *tag); - *tag[MAX_PATH-32] = '\0'; - length = MAX_PATH-32; + length = TAG_MAXLEN; + *tag[length] = '\0'; } return length + 1; @@ -1440,17 +1451,26 @@ static void add_tagcache(char *path) char tracknumfix[3]; char *genrestr; int offset = 0; + int path_length = strlen(path); if (cachefd < 0) return ; + /* Check for overlength file path. */ + if (path_length > TAG_MAXLEN) + { + /* Path can't be shortened. */ + logf("Too long path: %s"); + return ; + } + /* Check if the file is supported. */ if (probe_file_format(path) == AFMT_UNKNOWN) return ; /* Check if the file is already cached. */ #if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE) - if (stat.ramcache && dircache_is_enabled()) + if (tc_stat.ramcache && dircache_is_enabled()) { if (find_entry_ram(path, dc) >= 0) return ; @@ -1552,7 +1572,7 @@ static bool tempbuf_insert(char *str, int id, int idx_id, bool unique) int i; unsigned crc32; unsigned *crcbuf = (unsigned *)&tempbuf[tempbuf_size-4]; - char buf[MAX_PATH]; + char buf[TAG_MAXLEN+32]; for (i = 0; str[i] != '\0' && i < (int)sizeof(buf)-1; i++) buf[i] = tolower(str[i]); @@ -1628,7 +1648,7 @@ static int compare(const void *p1, const void *p2) e2 = &e2[4]; */ - return strncasecmp(e1->str, e2->str, MAX_PATH); + return strncasecmp(e1->str, e2->str, TAG_MAXLEN); } static int tempbuf_sort(int fd) @@ -1853,7 +1873,7 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd) struct master_header tcmh; struct index_entry idxbuf[IDX_BUF_DEPTH]; int idxbuf_pos; - char buf[MAX_PATH]; + char buf[TAG_MAXLEN+32]; int fd = -1, masterfd; bool error = false; int init; @@ -2031,7 +2051,7 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd) if (masterfd < 0) { - logf("Failure to create index file"); + logf("Failure to create index file (%s)", TAGCACHE_FILE_MASTER); close(fd); return -2; } @@ -2349,6 +2369,7 @@ static bool commit(void) return true; } + /* Load the header. */ len = sizeof(struct tagcache_header); rc = read(tmpfd, &tch, len); @@ -2375,7 +2396,7 @@ static bool commit(void) /* At first be sure to unload the ramcache! */ #ifdef HAVE_TC_RAMCACHE - stat.ramcache = false; + tc_stat.ramcache = false; #endif read_lock++; @@ -2399,10 +2420,10 @@ static bool commit(void) #endif #ifdef HAVE_TC_RAMCACHE - if (tempbuf_size == 0 && stat.ramcache_allocated > 0) + if (tempbuf_size == 0 && tc_stat.ramcache_allocated > 0) { tempbuf = (char *)(hdr + 1); - tempbuf_size = stat.ramcache_allocated - sizeof(struct ramcache_header) - 128; + tempbuf_size = tc_stat.ramcache_allocated - sizeof(struct ramcache_header) - 128; tempbuf_size &= ~0x03; } #endif @@ -2411,7 +2432,7 @@ static bool commit(void) if (tempbuf_size == 0) { logf("delaying commit until next boot"); - stat.commit_delayed = true; + tc_stat.commit_delayed = true; close(tmpfd); read_lock--; return false; @@ -2420,9 +2441,9 @@ static bool commit(void) logf("commit %d entries...", tch.entry_count); /* Now create the index files. */ - stat.commit_step = 0; + tc_stat.commit_step = 0; tch.datasize = 0; - stat.commit_delayed = false; + tc_stat.commit_delayed = false; for (i = 0; i < TAG_COUNT; i++) { @@ -2431,7 +2452,7 @@ static bool commit(void) if (tagcache_is_numeric_tag(i)) continue; - stat.commit_step++; + tc_stat.commit_step++; ret = build_index(i, &tch, tmpfd); if (ret <= 0) { @@ -2440,8 +2461,8 @@ static bool commit(void) if (ret < 0) remove_files(); else - stat.commit_delayed = true; - stat.commit_step = 0; + tc_stat.commit_delayed = true; + tc_stat.commit_step = 0; read_lock--; return false; } @@ -2449,7 +2470,7 @@ static bool commit(void) build_numeric_indices(&tch, tmpfd); close(tmpfd); - stat.commit_step = 0; + tc_stat.commit_step = 0; /* Update the master index headers. */ if ( (masterfd = open_master_fd(&tcmh, true)) < 0) @@ -2469,7 +2490,7 @@ static bool commit(void) logf("tagcache committed"); remove(TAGCACHE_FILE_TEMP); - stat.ready = true; + tc_stat.ready = true; if (local_allocation) { @@ -2485,7 +2506,7 @@ static bool commit(void) #ifdef HAVE_TC_RAMCACHE /* Reload tagcache. */ - if (stat.ramcache_allocated > 0) + if (tc_stat.ramcache_allocated > 0) tagcache_start_scan(); #endif @@ -2497,9 +2518,14 @@ static bool commit(void) static void allocate_tempbuf(void) { /* Yeah, malloc would be really nice now :) */ +#ifdef __PCTOOL__ + tempbuf_size = 32*1024*1024; + tempbuf = malloc(tempbuf_size); +#else tempbuf = (char *)(((long)audiobuf & ~0x03) + 0x04); tempbuf_size = (long)audiobufend - (long)audiobuf - 4; audiobuf += tempbuf_size; +#endif } static void free_tempbuf(void) @@ -2507,7 +2533,11 @@ static void free_tempbuf(void) if (tempbuf_size == 0) return ; +#ifdef __PCTOOL__ + free(tempbuf); +#else audiobuf -= tempbuf_size; +#endif tempbuf = NULL; tempbuf_size = 0; } @@ -2538,7 +2568,7 @@ static bool update_current_serial(long serial) long tagcache_increase_serial(void) { - if (!stat.ready) + if (!tc_stat.ready) return -2; while (read_lock) @@ -2559,7 +2589,7 @@ static bool modify_numeric_entry(int masterfd, int idx_id, int tag, long data) { struct index_entry idx; - if (!stat.ready) + if (!tc_stat.ready) return false; if (!tagcache_is_numeric_tag(tag)) @@ -2691,7 +2721,7 @@ static bool read_tag(char *dest, long size, static int parse_changelog_line(int line_n, const char *buf, void *parameters) { struct index_entry idx; - char tag_data[MAX_PATH]; + char tag_data[TAG_MAXLEN+32]; int idx_id; long masterfd = (long)parameters; const int import_tags[] = { tag_playcount, tag_playtime, tag_lastplayed }; @@ -2752,6 +2782,7 @@ static int parse_changelog_line(int line_n, const char *buf, void *parameters) return write_index(masterfd, idx_id, &idx) ? 0 : -5; } +#ifndef __PCTOOL__ bool tagcache_import_changelog(void) { struct master_header myhdr; @@ -2760,7 +2791,7 @@ bool tagcache_import_changelog(void) long masterfd; char buf[2048]; - if (!stat.ready) + if (!tc_stat.ready) return false; while (read_lock) @@ -2798,17 +2829,18 @@ bool tagcache_import_changelog(void) return true; } +#endif bool tagcache_create_changelog(struct tagcache_search *tcs) { struct master_header myhdr; struct index_entry idx; - char buf[MAX_PATH]; + char buf[TAG_MAXLEN+32]; char temp[32]; int clfd; int i, j; - if (!stat.ready) + if (!tc_stat.ready) return false; if (!tagcache_search(tcs, tag_filename)) @@ -2882,7 +2914,7 @@ static bool delete_entry(long idx_id) int tag, i; struct index_entry idx, myidx; struct master_header myhdr; - char buf[MAX_PATH]; + char buf[TAG_MAXLEN+32]; int in_use[TAG_COUNT]; logf("delete_entry(): %d", idx_id); @@ -2987,6 +3019,7 @@ static bool delete_entry(long idx_id) return true; } +#ifndef __PCTOOL__ /** * Returns true if there is an event waiting in the queue * that requires the current operation to be aborted. @@ -3008,6 +3041,7 @@ static bool check_event_queue(void) return false; } +#endif #ifdef HAVE_TC_RAMCACHE static bool allocate_tagcache(void) @@ -3028,13 +3062,13 @@ static bool allocate_tagcache(void) * Now calculate the required cache size plus * some extra space for alignment fixes. */ - stat.ramcache_allocated = tcmh.tch.datasize + 128 + TAGCACHE_RESERVE + + tc_stat.ramcache_allocated = tcmh.tch.datasize + 128 + TAGCACHE_RESERVE + sizeof(struct ramcache_header) + TAG_COUNT*sizeof(void *); - hdr = buffer_alloc(stat.ramcache_allocated + 128); + hdr = buffer_alloc(tc_stat.ramcache_allocated + 128); memset(hdr, 0, sizeof(struct ramcache_header)); memcpy(&hdr->h, &tcmh, sizeof(struct master_header)); hdr->indices = (struct index_entry *)(hdr + 1); - logf("tagcache: %d bytes allocated.", stat.ramcache_allocated); + logf("tagcache: %d bytes allocated.", tc_stat.ramcache_allocated); return true; } @@ -3069,18 +3103,18 @@ static bool tagcache_dumpload(void) offpos = (long)hdr - (long)shdr.hdr; /* Lets allocate real memory and load it */ - hdr = buffer_alloc(shdr.stat.ramcache_allocated); - rc = read(fd, hdr, shdr.stat.ramcache_allocated); + hdr = buffer_alloc(shdr.tc_stat.ramcache_allocated); + rc = read(fd, hdr, shdr.tc_stat.ramcache_allocated); close(fd); - if (rc != shdr.stat.ramcache_allocated) + if (rc != shdr.tc_stat.ramcache_allocated) { logf("read failure!"); hdr = NULL; return false; } - memcpy(&stat, &shdr.stat, sizeof(struct tagcache_stat)); + memcpy(&tc_stat, &shdr.tc_stat, sizeof(struct tagcache_stat)); /* Now fix the pointers */ hdr->indices = (struct index_entry *)((long)hdr->indices + offpos); @@ -3095,7 +3129,7 @@ static bool tagcache_dumpsave(void) struct statefile_header shdr; int fd; - if (!stat.ramcache) + if (!tc_stat.ramcache) return false; fd = open(TAGCACHE_STATEFILE, O_WRONLY | O_CREAT | O_TRUNC); @@ -3107,11 +3141,11 @@ static bool tagcache_dumpsave(void) /* Create the header */ shdr.hdr = hdr; - memcpy(&shdr.stat, &stat, sizeof(struct tagcache_stat)); + memcpy(&shdr.tc_stat, &tc_stat, sizeof(struct tagcache_stat)); write(fd, &shdr, sizeof(struct statefile_header)); /* And dump the data too */ - write(fd, hdr, stat.ramcache_allocated); + write(fd, hdr, tc_stat.ramcache_allocated); close(fd); return true; @@ -3121,7 +3155,7 @@ static bool tagcache_dumpsave(void) static bool load_tagcache(void) { struct tagcache_header *tch; - long bytesleft = stat.ramcache_allocated; + long bytesleft = tc_stat.ramcache_allocated; struct index_entry *idx; int rc, fd; char *p; @@ -3164,7 +3198,7 @@ static bool load_tagcache(void) } bytesleft -= sizeof(struct index_entry); - if (bytesleft < 0 || ((long)idx - (long)hdr->indices) >= stat.ramcache_allocated) + if (bytesleft < 0 || ((long)idx - (long)hdr->indices) >= tc_stat.ramcache_allocated) { logf("too big tagcache."); close(fd); @@ -3181,7 +3215,7 @@ static bool load_tagcache(void) for (tag = 0; tag < TAG_COUNT; tag++) { struct tagfile_entry *fe; - char buf[MAX_PATH]; + char buf[TAG_MAXLEN+32]; if (tagcache_is_numeric_tag(tag)) continue ; @@ -3341,7 +3375,7 @@ static bool load_tagcache(void) close(fd); } - stat.ramcache_used = stat.ramcache_allocated - bytesleft; + tc_stat.ramcache_used = tc_stat.ramcache_allocated - bytesleft; logf("tagcache loaded into ram!"); return true; @@ -3351,7 +3385,7 @@ static bool load_tagcache(void) static bool check_deleted_files(void) { int fd, testfd; - char buf[MAX_PATH]; + char buf[TAG_MAXLEN+32]; struct tagfile_entry tfe; logf("reverse scan..."); @@ -3366,7 +3400,11 @@ static bool check_deleted_files(void) lseek(fd, sizeof(struct tagcache_header), SEEK_SET); while (read(fd, &tfe, sizeof(struct tagfile_entry)) - == sizeof(struct tagfile_entry) && !check_event_queue()) + == sizeof(struct tagfile_entry) +#ifndef __PCTOOL__ + && !check_event_queue() +#endif + ) { if (tfe.tag_length >= (long)sizeof(buf)-1) { @@ -3414,7 +3452,11 @@ static bool check_dir(const char *dirname) } /* Recursively scan the dir. */ +#ifdef __PCTOOL__ + while (1) +#else while (!check_event_queue()) +#endif { struct dircache_entry *entry; @@ -3426,8 +3468,8 @@ static bool check_dir(const char *dirname) break ; } - if (!strcmp(entry->d_name, ".") || - !strcmp(entry->d_name, "..")) + if (!strcmp((char *)entry->d_name, ".") || + !strcmp((char *)entry->d_name, "..")) continue; yield(); @@ -3454,7 +3496,7 @@ static bool check_dir(const char *dirname) return success; } -static void build_tagcache(void) +void build_tagcache(const char *path) { struct tagcache_header header; bool ret; @@ -3482,7 +3524,7 @@ static void build_tagcache(void) cachefd = open(TAGCACHE_FILE_TEMP, O_RDWR | O_CREAT | O_TRUNC); if (cachefd < 0) { - logf("master file open failed"); + logf("master file open failed: %s", TAGCACHE_FILE_TEMP); return ; } @@ -3490,12 +3532,13 @@ static void build_tagcache(void) cpu_boost_id(true, CPUBOOSTID_TAGCACHE); + logf("Scanning files..."); /* Scan for new files. */ memset(&header, 0, sizeof(struct tagcache_header)); write(cachefd, &header, sizeof(struct tagcache_header)); - //strcpy(curpath, "/Best"); - ret = check_dir("/"); + strcpy(curpath, path); + ret = check_dir(path); /* Write the header. */ header.magic = TAGCACHE_MAGIC; @@ -3519,11 +3562,17 @@ static void build_tagcache(void) } /* Commit changes to the database. */ +#ifdef __PCTOOL__ + allocate_tempbuf(); +#endif if (commit()) { remove(TAGCACHE_FILE_TEMP); logf("tagcache built!"); } +#ifdef __PCTOOL__ + free_tempbuf(); +#endif #ifdef HAVE_TC_RAMCACHE if (hdr) @@ -3546,13 +3595,13 @@ static void load_ramcache(void) cpu_boost_id(true, CPUBOOSTID_TAGCACHE); /* At first we should load the cache (if exists). */ - stat.ramcache = load_tagcache(); + tc_stat.ramcache = load_tagcache(); - if (!stat.ramcache) + if (!tc_stat.ramcache) { /* If loading failed, it must indicate some problem with the db * so disable it entirely to prevent further issues. */ - stat.ready = false; + tc_stat.ready = false; hdr = NULL; } @@ -3561,7 +3610,7 @@ static void load_ramcache(void) void tagcache_unload_ramcache(void) { - stat.ramcache = false; + tc_stat.ramcache = false; /* Just to make sure there is no statefile present. */ // remove(TAGCACHE_STATEFILE); } @@ -3594,6 +3643,7 @@ static bool check_all_headers(void) return true; } +#ifndef __PCTOOL__ static void tagcache_thread(void) { struct event ev; @@ -3615,16 +3665,16 @@ static void tagcache_thread(void) # endif /* Allocate space for the tagcache if found on disk. */ - if (global_settings.tagcache_ram && !stat.ramcache) + if (global_settings.tagcache_ram && !tc_stat.ramcache) allocate_tagcache(); #endif cpu_boost_id(false, CPUBOOSTID_TAGCACHE); - stat.initialized = true; + tc_stat.initialized = true; /* Don't delay bootup with the header check but do it on background. */ sleep(HZ); - stat.ready = check_all_headers(); + tc_stat.ready = check_all_headers(); while (1) { @@ -3638,11 +3688,11 @@ static void tagcache_thread(void) case Q_REBUILD: remove_files(); - build_tagcache(); + build_tagcache("/"); break; case Q_UPDATE: - build_tagcache(); + build_tagcache("/"); #ifdef HAVE_TC_RAMCACHE load_ramcache(); #endif @@ -3652,21 +3702,21 @@ static void tagcache_thread(void) case Q_START_SCAN: check_done = false; case SYS_TIMEOUT: - if (check_done || !stat.ready) + if (check_done || !tc_stat.ready) break ; #ifdef HAVE_TC_RAMCACHE - if (!stat.ramcache && global_settings.tagcache_ram) + if (!tc_stat.ramcache && global_settings.tagcache_ram) { load_ramcache(); - if (stat.ramcache && global_settings.tagcache_autoupdate) - build_tagcache(); + if (tc_stat.ramcache && global_settings.tagcache_autoupdate) + build_tagcache("/"); } else #endif if (global_settings.tagcache_autoupdate) { - build_tagcache(); + build_tagcache("/"); /* Don't do auto removal without dircache (very slow). */ #ifdef HAVE_DIRCACHE if (dircache_is_enabled()) @@ -3711,7 +3761,7 @@ bool tagcache_prepare_shutdown(void) void tagcache_shutdown(void) { #ifdef HAVE_EEPROM_SETTINGS - if (stat.ramcache) + if (tc_stat.ramcache) tagcache_dumpsave(); #endif } @@ -3729,7 +3779,7 @@ static int get_progress(void) #endif #ifdef HAVE_TC_RAMCACHE { - if (hdr && stat.ramcache) + if (hdr && tc_stat.ramcache) total_count = hdr->h.tch.entry_count; } #endif @@ -3742,12 +3792,12 @@ static int get_progress(void) struct tagcache_stat* tagcache_get_stat(void) { - stat.progress = get_progress(); - stat.processed_entries = processed_dir_count; + tc_stat.progress = get_progress(); + tc_stat.processed_entries = processed_dir_count; - return &stat; + return &tc_stat; } - + void tagcache_start_scan(void) { queue_post(&tagcache_queue, Q_START_SCAN, 0); @@ -3755,7 +3805,7 @@ void tagcache_start_scan(void) bool tagcache_update(void) { - if (!stat.ready) + if (!tc_stat.ready) return false; queue_post(&tagcache_queue, Q_UPDATE, 0); @@ -3780,31 +3830,41 @@ void tagcache_stop_scan(void) #ifdef HAVE_TC_RAMCACHE bool tagcache_is_ramcache(void) { - return stat.ramcache; + return tc_stat.ramcache; } #endif +#endif /* !__PCTOOL__ */ + void tagcache_init(void) { - memset(&stat, 0, sizeof(struct tagcache_stat)); + memset(&tc_stat, 0, sizeof(struct tagcache_stat)); filenametag_fd = -1; current_serial = 0; write_lock = read_lock = 0; +#ifndef __PCTOOL__ queue_init(&tagcache_queue, true); create_thread(tagcache_thread, tagcache_stack, sizeof(tagcache_stack), tagcache_thread_name IF_PRIO(, PRIORITY_BACKGROUND)); +#else + tc_stat.initialized = true; + allocate_tempbuf(); + commit(); + free_tempbuf(); + tc_stat.ready = check_all_headers(); +#endif } bool tagcache_is_initialized(void) { - return stat.initialized; + return tc_stat.initialized; } int tagcache_get_commit_step(void) { - return stat.commit_step; + return tc_stat.commit_step; } diff --git a/apps/tagcache.h b/apps/tagcache.h index f1819855db..ea4d255630 100644 --- a/apps/tagcache.h +++ b/apps/tagcache.h @@ -30,6 +30,9 @@ enum tag_type { tag_artist = 0, tag_album, tag_genre, tag_title, #define TAG_COUNT 13 +/* Maximum length of a single tag. */ +#define TAG_MAXLEN (MAX_PATH*2) + /* Allow a little drift to the filename ordering (should not be too high/low). */ #define POS_HISTORY_COUNT 4 @@ -119,7 +122,7 @@ struct tagcache_search { int entry_count; bool valid; bool initialized; - long *unique_list; + unsigned long *unique_list; int unique_list_capacity; int unique_list_count; @@ -133,6 +136,10 @@ struct tagcache_search { int idx_id; }; +#ifdef __PCTOOL__ +void build_tagcache(const char *path); +#endif + int tagcache_str_to_tag(const char *str); const char* tagcache_tag_to_str(int tag); diff --git a/firmware/common/dircache.c b/firmware/common/dircache.c index 7222a41221..7227704ffc 100644 --- a/firmware/common/dircache.c +++ b/firmware/common/dircache.c @@ -57,7 +57,7 @@ static unsigned long dircache_size = 0; static unsigned long entry_count = 0; static unsigned long reserve_used = 0; static unsigned int cache_build_ticks = 0; -static char dircache_cur_path[MAX_PATH]; +static char dircache_cur_path[MAX_PATH*2]; static struct event_queue dircache_queue; static long dircache_stack[(DEFAULT_STACK_SIZE + 0x800)/sizeof(long)]; @@ -178,7 +178,7 @@ static int dircache_scan(struct travel_data *td) } td->ce->attribute = td->entry->attribute; - td->ce->name_len = MIN(254, strlen(td->entry->d_name)) + 1; + td->ce->name_len = strlen(td->entry->d_name); td->ce->d_name = ((char *)dircache_root+dircache_size); td->ce->size = td->entry->size; td->ce->wrtdate = td->entry->wrtdate; @@ -192,7 +192,7 @@ static int dircache_scan(struct travel_data *td) } td->ce->attribute = td->entry.attr; - td->ce->name_len = MIN(254, strlen(td->entry.name)) + 1; + td->ce->name_len = strlen(td->entry.name) + 1; td->ce->d_name = ((char *)dircache_root+dircache_size); td->ce->startcluster = td->entry.firstcluster; td->ce->size = td->entry.filesize; @@ -215,9 +215,11 @@ static int dircache_scan(struct travel_data *td) return -2; td->pathpos = strlen(dircache_cur_path); - strncpy(&dircache_cur_path[td->pathpos], "/", MAX_PATH - td->pathpos - 1); + strncpy(&dircache_cur_path[td->pathpos], "/", + sizeof(dircache_cur_path) - td->pathpos - 1); #ifdef SIMULATOR - strncpy(&dircache_cur_path[td->pathpos+1], td->entry->d_name, MAX_PATH - td->pathpos - 2); + strncpy(&dircache_cur_path[td->pathpos+1], td->entry->d_name, + sizeof(dircache_cur_path) - td->pathpos - 2); td->newdir = opendir(dircache_cur_path); if (td->newdir == NULL) @@ -226,7 +228,8 @@ static int dircache_scan(struct travel_data *td) return -3; } #else - strncpy(&dircache_cur_path[td->pathpos+1], td->entry.name, MAX_PATH - td->pathpos - 2); + strncpy(&dircache_cur_path[td->pathpos+1], td->entry.name, + sizeof(dircache_cur_path) - td->pathpos - 2); td->newdir = *td->dir; if (fat_opendir(IF_MV2(volume,) &td->newdir, @@ -360,7 +363,7 @@ static struct dircache_entry* dircache_get_entry(const char *path, bool get_before, bool only_directories) { struct dircache_entry *cache_entry, *before; - char namecopy[MAX_PATH]; + char namecopy[MAX_PATH*2]; char* part; char* end; @@ -543,7 +546,7 @@ static int dircache_do_rebuild(void) pdir = &dir; #endif - memset(dircache_cur_path, 0, MAX_PATH); + memset(dircache_cur_path, 0, sizeof(dircache_cur_path)); dircache_size = sizeof(struct dircache_entry); cpu_boost_id(true, CPUBOOSTID_DIRCACHE); @@ -837,7 +840,7 @@ static int block_until_ready(void) static struct dircache_entry* dircache_new_entry(const char *path, int attribute) { struct dircache_entry *entry; - char basedir[MAX_PATH]; + char basedir[MAX_PATH*2]; char *new; long last_cache_size = dircache_size; @@ -1005,7 +1008,7 @@ void dircache_rename(const char *oldpath, const char *newpath) { /* Test ok. */ struct dircache_entry *entry, *newentry; struct dircache_entry oldentry; - char absolute_path[MAX_PATH]; + char absolute_path[MAX_PATH*2]; char *p; if (block_until_ready()) diff --git a/firmware/export/config.h b/firmware/export/config.h index 18c0ef7d17..45d974a96f 100644 --- a/firmware/export/config.h +++ b/firmware/export/config.h @@ -20,7 +20,9 @@ #ifndef __CONFIG_H__ #define __CONFIG_H__ +#ifndef __PCTOOL__ #include "autoconf.h" +#endif /* symbolic names for multiple choice configurations: */ diff --git a/firmware/export/debug.h b/firmware/export/debug.h index 52b6687c6b..ce556d6418 100644 --- a/firmware/export/debug.h +++ b/firmware/export/debug.h @@ -26,7 +26,7 @@ extern void ldebugf(const char* file, int line, const char *fmt, ...); #ifdef __GNUC__ /* */ -#if defined(SIMULATOR) +#if defined(SIMULATOR) && !defined(__PCTOOL__) #define DEBUGF debugf #define LDEBUGF(...) ldebugf(__FILE__, __LINE__, __VA_ARGS__) #else diff --git a/firmware/export/logf.h b/firmware/export/logf.h index 4206173596..35cb7127e4 100644 --- a/firmware/export/logf.h +++ b/firmware/export/logf.h @@ -23,6 +23,7 @@ #ifdef ROCKBOX_HAS_LOGF +#ifndef __PCTOOL__ #define MAX_LOGF_LINES 1000 #define MAX_LOGF_ENTRY 30 #define MAX_LOGF_DATASIZE (MAX_LOGF_ENTRY*MAX_LOGF_LINES) @@ -30,11 +31,14 @@ extern unsigned char logfbuffer[MAX_LOGF_LINES][MAX_LOGF_ENTRY]; extern int logfindex; extern bool logfwrap; +#endif /* __PCTOOL__ */ -void logf(const char *format, ...); -#else +#define logf _logf +void _logf(const char *format, ...); + +#else /* !ROCKBOX_HAS_LOGF */ /* built without logf() support enabled */ #define logf(...) -#endif +#endif /* !ROCKBOX_HAS_LOGF */ #endif /* LOGF_H */ diff --git a/firmware/id3.c b/firmware/id3.c index 470f4dc352..90b5b3bdee 100644 --- a/firmware/id3.c +++ b/firmware/id3.c @@ -457,9 +457,9 @@ static int unicode_munge(char* string, char* utf8buf, int *len) { long tmp; bool le = false; int i = 0; - char *str = string; + unsigned char *str = (unsigned char *)string; int templen = 0; - char* utf8 = utf8buf; + unsigned char* utf8 = (unsigned char *)utf8buf; switch (str[0]) { case 0x00: /* Type 0x00 is ordinary ISO 8859-1 */ @@ -467,7 +467,7 @@ static int unicode_munge(char* string, char* utf8buf, int *len) { (*len)--; utf8 = iso_decode(str, utf8, -1, *len); *utf8 = 0; - *len = utf8 - utf8buf; + *len = (unsigned long)utf8 - (unsigned long)utf8buf; break; case 0x01: /* Unicode with or without BOM */ @@ -524,7 +524,7 @@ static int unicode_munge(char* string, char* utf8buf, int *len) { default: /* Plain old string */ utf8 = iso_decode(str, utf8, -1, *len); *utf8 = 0; - *len = utf8 - utf8buf; + *len = (unsigned long)utf8 - (unsigned long)utf8buf; break; } return 0; @@ -571,7 +571,7 @@ static bool setid3v1title(int fd, struct mp3entry *entry) case 1: case 2: /* convert string to utf8 */ - utf8 = entry->id3v1buf[i]; + utf8 = (unsigned char *)entry->id3v1buf[i]; utf8 = iso_decode(ptr, utf8, -1, 30); /* make sure string is terminated */ *utf8 = 0; @@ -579,7 +579,7 @@ static bool setid3v1title(int fd, struct mp3entry *entry) case 3: ptr[4] = 0; - entry->year = atoi(ptr); + entry->year = atoi((char *)ptr); break; case 4: diff --git a/firmware/include/dir.h b/firmware/include/dir.h index 948b30ffe2..c10640199f 100644 --- a/firmware/include/dir.h +++ b/firmware/include/dir.h @@ -20,7 +20,7 @@ #define _DIR_H_ #include -#include +#include "file.h" #define ATTR_READ_ONLY 0x01 #define ATTR_HIDDEN 0x02 diff --git a/firmware/include/dircache.h b/firmware/include/dircache.h index f6bc153faf..9c3bc68ddc 100644 --- a/firmware/include/dircache.h +++ b/firmware/include/dircache.h @@ -67,7 +67,7 @@ struct dircache_entry { long startcluster; unsigned short wrtdate; unsigned short wrttime; - unsigned char name_len; + unsigned long name_len; char *d_name; }; diff --git a/firmware/logf.c b/firmware/logf.c index fc57bd85bf..2056db5cc4 100644 --- a/firmware/logf.c +++ b/firmware/logf.c @@ -27,7 +27,6 @@ #include #include #include -#include #include "config.h" #include "lcd-remote.h" #include "logf.h" @@ -36,9 +35,11 @@ /* Only provide all this if asked to */ #ifdef ROCKBOX_HAS_LOGF +#ifndef __PCTOOL__ unsigned char logfbuffer[MAX_LOGF_LINES][MAX_LOGF_ENTRY]; int logfindex; bool logfwrap; +#endif #ifdef HAVE_REMOTE_LCD static void displayremote(void) @@ -77,7 +78,18 @@ static void displayremote(void) #define displayremote() #endif -void logf(const char *format, ...) +#ifdef __PCTOOL__ +void _logf(const char *format, ...) +{ + char buf[1024]; + va_list ap; + va_start(ap, format); + + vsnprintf(buf, sizeof buf, format, ap); + printf("DEBUG: %s\n", buf); +} +#else +void _logf(const char *format, ...) { int len; unsigned char *ptr; @@ -104,5 +116,6 @@ void logf(const char *format, ...) displayremote(); } +#endif #endif diff --git a/firmware/mp3data.c b/firmware/mp3data.c index 0710090b37..49b95f2d9e 100644 --- a/firmware/mp3data.c +++ b/firmware/mp3data.c @@ -242,6 +242,7 @@ unsigned long find_next_frame(int fd, long *offset, long max_offset, unsigned lo return __find_next_frame(fd, offset, max_offset, last_header, fileread); } +#ifndef __PCTOOL__ static int fnf_read_index; static int fnf_buf_len; @@ -335,6 +336,7 @@ unsigned long mem_find_next_frame(int startpos, long *offset, long max_offset, return __find_next_frame(0, offset, max_offset, last_header, mem_getbyte); } +#endif int get_mp3file_info(int fd, struct mp3info *info) { @@ -543,6 +545,7 @@ static void long2bytes(unsigned char *buf, long val) buf[3] = val & 0xff; } +#ifndef __PCTOOL__ int count_mp3_frames(int fd, int startpos, int filesize, void (*progressfunc)(int)) { @@ -762,3 +765,5 @@ int create_xing_header(int fd, long startpos, long filesize, return info.frame_size; } + +#endif diff --git a/tools/Makefile b/tools/Makefile index 1f8be87370..d6c885d85b 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -10,7 +10,7 @@ CFLAGS := -O -ansi -g LDFLAGS := -g CLEANALL := scramble descramble iriver sh2d bmp2rb rdf2binary convbdf \ - generate_rocklatin mkboot ipod_fw codepages uclpack mi4 gigabeat + generate_rocklatin mkboot ipod_fw codepages uclpack mi4 gigabeat database all: @echo "Run make in your build directory!" @@ -38,6 +38,13 @@ mkboot: mkboot.c ipod_fw: ipod_fw.c $(SILENT)$(CC) -g $+ -o $@ +database: database.c ../apps/tagcache.c ../apps/metadata.c \ +../firmware/id3.c ../firmware/common/unicode.c \ +../firmware/common/crc32.c ../uisimulator/common/io.c \ +../firmware/mp3data.c ../firmware/logf.c + $(SILENT)$(CC) -g -I../firmware/export -iquote ../firmware/include \ +-D__PCTOOL__ -DHAVE_TAGCACHE -DROCKBOX_HAS_LOGF -DSIMULATOR -ldl -I../apps $+ -o $@ + convbdf: convbdf.c $(SILENT)$(CC) -g $+ -o $@ diff --git a/tools/database.c b/tools/database.c new file mode 100644 index 0000000000..780586ea90 --- /dev/null +++ b/tools/database.c @@ -0,0 +1,13 @@ +/* A _very_ skeleton file to demonstrate building tagcache db on host. */ + +#include +#include "tagcache.h" + +int main(int argc, char **argv) +{ + tagcache_init(); + build_tagcache("/export/stuff/mp3"); + + return 0; +} + diff --git a/uisimulator/common/io.c b/uisimulator/common/io.c index c4f8840cc5..ca64affa8c 100644 --- a/uisimulator/common/io.c +++ b/uisimulator/common/io.c @@ -106,11 +106,14 @@ MYDIR *sim_opendir(const char *name) char buffer[256]; /* sufficiently big */ DIR *dir; - if(name[0] == '/') { +#ifndef __PCTOOL__ + if(name[0] == '/') + { sprintf(buffer, "%s%s", SIMULATOR_ARCHOS_ROOT, name); dir=(DIR *)opendir(buffer); } else +#endif dir=(DIR *)opendir(name); if(dir) { @@ -137,8 +140,12 @@ struct sim_dirent *sim_readdir(MYDIR *dir) strcpy((char *)secret.d_name, x11->d_name); /* build file name */ +#ifdef __PCTOOL__ + sprintf(buffer, "%s/%s", dir->name, x11->d_name); +#else sprintf(buffer, SIMULATOR_ARCHOS_ROOT "%s/%s", dir->name, x11->d_name); +#endif stat(buffer, &s); /* get info */ #define ATTR_DIRECTORY 0x10 @@ -164,22 +171,32 @@ int sim_open(const char *name, int o) char buffer[256]; /* sufficiently big */ int opts = rockbox2sim(o); - if(name[0] == '/') { +#ifndef __PCTOOL__ + if(name[0] == '/') + { sprintf(buffer, "%s%s", SIMULATOR_ARCHOS_ROOT, name); debugf("We open the real file '%s'\n", buffer); return open(buffer, opts, 0666); } + fprintf(stderr, "WARNING, bad file name lacks slash: %s\n", name); return -1; +#else + return open(name, opts, 0666); +#endif + } int sim_creat(const char *name, mode_t mode) { - char buffer[256]; /* sufficiently big */ int opts = rockbox2sim(mode); - if(name[0] == '/') { + +#ifndef __PCTOOL__ + char buffer[256]; /* sufficiently big */ + if(name[0] == '/') + { sprintf(buffer, "%s%s", SIMULATOR_ARCHOS_ROOT, name); debugf("We create the real file '%s'\n", buffer); @@ -188,12 +205,22 @@ int sim_creat(const char *name, mode_t mode) fprintf(stderr, "WARNING, bad file name lacks slash: %s\n", name); return -1; +#else + return open(name, opts | O_CREAT | O_TRUNC, 0666); +#endif } int sim_mkdir(const char *name, mode_t mode) { - char buffer[256]; /* sufficiently big */ (void)mode; +#ifdef __PCTOOL__ +# ifdef WIN32 + return mkdir(name); +# else + return mkdir(name, 0777); +# endif +#else + char buffer[256]; /* sufficiently big */ sprintf(buffer, "%s%s", SIMULATOR_ARCHOS_ROOT, name); @@ -204,22 +231,31 @@ int sim_mkdir(const char *name, mode_t mode) #else return mkdir(buffer, 0777); #endif +#endif } int sim_rmdir(const char *name) { +#ifdef __PCTOOL__ + return rmdir(name); +#else char buffer[256]; /* sufficiently big */ - if(name[0] == '/') { + if(name[0] == '/') + { sprintf(buffer, "%s%s", SIMULATOR_ARCHOS_ROOT, name); debugf("We remove the real directory '%s'\n", buffer); return rmdir(buffer); } return rmdir(name); +#endif } int sim_remove(const char *name) { +#ifdef __PCTOOL__ + return remove(name); +#else char buffer[256]; /* sufficiently big */ #ifdef HAVE_DIRCACHE @@ -233,10 +269,14 @@ int sim_remove(const char *name) return remove(buffer); } return remove(name); +#endif } int sim_rename(const char *oldpath, const char* newpath) { +#ifdef __PCTOOL__ + return rename(oldpath, newpath); +#else char buffer1[256]; char buffer2[256]; @@ -252,6 +292,7 @@ int sim_rename(const char *oldpath, const char* newpath) return rename(buffer1, buffer2); } return -1; +#endif } /* rockbox off_t may be different from system off_t */