|
zagor: apps dbtree.c, 1.5, 1.6 dbtree.h, 1.2, 1.3 filetree.c, 1.5, 1.6 file: msg#00081systems.archos.rockbox.cvs
Update of /cvsroot/rockbox/apps In directory labb:/tmp/cvs-serv16523 Modified Files: dbtree.c dbtree.h filetree.c filetree.h playlist.c tree.c tree.h Log Message: Added support for very large tables in ID3 database. Index: dbtree.c =================================================================== RCS file: /cvsroot/rockbox/apps/dbtree.c,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- dbtree.c 18 Jan 2005 00:04:08 -0000 1.5 +++ dbtree.c 18 Jan 2005 22:45:00 -0000 1.6 @@ -121,18 +121,21 @@ return 0; } -int db_load(struct tree_context* c, bool* dir_buffer_full) +int db_load(struct tree_context* c) { - int i, offset, len, rc; + int i, offset, rc; int dcachesize = global_settings.max_files_in_dir * sizeof(struct entry); int max_items, itemcount, stringlen; unsigned int* nptr = (void*) c->name_buffer; unsigned int* dptr = c->dircache; unsigned int* safeplace = NULL; + int safeplacelen = 0; int table = c->currtable; int extra = c->currextra; + char* end_of_nbuf = c->name_buffer + c->name_buffer_size; + if (!initialized) { DEBUGF("ID3 database is not initialized.\n"); c->filesindir = 0; @@ -140,8 +143,9 @@ } c->dentry_size = 2 * sizeof(int); - - DEBUGF("db_load(%d, %x)\n", table, extra); + c->dirfull = false; + + DEBUGF("db_load(%d, %x, %d)\n", table, extra, c->firstpos); if (!table) { table = allartists; @@ -150,51 +154,50 @@ switch (table) { case allsongs: - offset = songstart; + offset = songstart + c->firstpos * (songlen + 12); itemcount = songcount; stringlen = songlen; break; case allalbums: - offset = albumstart; + offset = albumstart + + c->firstpos * (albumlen + 4 + songarraylen * 4); itemcount = albumcount; stringlen = albumlen; break; case allartists: - offset = artiststart; + offset = artiststart + + c->firstpos * (artistlen + albumarraylen * 4); itemcount = artistcount; stringlen = artistlen; break; - case albums: + case albums4artist: /* 'extra' is offset to the artist */ - len = albumarraylen * 4; - safeplace = (void*)(c->name_buffer + c->name_buffer_size - len); - //DEBUGF("Seeking to %x\n", extra + artistlen); + safeplacelen = albumarraylen * 4; + safeplace = (void*)(end_of_nbuf - safeplacelen); lseek(fd, extra + artistlen, SEEK_SET); - rc = read(fd, safeplace, len); - if (rc < len) + rc = read(fd, safeplace, safeplacelen); + if (rc < safeplacelen) return -1; #ifdef LITTLE_ENDIAN for (i=0; i<albumarraylen; i++) safeplace[i] = BE32(safeplace[i]); #endif - offset = safeplace[0]; itemcount = albumarraylen; stringlen = albumlen; break; - case songs: + case songs4album: /* 'extra' is offset to the album */ - len = songarraylen * 4; - safeplace = (void*)(c->name_buffer + c->name_buffer_size - len); - //DEBUGF("Seeking to %x\n", extra + albumlen + 4); + safeplacelen = songarraylen * 4; + safeplace = (void*)(end_of_nbuf - safeplacelen); lseek(fd, extra + albumlen + 4, SEEK_SET); - rc = read(fd, safeplace, len); - if (rc < len) + rc = read(fd, safeplace, safeplacelen); + if (rc < safeplacelen) return -1; #ifdef LITTLE_ENDIAN @@ -211,6 +214,10 @@ return -1; } max_items = dcachesize / c->dentry_size; + end_of_nbuf -= safeplacelen; + + c->dirlength = itemcount; + itemcount -= c->firstpos; if (!safeplace) { //DEBUGF("Seeking to %x\n", offset); @@ -222,8 +229,7 @@ the rest is table specific. see below. */ if (itemcount > max_items) - if (dir_buffer_full) - *dir_buffer_full = true; + c->dirfull = true; if (max_items > itemcount) { max_items = itemcount; @@ -233,8 +239,10 @@ int rc, skip=0; if (safeplace) { - if (!safeplace[i]) + if (!safeplace[i]) { + c->dirlength = i; break; + } //DEBUGF("Seeking to %x\n", safeplace[i]); lseek(fd, safeplace[i], SEEK_SET); offset = safeplace[i]; @@ -252,15 +260,15 @@ dptr[0] = (unsigned int)nptr; switch (table) { - case songs: case allsongs: + case songs4album: /* save offset of this song */ skip = 12; dptr[1] = offset; break; case allalbums: - case albums: + case albums4artist: /* save offset of this album */ skip = songarraylen * 4 + 4; dptr[1] = offset; @@ -273,15 +281,14 @@ break; } - //DEBUGF("%x: %s\n", dptr[1], dptr[0]); - if (skip) lseek(fd, skip, SEEK_CUR); /* next name is stored immediately after this */ nptr = (void*)nptr + strlen((char*)nptr) + 1; - if ((void*)nptr > (void*)c->name_buffer + c->name_buffer_size) { + if ((void*)nptr > (void*)end_of_nbuf) { DEBUGF("Name buffer overflow (%d)\n",i); + c->dirfull = true; break; } dptr = (void*)dptr + c->dentry_size; @@ -299,11 +306,12 @@ { switch (c->currtable) { case allartists: - case albums: + case albums4artist: c->dirpos[c->dirlevel] = c->dirstart; c->cursorpos[c->dirlevel] = c->dircursor; c->table_history[c->dirlevel] = c->currtable; c->extra_history[c->dirlevel] = c->currextra; + c->pos_history[c->dirlevel] = c->firstpos; c->dirlevel++; break; @@ -313,16 +321,16 @@ switch (c->currtable) { case allartists: - c->currtable = albums; + c->currtable = albums4artist; c->currextra = ((int*)c->dircache)[(c->dircursor + c->dirstart)*2 + 1]; break; - case albums: - c->currtable = songs; + case albums4artist: + c->currtable = songs4album; c->currextra = ((int*)c->dircache)[(c->dircursor + c->dirstart)*2 + 1]; break; - case songs: + case songs4album: splash(HZ,true,"No playing implemented yet"); #if 0 /* find filenames, build playlist, play */ @@ -334,7 +342,7 @@ break; } - c->dirstart = c->dircursor = 0; + c->dirstart = c->dircursor = c->firstpos = 0; } void db_exit(struct tree_context* c) @@ -344,6 +352,7 @@ c->dircursor = c->cursorpos[c->dirlevel]; c->currtable = c->table_history[c->dirlevel]; c->currextra = c->extra_history[c->dirlevel]; + c->firstpos = c->pos_history[c->dirlevel]; } #ifdef HAVE_LCD_BITMAP @@ -354,7 +363,7 @@ switch (c->currtable) { case allsongs: - case songs: + case songs4album: icon = File; break; @@ -372,7 +381,7 @@ switch (c->currtable) { case allsongs: - case songs: + case songs4album: icon = File; break; Index: filetree.c =================================================================== RCS file: /cvsroot/rockbox/apps/filetree.c,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- filetree.c 17 Jan 2005 23:55:55 -0000 1.5 +++ filetree.c 18 Jan 2005 22:45:00 -0000 1.6 @@ -184,9 +184,8 @@ } /* load and sort directory into dircache. returns NULL on failure. */ -int ft_load(struct tree_context* c, bool *buffer_full) +int ft_load(struct tree_context* c) { - extern char lastdir[]; /* from tree.c */ int i; int name_buffer_used = 0; DIR *dir = opendir(c->currdir); @@ -194,13 +193,13 @@ return -1; /* not a directory */ c->dirsindir = 0; - if (buffer_full) - *buffer_full = false; + c->dirfull = false; for ( i=0; i < global_settings.max_files_in_dir; i++ ) { int len; struct dirent *entry = readdir(dir); - struct entry* dptr = (struct entry*)(c->dircache + i * sizeof(struct entry)); + struct entry* dptr = + (struct entry*)(c->dircache + i * sizeof(struct entry)); if (!entry) break; @@ -268,8 +267,7 @@ if (len > c->name_buffer_size - name_buffer_used - 1) { /* Tell the world that we ran out of buffer space */ - if (buffer_full) - *buffer_full = true; + c->dirfull = true; break; } dptr->name = &c->name_buffer[name_buffer_used]; @@ -281,10 +279,9 @@ c->dirsindir++; } c->filesindir = i; + c->dirlength = i; closedir(dir); - strcpy(lastdir, c->currdir); - qsort(c->dircache,i,sizeof(struct entry),compare); /* If thumbnail talking is enabled, make an extra run to mark files with Index: tree.c =================================================================== RCS file: /cvsroot/rockbox/apps/tree.c,v retrieving revision 1.283 retrieving revision 1.284 diff -u -d -r1.283 -r1.284 --- tree.c 17 Jan 2005 12:56:00 -0000 1.283 +++ tree.c 18 Jan 2005 22:45:00 -0000 1.284 @@ -92,7 +92,9 @@ bool boot_changed = false; char lastfile[MAX_PATH]; -char lastdir[MAX_PATH]; +static char lastdir[MAX_PATH]; +static int lasttable, lastextra, lastfirstpos; +static int max_files = 0; static bool reload_dir = false; @@ -245,10 +247,9 @@ struct entry *dircache = tc.dircache; int i; int tree_max_on_screen; - bool dir_buffer_full = false; int start = tc.dirstart; bool id3db = global_settings.dirfilter == SHOW_ID3DB; - + bool newdir = false; #ifdef HAVE_LCD_BITMAP const char* icon; int line_height; @@ -264,17 +265,30 @@ /* new file dir? load it */ if (id3db) { - if (db_load(&tc, &dir_buffer_full) < 0) - return -1; + if (tc.currtable != lasttable || + tc.currextra != lastextra || + tc.firstpos != lastfirstpos) + { + if (db_load(&tc) < 0) + return -1; + lasttable = tc.currtable; + lastextra = tc.currextra; + lastfirstpos = tc.firstpos; + newdir = true; + } } else { if (strncmp(tc.currdir, lastdir, sizeof(lastdir)) || reload_dir) { - if (ft_load(&tc, &dir_buffer_full) < 0) + if (ft_load(&tc) < 0) return -1; + strcpy(lastdir, tc.currdir); + newdir = true; } } - if ( dir_buffer_full || tc.filesindir == global_settings.max_files_in_dir ) { + if (newdir && !id3db && + (tc.dirfull || tc.filesindir == global_settings.max_files_in_dir) ) + { #ifdef HAVE_LCD_CHARCELLS lcd_double_height(false); #endif @@ -383,10 +397,11 @@ } #ifdef HAVE_LCD_BITMAP - if (global_settings.scrollbar && (tc.filesindir > tree_max_on_screen)) + if (global_settings.scrollbar && (tc.dirlength > tree_max_on_screen)) scrollbar(SCROLLBAR_X, SCROLLBAR_Y, SCROLLBAR_WIDTH - 1, - tree_max_on_screen * line_height, tc.filesindir, start, - start + tree_max_on_screen, VERTICAL); + tree_max_on_screen * line_height, tc.dirlength, + start + tc.firstpos, + start + tc.firstpos + tree_max_on_screen, VERTICAL); #if CONFIG_KEYPAD == RECORDER_PAD if(global_settings.buttonbar) { @@ -483,10 +498,8 @@ /* load tracks from specified directory to resume play */ void resume_directory(const char *dir) { - bool buffer_full; - strcpy(tc.currdir, dir); - if (!ft_load(&tc, &buffer_full)) + if (!ft_load(&tc)) return; lastdir[0] = 0; @@ -586,10 +599,10 @@ if (currmode != (global_settings.dirfilter == SHOW_ID3DB)) { currmode = global_settings.dirfilter == SHOW_ID3DB; if (currmode) { - db_load(&tc, NULL); + db_load(&tc); } else - ft_load(&tc, NULL); + ft_load(&tc); } return currmode; } @@ -624,6 +637,10 @@ tc.dircursor=0; tc.dirstart=0; tc.dirlevel=0; + tc.firstpos=0; + lasttable = -1; + lastextra = -1; + lastfirstpos = 0; if (*tc.dirfilter < NUM_FILTER_MODES) start_resume(true); @@ -778,39 +795,59 @@ case TREE_RC_PREV: case TREE_RC_PREV | BUTTON_REPEAT: #endif - if(tc.filesindir) { - if(tc.dircursor) { - put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, false); - tc.dircursor--; - put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, true); - } - else { - if (tc.dirstart) { + if (!tc.filesindir) + break; + + if (tc.dircursor) { + put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, false); + tc.dircursor--; + put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, true); + } + else { + if (tc.dirstart || tc.firstpos) { + if (tc.dirstart) tc.dirstart--; - numentries = showdir(); - update_all=true; - put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, true); - } else { - if (numentries < tree_max_on_screen) { - put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, - false); - tc.dircursor = numentries - 1; - put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, - true); + if (tc.firstpos > max_files/2) { + tc.firstpos -= max_files/2; + tc.dirstart += max_files/2; + tc.dirstart--; } else { - tc.dirstart = numentries - tree_max_on_screen; - tc.dircursor = tree_max_on_screen - 1; - numentries = showdir(); - update_all = true; - put_cursorxy(CURSOR_X, CURSOR_Y + - tree_max_on_screen - 1, true); + tc.dirstart = tc.firstpos - 1; + tc.firstpos = 0; } } + restore = true; + } + else { + if (numentries < tree_max_on_screen) { + put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, + false); + tc.dircursor = numentries - 1; + put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, + true); + } + else if (id3db && tc.dirfull) { + /* load last dir segment */ + /* use max_files/2 in case names are longer than + AVERAGE_FILE_LENGTH */ + tc.firstpos = tc.dirlength - max_files/2; + tc.dirstart = tc.firstpos; + tc.dircursor = tree_max_on_screen - 1; + numentries = showdir(); + update_all = true; + put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, + true); + } + else { + tc.dirstart = numentries - tree_max_on_screen; + tc.dircursor = tree_max_on_screen - 1; + restore = true; + } } - need_update = true; } + need_update = true; break; case TREE_NEXT: @@ -819,46 +856,67 @@ case TREE_RC_NEXT: case TREE_RC_NEXT | BUTTON_REPEAT: #endif - if(tc.filesindir) - { - if (tc.dircursor + tc.dirstart + 1 < numentries ) { - if(tc.dircursor+1 < tree_max_on_screen) { - put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, false); - tc.dircursor++; - put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, true); - } - else { - tc.dirstart++; - numentries = showdir(); - update_all = true; - put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, true); - } + if (!tc.filesindir) + break; + + if (tc.dircursor + tc.dirstart + 1 < numentries ) { + if(tc.dircursor+1 < tree_max_on_screen) { + put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, false); + tc.dircursor++; + put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, true); } else { - if(numentries < tree_max_on_screen) { - put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, false); - tc.dirstart = tc.dircursor = 0; - put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, true); - } - else { - tc.dirstart = tc.dircursor = 0; - numentries = showdir(); - update_all=true; - put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, true); - } + tc.dirstart++; + restore = true; + } + } + else if (id3db && (tc.firstpos || tc.dirfull)) { + if (tc.dircursor + tc.dirstart + tc.firstpos + 1 >= tc.dirlength) { + /* wrap and load first dir segment */ + tc.firstpos = tc.dirstart = tc.dircursor = 0; + } + else { + /* load next dir segment */ + tc.firstpos += tc.dirstart; + tc.dirstart = 0; + } + restore = true; + } + else { + if(numentries < tree_max_on_screen) { + put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, false); + tc.dirstart = tc.dircursor = 0; + put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, true); + } + else { + tc.dirstart = tc.dircursor = 0; + numentries = showdir(); + update_all=true; + put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, true); } - need_update = true; } + need_update = true; break; #ifdef TREE_PGUP case TREE_PGUP: case TREE_PGUP | BUTTON_REPEAT: - if ( tc.dirstart ) { + if (tc.dirstart) { tc.dirstart -= tree_max_on_screen; if ( tc.dirstart < 0 ) tc.dirstart = 0; } + else if (tc.firstpos) { + if (tc.firstpos > max_files/2) { + tc.firstpos -= max_files/2; + tc.dirstart += max_files/2; + tc.dirstart -= tree_max_on_screen; + } + else { + tc.dirstart = tc.firstpos - tree_max_on_screen; + tc.firstpos = 0; + } + } else tc.dircursor = 0; restore = true; @@ -868,10 +926,14 @@ case TREE_PGDN | BUTTON_REPEAT: if ( tc.dirstart < numentries - tree_max_on_screen ) { tc.dirstart += tree_max_on_screen; - if ( tc.dirstart > - numentries - tree_max_on_screen ) + if ( tc.dirstart > numentries - tree_max_on_screen ) tc.dirstart = numentries - tree_max_on_screen; } + else if (id3db && tc.dirfull) { + /* load next dir segment */ + tc.firstpos += tc.dirstart; + tc.dirstart = 0; + } else tc.dircursor = numentries - tc.dirstart - 1; restore = true; @@ -1334,7 +1396,7 @@ { /* We copy the settings value in case it is changed by the user. We can't use it until the next reboot. */ - int max_files = global_settings.max_files_in_dir; + max_files = global_settings.max_files_in_dir; /* initialize tree context struct */ memset(&tc, 0, sizeof(tc)); Index: dbtree.h =================================================================== RCS file: /cvsroot/rockbox/apps/dbtree.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- dbtree.h 17 Jan 2005 16:06:07 -0000 1.2 +++ dbtree.h 18 Jan 2005 22:45:00 -0000 1.3 @@ -21,13 +21,13 @@ #include "tree.h" -enum table { invalid, allsongs, allalbums, allartists, albums, songs }; +enum table { invalid, allsongs, allalbums, allartists, + albums4artist, songs4album }; int db_init(void); void db_enter(struct tree_context* c); void db_exit(struct tree_context* c); -int db_load(struct tree_context* c, - bool* dir_buffer_full); +int db_load(struct tree_context* c); #ifdef HAVE_LCD_BITMAP const char* db_get_icon(struct tree_context* c); #else Index: tree.h =================================================================== RCS file: /cvsroot/rockbox/apps/tree.h,v retrieving revision 1.34 retrieving revision 1.35 diff -u -d -r1.34 -r1.35 --- tree.h 17 Jan 2005 11:39:46 -0000 1.34 +++ tree.h 18 Jan 2005 22:45:00 -0000 1.35 @@ -121,12 +121,16 @@ int dirlevel; int dircursor; int dirstart; + int firstpos; /* which dir entry is on first + position in dir buffer */ + int pos_history[MAX_DIR_LEVELS]; int dirpos[MAX_DIR_LEVELS]; int cursorpos[MAX_DIR_LEVELS]; char currdir[MAX_PATH]; /* file use */ int *dirfilter; /* file use */ int filesindir; int dirsindir; /* file use */ + int dirlength; /* total number of entries in dir, incl. those not loaded */ int table_history[MAX_DIR_LEVELS]; /* db use */ int extra_history[MAX_DIR_LEVELS]; /* db use */ int currtable; /* db use */ @@ -137,6 +141,7 @@ char* name_buffer; int name_buffer_size; int dentry_size; + bool dirfull; }; /* using attribute bits not used by FAT (FAT uses lower 7) */ Index: filetree.h =================================================================== RCS file: /cvsroot/rockbox/apps/filetree.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- filetree.h 17 Jan 2005 16:06:07 -0000 1.2 +++ filetree.h 18 Jan 2005 22:45:00 -0000 1.3 @@ -20,7 +20,7 @@ #define FILETREE_H #include "tree.h" -int ft_load(struct tree_context* c, bool *buffer_full); +int ft_load(struct tree_context* c); int ft_play_filenumber(int pos, int attr); int ft_play_dirname(int start_index); void ft_play_filename(char *dir, char *file); Index: playlist.c =================================================================== RCS file: /cvsroot/rockbox/apps/playlist.c,v retrieving revision 1.107 retrieving revision 1.108 diff -u -d -r1.107 -r1.108 --- playlist.c 17 Jan 2005 12:56:00 -0000 1.107 +++ playlist.c 18 Jan 2005 22:45:00 -0000 1.108 @@ -545,7 +545,7 @@ /* use the tree browser dircache to load files */ global_settings.dirfilter = SHOW_ALL; strncpy(tc->currdir, dirname, sizeof(tc->currdir)); - num_files = ft_load(tc, NULL); + num_files = ft_load(tc); files = (struct entry*) tc->dircache; if(!num_files) @@ -585,7 +585,7 @@ /* we now need to reload our current directory */ strncpy(tc->currdir, dirname, sizeof(tc->currdir)); - num_files = ft_load(tc, NULL); + num_files = ft_load(tc); files = (struct entry*) tc->dircache; if (!num_files) { _______________________________________________ http://cool.haxx.se/mailman/listinfo/rockbox-cvs |
|
| <Prev in Thread] | Current Thread | [Next in Thread> |
|---|---|---|
| Previous by Date: | amiconn: apps/lang deutsch.lang,1.52,1.53: 00081, cvs |
|---|---|
| Next by Date: | zagor: apps filetree.c, 1.6, 1.7 filetree.h, 1.3, 1.4 playlist.c, 1.108, 1.109 tree.c, 1.284, 1.285: 00081, cvs |
| Previous by Thread: | amiconn: apps/lang deutsch.lang,1.52,1.53i: 00081, cvs |
| Next by Thread: | zagor: apps filetree.c, 1.6, 1.7 filetree.h, 1.3, 1.4 playlist.c, 1.108, 1.109 tree.c, 1.284, 1.285: 00081, cvs |
| Indexes: | [Date] [Thread] [Top] [All Lists] |
| News | Mail Home | sitemap | FAQ | advertise |