summaryrefslogtreecommitdiffstats
path: root/apps/dbtree.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/dbtree.c')
-rw-r--r--apps/dbtree.c559
1 files changed, 0 insertions, 559 deletions
diff --git a/apps/dbtree.c b/apps/dbtree.c
deleted file mode 100644
index bc98491d9e..0000000000
--- a/apps/dbtree.c
+++ /dev/null
@@ -1,559 +0,0 @@
-/***************************************************************************
- * __________ __ ___.
- * Open \______ \ ____ ____ | | _\_ |__ _______ ___
- * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
- * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
- * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
- * \/ \/ \/ \/ \/
- * $Id$
- *
- * Copyright (C) 2005 by Björn Stenberg
- *
- * All files in this archive are subject to the GNU General Public License.
- * See the file COPYING in the source tree root for full license agreement.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ****************************************************************************/
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <string.h>
-#include "file.h"
-#include "screens.h"
-#include "kernel.h"
-#include "tree.h"
-#include "lcd.h"
-#include "font.h"
-#include "settings.h"
-#include "icons.h"
-#include "status.h"
-#include "debug.h"
-#include "button.h"
-#include "menu.h"
-#include "main_menu.h"
-#include "mpeg.h"
-#include "misc.h"
-#include "ata.h"
-#include "playlist.h"
-#include "filetypes.h"
-#include "applimits.h"
-#include "dbtree.h"
-#include "icons.h"
-#include "lang.h"
-#include "keyboard.h"
-#include "autoconf.h"
-#include "list.h"
-#include "splash.h"
-
-static int db_play_folder(struct tree_context* c);
-static int db_search(struct tree_context* c, char* string);
-
-static char searchstring[32];
-
-int db_load(struct tree_context* c)
-{
- int i, offset, rc;
- int dcachesize = global_settings.max_files_in_dir * sizeof(struct entry);
- int itemcount, stringlen, hits=0;
- unsigned long* nptr = (void*) c->name_buffer;
- unsigned long* dptr = c->dircache;
- unsigned long* 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 (!tagdb_initialized) {
- DEBUGF("ID3 database is not initialized.\n");
- c->filesindir = 0;
- return 0;
- }
-
- c->dentry_size = 2;
- c->dirfull = false;
-
- DEBUGF("db_load() table: %d extra: 0x%x firstpos: %d\n", table, extra,
- c->firstpos);
-
- if (!table) {
- table = root;
- c->currtable = table;
- }
-
- switch (table) {
- case root: {
- static const int tables[] = {allartists, allalbums, allsongs,
- search };
- char* nbuf = (char*)nptr;
- unsigned char* labels[] = { str(LANG_ID3DB_ARTISTS),
- str(LANG_ID3DB_ALBUMS),
- str(LANG_ID3DB_SONGS),
- str(LANG_ID3DB_SEARCH)};
- DEBUGF("dbload table root\n");
- for (i=0; i < 4; i++) {
- strcpy(nbuf, (char *)labels[i]);
- dptr[0] = (unsigned long)nbuf;
- dptr[1] = tables[i];
- nbuf += strlen(nbuf) + 1;
- dptr += 2;
- }
- c->dirlength = c->filesindir = i;
- return i;
- }
-
- case search: {
- static const int tables[] = {searchartists,
- searchalbums,
- searchsongs};
- char* nbuf = (char*)nptr;
- unsigned char* labels[] = { str(LANG_ID3DB_SEARCH_ARTISTS),
- str(LANG_ID3DB_SEARCH_ALBUMS),
- str(LANG_ID3DB_SEARCH_SONGS)};
- DEBUGF("dbload table search\n");
- for (i=0; i < 3; i++) {
- strcpy(nbuf, (char *)labels[i]);
- dptr[0] = (unsigned long)nbuf;
- dptr[1] = tables[i];
- nbuf += strlen(nbuf) + 1;
- dptr += 2;
- }
- c->dirlength = c->filesindir = i;
- return i;
- }
-
- case searchartists:
- case searchalbums:
- case searchsongs:
- DEBUGF("dbload table searchsongs/searchartists/searchalbums\n");
- i = db_search(c, searchstring);
- c->dirlength = c->filesindir = i;
- if (c->dirfull) {
- gui_syncsplash(HZ, true, str(LANG_SHOWDIR_BUFFER_FULL));
- c->dirfull = false;
- }
- else
- gui_syncsplash(HZ, true, str(LANG_ID3DB_MATCHES), i);
- return i;
-
- case allsongs:
- DEBUGF("dbload table allsongs\n");
- offset = tagdbheader.songstart + c->firstpos * SONGENTRY_SIZE;
- itemcount = tagdbheader.songcount;
- stringlen = tagdbheader.songlen;
- break;
-
- case allalbums:
- DEBUGF("dbload table allalbums\n");
- offset = tagdbheader.albumstart + c->firstpos * ALBUMENTRY_SIZE;
- itemcount = tagdbheader.albumcount;
- stringlen = tagdbheader.albumlen;
- break;
-
- case allartists:
- DEBUGF("dbload table allartists\n");
- offset = tagdbheader.artiststart + c->firstpos * ARTISTENTRY_SIZE;
- itemcount = tagdbheader.artistcount;
- stringlen = tagdbheader.artistlen;
- break;
-
- case albums4artist:
- DEBUGF("dbload table albums4artist\n");
- /* 'extra' is offset to the artist */
- safeplacelen = tagdbheader.albumarraylen * 4;
- safeplace = (void*)(end_of_nbuf - safeplacelen);
- lseek(tagdb_fd, extra + tagdbheader.artistlen, SEEK_SET);
- rc = read(tagdb_fd, safeplace, safeplacelen);
- if (rc < safeplacelen)
- return -1;
-
-#ifdef ROCKBOX_LITTLE_ENDIAN
- for (i=0; i<tagdbheader.albumarraylen; i++)
- safeplace[i] = BE32(safeplace[i]);
-#endif
- offset = safeplace[0];
- itemcount = tagdbheader.albumarraylen;
- stringlen = tagdbheader.albumlen;
- break;
-
- case songs4album:
- DEBUGF("dbload table songs4album\n");
- /* 'extra' is offset to the album */
- safeplacelen = tagdbheader.songarraylen * 4;
- safeplace = (void*)(end_of_nbuf - safeplacelen);
- lseek(tagdb_fd, extra + tagdbheader.albumlen + 4, SEEK_SET);
- rc = read(tagdb_fd, safeplace, safeplacelen);
- if (rc < safeplacelen)
- return -1;
-
-#ifdef ROCKBOX_LITTLE_ENDIAN
- for (i=0; i<tagdbheader.songarraylen; i++) {
- safeplace[i] = BE32(safeplace[i]);
- DEBUGF("db_load songs4album song %d: 0x%x\n",i,safeplace[i]);
- }
-#endif
- offset = safeplace[0];
- itemcount = tagdbheader.songarraylen;
- stringlen = tagdbheader.songlen;
- break;
-
- case songs4artist:
- DEBUGF("dbload table songs4artist\n");
- /* 'extra' is offset to the artist, used as filter */
- offset = tagdbheader.songstart + c->firstpos * SONGENTRY_SIZE;
- itemcount = tagdbheader.songcount;
- stringlen = tagdbheader.songlen;
- break;
-
- default:
- DEBUGF("Unsupported table %d\n", table);
- return -1;
- }
- end_of_nbuf -= safeplacelen;
-
- c->dirlength = itemcount;
- itemcount -= c->firstpos;
-
- if (!safeplace)
- lseek(tagdb_fd, offset, SEEK_SET);
-
- /* name_buffer (nptr) contains only names, null terminated.
- the first word of dcache (dptr) is a pointer to the name,
- the rest is table specific. see below. */
-
- for ( i=0; i < itemcount; i++ ) {
- int rc, skip=0;
- int intbuf[4];
-
- if (safeplace) {
- if (!safeplace[i]) {
- c->dirlength = i;
- break;
- }
- lseek(tagdb_fd, safeplace[i], SEEK_SET);
- offset = safeplace[i];
- }
-
- /* read name */
- rc = read(tagdb_fd, nptr, stringlen);
- if (rc < stringlen)
- {
- DEBUGF("%d read(%d) returned %d\n", i, stringlen, rc);
- return -1;
- }
-
- switch (table) {
- case allsongs:
- case songs4album:
- case songs4artist:
- rc = read(tagdb_fd, intbuf, 12);
- /* skip the rest of the song info */
- skip = SONGENTRY_SIZE-stringlen-12;
- if (rc < 12) {
- DEBUGF("%d read(%d) returned %d\n", i, 12, rc);
- return -1;
- }
- /* continue to next song if wrong artist */
- if (table == songs4artist && (int)BE32(intbuf[0]) != extra) {
- lseek(tagdb_fd, skip, SEEK_CUR);
- continue;
- }
-
- /* save offset of filename */
- dptr[1] = BE32(intbuf[2]);
- break;
-
- case allalbums:
- case albums4artist:
- /* save offset of this album */
- skip = tagdbheader.songarraylen * 4 + 4;
- dptr[1] = offset;
- break;
-
- case allartists:
- /* save offset of this artist */
- skip = tagdbheader.albumarraylen * 4;
- dptr[1] = offset;
- break;
- }
-
- /* store name pointer in dir cache */
- dptr[0] = (unsigned long)nptr;
-
- if (skip)
- lseek(tagdb_fd, skip, SEEK_CUR);
-
- hits++;
-
- if(table==songs4artist)
- c->dirlength=hits;
-
- /* next name is stored immediately after this */
- nptr = (void*)nptr + strlen((char*)nptr) + 1;
- if ((void*)nptr + stringlen > (void*)end_of_nbuf) {
- c->dirfull = true;
- break;
- }
-
- /* limit dir buffer */
- dptr = (void*)dptr + c->dentry_size * sizeof(int);
- if ((void*)(dptr + c->dentry_size) >
- (void*)(c->dircache + dcachesize))
- {
- c->dirfull = true;
- break;
- }
-
- if (!safeplace)
- offset += stringlen + skip;
- }
-
- if (c->currtable == albums4artist && !c->dirfull) {
- strcpy((char*)nptr, (char *)str(LANG_ID3DB_ALL_SONGS));
- dptr[0] = (unsigned long)nptr;
- dptr[1] = extra; /* offset to artist */
- hits++;
- }
-
- c->filesindir = hits;
-
- return hits;
-}
-
-static int db_search(struct tree_context* c, char* string)
-{
- int i, count, size, hits=0;
- long start;
-
- char* nptr = c->name_buffer;
- const char* end_of_nbuf = nptr + c->name_buffer_size;
-
- unsigned long* dptr = c->dircache;
- const long dcachesize = global_settings.max_files_in_dir *
- sizeof(struct entry);
-
- switch (c->currtable) {
- case searchartists:
- start = tagdbheader.artiststart;
- count = tagdbheader.artistcount;
- size = ARTISTENTRY_SIZE;
- break;
-
- case searchalbums:
- start = tagdbheader.albumstart;
- count = tagdbheader.albumcount;
- size = ALBUMENTRY_SIZE;
- break;
-
- case searchsongs:
- start = tagdbheader.songstart;
- count = tagdbheader.songcount;
- size = SONGENTRY_SIZE;
- break;
-
- default:
- DEBUGF("Invalid table %d\n", c->currtable);
- return 0;
- }
-
- lseek(tagdb_fd, start, SEEK_SET);
-
- for (i=0; i<count; i++) {
- if (read(tagdb_fd, nptr, size) < size) {
- DEBUGF("Short read(%d) in db_search()\n",size);
- break;
- }
- if (strcasestr(nptr, string)) {
- hits++;
-
- dptr[0] = (unsigned long)nptr;
- if (c->currtable == searchsongs) {
- /* store offset of filename */
- dptr[1] = BE32(*((long*)(nptr + tagdbheader.songlen + 8)));
- }
- else
- /* store offset of database record */
- dptr[1] = start + i * size;
-
- dptr += 2;
-
- /* limit dir buffer */
- if ((void*)(dptr + c->dentry_size) >
- (void*)(c->dircache + dcachesize))
- {
- c->dirfull = true;
- break;
- }
-
- nptr += strlen(nptr) + 1;
- while ((unsigned long)nptr & 3)
- nptr++;
-
- /* limit name buffer */
- if ((void*)nptr + size > (void*)end_of_nbuf) {
- c->dirfull = true;
- break;
- }
- }
- }
-
- return hits;
-}
-
-int db_enter(struct tree_context* c)
-{
- int rc = 0;
- int offset = (c->selected_item) * c->dentry_size + 1;
- int newextra = ((int*)c->dircache)[offset];
-
- if (c->dirlevel >= MAX_DIR_LEVELS)
- return 0;
-
- c->selected_item_history[c->dirlevel]=c->selected_item;
- c->table_history[c->dirlevel] = c->currtable;
- c->extra_history[c->dirlevel] = c->currextra;
- c->pos_history[c->dirlevel] = c->firstpos;
- c->dirlevel++;
-
- switch (c->currtable) {
- case root:
- c->currtable = newextra;
- c->currextra = newextra;
- break;
-
- case allartists:
- case searchartists:
- c->currtable = albums4artist;
- c->currextra = newextra;
- break;
-
- case allalbums:
- case albums4artist:
- case searchalbums:
- /* virtual <all albums> entry points to the artist,
- all normal entries point to the album */
- if (newextra < tagdbheader.albumstart)
- c->currtable = songs4artist;
- else
- c->currtable = songs4album;
-
- c->currextra = newextra;
- break;
-
- case allsongs:
- case songs4album:
- case songs4artist:
- case searchsongs:
- c->dirlevel--;
- if (db_play_folder(c) >= 0)
- rc = 2;
- break;
-
- case search:
- rc = kbd_input(searchstring, sizeof(searchstring));
- if (rc == -1 || !searchstring[0])
- c->dirlevel--;
- else
- c->currtable = newextra;
- break;
-
- default:
- c->dirlevel--;
- break;
- }
- c->selected_item=0;
- gui_synclist_select_item(&tree_lists, c->selected_item);
-
- return rc;
-}
-
-void db_exit(struct tree_context* c)
-{
- c->dirlevel--;
- c->selected_item=c->selected_item_history[c->dirlevel];
- gui_synclist_select_item(&tree_lists, c->selected_item);
- c->currtable = c->table_history[c->dirlevel];
- c->currextra = c->extra_history[c->dirlevel];
- c->firstpos = c->pos_history[c->dirlevel];
-}
-
-int db_get_filename(struct tree_context* c, char *buf, int buflen)
-{
- int rc;
- int pathoffset = ((int*)c->dircache)[c->selected_item * c->dentry_size + 1];
-
- lseek(tagdb_fd, pathoffset, SEEK_SET);
- rc = read(tagdb_fd, buf, buflen);
-
- if (rc < tagdbheader.songlen) {
- DEBUGF("short path read(%ld) = %d\n", sizeof(buf), rc);
- return -2;
- }
- return 0;
-}
-
-static int db_play_folder(struct tree_context* c)
-{
- char buf[MAX_PATH];
- int rc, i;
-
- if (playlist_create(NULL, NULL) < 0) {
- DEBUGF("Failed creating playlist\n");
- return -1;
- }
-
- /* TODO: add support for very long tables */
-
- for (i=0; i < c->filesindir; i++) {
- int pathoffset = ((int*)c->dircache)[i * c->dentry_size + 1];
- lseek(tagdb_fd, pathoffset, SEEK_SET);
- rc = read(tagdb_fd, buf, sizeof(buf));
- if (rc < tagdbheader.songlen) {
- DEBUGF("short path read(%ld) = %d\n", sizeof(buf), rc);
- return -2;
- }
-
- playlist_insert_track(NULL, buf, PLAYLIST_INSERT, false);
- }
-
- if (global_settings.playlist_shuffle)
- c->selected_item = playlist_shuffle(current_tick, c->selected_item);
- if (!global_settings.play_selected)
- c->selected_item = 0;
- gui_synclist_select_item(&tree_lists, c->selected_item);
-
- playlist_start(c->selected_item,0);
-
- return 0;
-}
-
-#ifdef HAVE_LCD_BITMAP
-const char* db_get_icon(struct tree_context* c)
-#else
-int db_get_icon(struct tree_context* c)
-#endif
-{
- int icon;
-
- switch (c->currtable)
- {
- case allsongs:
- case songs4album:
- case songs4artist:
- case searchsongs:
- icon = Icon_Audio;
- break;
-
- default:
- icon = Icon_Folder;
- break;
- }
-
-#ifdef HAVE_LCD_BITMAP
- return (char *)bitmap_icons_6x8[icon];
-#else
- return icon;
-#endif
-}