From 812cbad890c5f891a27d6e827969424aa184bf2f Mon Sep 17 00:00:00 2001 From: Miika Pekkarinen Date: Wed, 4 Oct 2006 09:05:01 +0000 Subject: [PATCH] Fixed find_index returning incorrect entry unless entries are found. Commit all numeric tags at once and set a flag if tracknumber has been guessed. Cleaned up temporary file creation. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11122 a1c6a512-1295-4272-9138-f99709370657 --- apps/main.c | 4 +- apps/tagcache.c | 211 ++++++++++++++++++++++++++---------------------- apps/tagcache.h | 1 + 3 files changed, 119 insertions(+), 97 deletions(-) diff --git a/apps/main.c b/apps/main.c index 2ceb24d96f..a2bbe73e65 100644 --- a/apps/main.c +++ b/apps/main.c @@ -185,10 +185,10 @@ void init_tagcache(void) { #ifdef HAVE_LCD_BITMAP gui_syncsplash(0, true, "%s [%d/%d]", - str(LANG_TAGCACHE_INIT), ret, TAG_COUNT); + str(LANG_TAGCACHE_INIT), ret, 7); #else lcd_double_height(false); - snprintf(buf, sizeof(buf), " TC [%d/%d]", ret, TAG_COUNT); + snprintf(buf, sizeof(buf), " TC [%d/%d]", ret, 7); lcd_puts(0, 1, buf); #endif clear = true; diff --git a/apps/tagcache.c b/apps/tagcache.c index dbf58c69fa..042d27cc84 100644 --- a/apps/tagcache.c +++ b/apps/tagcache.c @@ -171,7 +171,8 @@ static struct ramcache_header *hdr; struct temp_file_entry { long tag_offset[TAG_COUNT]; short tag_length[TAG_COUNT]; - + long flag; + long data_length; }; @@ -448,9 +449,6 @@ static int find_index(const char *filename) if (idx_id < 0) idx_id = find_entry_disk(filename); - if (idx_id < 0) - return false; - return idx_id; } @@ -1327,18 +1325,37 @@ static inline void write_item(const char *item) write(cachefd, item, len); } -inline void check_if_empty(char **tag) +static int check_if_empty(char **tag) { - if (tag == NULL || *tag == NULL || *tag[0] == '\0') + int length; + + if (*tag == NULL || *tag[0] == '\0') + { *tag = ""; + return 11; /* Tag length */ + } + + length = strlen(*tag); + if (length >= MAX_PATH-32) + { + logf("over length tag: %s", *tag); + *tag[MAX_PATH-32] = '\0'; + length = MAX_PATH-32; + } + + return length + 1; } -#define CRC_BUF_LEN 8 - +#define ADD_TAG(entry,tag,data) \ + /* Adding tag */ \ + entry.tag_offset[tag] = offset; \ + entry.tag_length[tag] = check_if_empty(data); \ + offset += entry.tag_length[tag] + #if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE) -static void add_tagcache(const char *path, const struct dircache_entry *dc) +static void add_tagcache(char *path, const struct dircache_entry *dc) #else -static void add_tagcache(const char *path) +static void add_tagcache(char *path) #endif { struct track_info track; @@ -1347,7 +1364,7 @@ static void add_tagcache(const char *path) int fd; char tracknumfix[3]; char *genrestr; - //uint32_t crcbuf[CRC_BUF_LEN]; + int offset = 0; if (cachefd < 0) return ; @@ -1391,36 +1408,8 @@ static void add_tagcache(const char *path) logf("-> %s", path); - genrestr = id3_get_genre(&track.id3); - - check_if_empty(&track.id3.title); - check_if_empty(&track.id3.artist); - check_if_empty(&track.id3.album); - check_if_empty(&genrestr); - check_if_empty(&track.id3.composer); - - entry.tag_length[tag_filename] = strlen(path) + 1; - entry.tag_length[tag_title] = strlen(track.id3.title) + 1; - entry.tag_length[tag_artist] = strlen(track.id3.artist) + 1; - entry.tag_length[tag_album] = strlen(track.id3.album) + 1; - entry.tag_length[tag_genre] = strlen(genrestr) + 1; - entry.tag_length[tag_composer] = strlen(track.id3.composer) + 1; - - entry.tag_offset[tag_filename] = 0; - entry.tag_offset[tag_title] = entry.tag_offset[tag_filename] + entry.tag_length[tag_filename]; - entry.tag_offset[tag_artist] = entry.tag_offset[tag_title] + entry.tag_length[tag_title]; - entry.tag_offset[tag_album] = entry.tag_offset[tag_artist] + entry.tag_length[tag_artist]; - entry.tag_offset[tag_genre] = entry.tag_offset[tag_album] + entry.tag_length[tag_album]; - entry.tag_offset[tag_composer] = entry.tag_offset[tag_genre] + entry.tag_length[tag_genre]; - entry.data_length = entry.tag_offset[tag_composer] + entry.tag_length[tag_composer]; - - /* Numeric tags */ - entry.tag_offset[tag_year] = track.id3.year; - entry.tag_offset[tag_tracknumber] = track.id3.tracknum; - entry.tag_offset[tag_length] = track.id3.length; - entry.tag_offset[tag_bitrate] = track.id3.bitrate; - - if (entry.tag_offset[tag_tracknumber] <= 0) + /* Generate track number if missing. */ + if (track.id3.tracknum <= 0) { const char *p = strrchr(path, '.'); @@ -1439,12 +1428,39 @@ static void add_tagcache(const char *path) } if (tracknumfix[0] != '\0') - entry.tag_offset[tag_tracknumber] = atoi(tracknumfix); + { + track.id3.tracknum = atoi(tracknumfix); + /* Set a flag to indicate track number has been generated. */ + entry.flag |= FLAG_TRKNUMGEN; + } else - entry.tag_offset[tag_tracknumber] = -1; + { + /* Unable to generate track number. */ + track.id3.tracknum = -1; + } } + genrestr = id3_get_genre(&track.id3); + + /* Numeric tags */ + entry.tag_offset[tag_year] = track.id3.year; + entry.tag_offset[tag_tracknumber] = track.id3.tracknum; + entry.tag_offset[tag_length] = track.id3.length; + entry.tag_offset[tag_bitrate] = track.id3.bitrate; + + /* String tags. */ + ADD_TAG(entry, tag_filename, &path); + ADD_TAG(entry, tag_title, &track.id3.title); + ADD_TAG(entry, tag_artist, &track.id3.artist); + ADD_TAG(entry, tag_album, &track.id3.album); + ADD_TAG(entry, tag_genre, &genrestr); + ADD_TAG(entry, tag_composer, &track.id3.composer); + entry.data_length = offset; + + /* Write the header */ write(cachefd, &entry, sizeof(struct temp_file_entry)); + + /* And tags also... Correct order is critical */ write_item(path); write_item(track.id3.title); write_item(track.id3.artist); @@ -1659,47 +1675,22 @@ inline static int tempbuf_find_location(int id) return entry->seek; } -static bool build_numeric_index(int index_type, struct tagcache_header *h, int tmpfd) +static bool build_numeric_indices(struct tagcache_header *h, int tmpfd) { struct master_header tcmh; struct index_entry idx; int masterfd; int masterfd_pos; - long *databuf = (long *)tempbuf; + struct temp_file_entry *entrybuf = (struct temp_file_entry *)tempbuf; int max_entries; - int i; + int entries_processed = 0; + int i, j; - max_entries = tempbuf_size / sizeof(long); + max_entries = tempbuf_size / sizeof(struct temp_file_entry) - 1; - if (h->entry_count >= max_entries) - { - logf("not enough space!"); - return false; - } - - logf("Building numeric index: %d", index_type); - - /* Walk through the temporary file. */ + logf("Building numeric indices..."); lseek(tmpfd, sizeof(struct tagcache_header), SEEK_SET); - for (i = 0; i < h->entry_count; i++) - { - struct temp_file_entry entry; - - if (read(tmpfd, &entry, sizeof(struct temp_file_entry)) != - sizeof(struct temp_file_entry)) - { - logf("read fail #1"); - return false; - } - - /* Insert data in buffer. */ - databuf[i] = (long)entry.tag_offset[index_type]; - - /* Skip to next. */ - lseek(tmpfd, entry.data_length, SEEK_CUR); - } - /* Update the entries in index. */ if ( (masterfd = open_master_fd(&tcmh, true)) < 0) return false; @@ -1712,29 +1703,61 @@ static bool build_numeric_index(int index_type, struct tagcache_header *h, int t return false; } - for (i = 0; i < h->entry_count; i++) + while (entries_processed < h->entry_count) { - int loc = lseek(masterfd, 0, SEEK_CUR); - - if (read(masterfd, &idx, sizeof(struct index_entry)) != - sizeof(struct index_entry)) + int count = MIN(h->entry_count, max_entries); + + /* Read in as many entries as possible. */ + for (i = 0; i < count; i++) { - logf("read fail #2"); - close(masterfd); - return false; + /* Read in numeric data. */ + if (read(tmpfd, &entrybuf[i], sizeof(struct temp_file_entry)) != + sizeof(struct temp_file_entry)) + { + logf("read fail #1"); + close(masterfd); + return false; + } + + /* Skip string data. */ + lseek(tmpfd, entrybuf[i].data_length, SEEK_CUR); } - idx.tag_seek[index_type] = databuf[i]; - - /* Write back the updated index. */ - lseek(masterfd, loc, SEEK_SET); - if (write(masterfd, &idx, sizeof(struct index_entry)) != - sizeof(struct index_entry)) + /* Commit the data to the index. */ + for (i = 0; i < count; i++) { - logf("write fail"); - close(masterfd); - return false; + int loc = lseek(masterfd, 0, SEEK_CUR); + + if (read(masterfd, &idx, sizeof(struct index_entry)) != + sizeof(struct index_entry)) + { + logf("read fail #2"); + close(masterfd); + return false; + } + + for (j = 0; j < TAG_COUNT; j++) + { + if (!tagcache_is_numeric_tag(j)) + continue; + + idx.tag_seek[j] = entrybuf[i].tag_offset[j]; + } + idx.flag = entrybuf[i].flag; + + /* Write back the updated index. */ + lseek(masterfd, loc, SEEK_SET); + if (write(masterfd, &idx, sizeof(struct index_entry)) != + sizeof(struct index_entry)) + { + logf("write fail"); + close(masterfd); + return false; + } } + + entries_processed += count; + logf("%d/%d entries processed", entries_processed, h->entry_count); } close(masterfd); @@ -2330,13 +2353,10 @@ static bool commit(void) { int ret; - stat.commit_step++; if (tagcache_is_numeric_tag(i)) - { - build_numeric_index(i, &tch, tmpfd); continue; - } + stat.commit_step++; ret = build_index(i, &tch, tmpfd); if (ret <= 0) { @@ -2352,6 +2372,7 @@ static bool commit(void) } } + build_numeric_indices(&tch, tmpfd); close(tmpfd); stat.commit_step = 0; diff --git a/apps/tagcache.h b/apps/tagcache.h index b639611394..23525f8ea8 100644 --- a/apps/tagcache.h +++ b/apps/tagcache.h @@ -70,6 +70,7 @@ enum tag_type { tag_artist = 0, tag_album, tag_genre, tag_title, #define FLAG_DELETED 0x0001 /* Entry has been removed from db */ #define FLAG_DIRCACHE 0x0002 /* Filename is a dircache pointer */ #define FLAG_DIRTYNUM 0x0004 /* Numeric data has been modified */ +#define FLAG_TRKNUMGEN 0x0008 /* Track number has been generated */ #define FLAG_GET_ATTR(flag) ((flag >> 16) & 0x0000ffff) #define FLAG_SET_ATTR(flag,attr) flag = (flag & 0x0000ffff) | (attr << 16)