/*************************************************************************** * __________ __ ___. * Open \______ \ ____ ____ | | _\_ |__ _______ ___ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ * $Id$ * * Copyright (C) 2005 by Michiel van der Kolk * * This program 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 Foundation; either version 2 * of the License, or (at your option) any later version. * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * ****************************************************************************/ #include "searchengine.h" #include "dbinterface.h" #undef SONGENTRY_SIZE #undef FILEENTRY_SIZE #undef ALBUMENTRY_SIZE #undef ARTISTENTRY_SIZE #undef FILERECORD2OFFSET #define SONGENTRY_SIZE (rb->tagdbheader->songlen+12+rb->tagdbheader->genrelen+12) #define FILEENTRY_SIZE (rb->tagdbheader->filelen+12) #define ALBUMENTRY_SIZE (rb->tagdbheader->albumlen+4+rb->tagdbheader->songarraylen*4) #define ARTISTENTRY_SIZE (rb->tagdbheader->artistlen+rb->tagdbheader->albumarraylen*4) #define RUNDBENTRY_SIZE 20 #define FILERECORD2OFFSET(_x_) (rb->tagdbheader->filestart + _x_ * FILEENTRY_SIZE) struct dbentry *currententry; struct dbglobals dbglobal; static struct dbentry *entryarray; int database_init() { char *p; unsigned int i; // allocate room for all entries entryarray=(struct dbentry *)my_malloc(sizeof(struct dbentry)*rb->tagdbheader->filecount); p=(char *)entryarray; // zero all entries. for(i=0;itagdbheader->filecount;i++) *(p++)=0; if(!*rb->tagdb_initialized) { if(!rb->tagdb_init()) { // failed loading db return -1; } } dbglobal.playcountmin=0; dbglobal.playcountmax=0; dbglobal.gotplaycountlimits=0; return 0; } long readlong(int fd) { long num; rb->read(fd,&num,4); #ifdef ROCKBOX_LITTLE_ENDIAN num=BE32(num); #endif return num; } short readshort(int fd) { short num; rb->read(fd,&num,2); #ifdef ROCKBOX_LITTLE_ENDIAN num=BE16(num); #endif return num; } void loadentry(int filerecord) { if(entryarray[filerecord].loadedfiledata==0) { rb->lseek(*rb->tagdb_fd,FILERECORD2OFFSET(filerecord),SEEK_SET); entryarray[filerecord].filename=(char *)my_malloc(rb->tagdbheader->filelen); rb->read(*rb->tagdb_fd,entryarray[filerecord].filename,rb->tagdbheader->filelen); entryarray[filerecord].hash=readlong(*rb->tagdb_fd); entryarray[filerecord].songentry=readlong(*rb->tagdb_fd); entryarray[filerecord].rundbentry=readlong(*rb->tagdb_fd); entryarray[filerecord].loadedfiledata=1; } currententry=&entryarray[filerecord]; dbglobal.currententryindex=filerecord; } void loadsongdata() { if(currententry->loadedsongdata) return; currententry->title=(char *)my_malloc(rb->tagdbheader->songlen); currententry->genre=(char *)my_malloc(rb->tagdbheader->genrelen); rb->lseek(*rb->tagdb_fd,currententry->songentry,SEEK_SET); rb->read(*rb->tagdb_fd,currententry->title,rb->tagdbheader->songlen); currententry->artistoffset=readlong(*rb->tagdb_fd); currententry->albumoffset=readlong(*rb->tagdb_fd); rb->lseek(*rb->tagdb_fd,4,SEEK_CUR); rb->read(*rb->tagdb_fd,currententry->genre,rb->tagdbheader->genrelen); currententry->bitrate=readshort(*rb->tagdb_fd); currententry->year=readshort(*rb->tagdb_fd); currententry->playtime=readlong(*rb->tagdb_fd); currententry->track=readshort(*rb->tagdb_fd); currententry->samplerate=readshort(*rb->tagdb_fd); currententry->loadedsongdata=1; } void loadrundbdata() { currententry->loadedrundbdata=1; if(!*rb->rundb_initialized) return; if(currententry->rundbentry==-1) return; rb->lseek(*rb->rundb_fd,currententry->rundbentry,SEEK_SET); currententry->rundbfe=readlong(*rb->rundb_fd); currententry->rundbhash=readlong(*rb->rundb_fd); currententry->rating=readshort(*rb->rundb_fd); currententry->voladj=readshort(*rb->rundb_fd); currententry->playcount=readlong(*rb->rundb_fd); currententry->lastplayed=readlong(*rb->rundb_fd); } void loadartistname() { /* memory optimization possible, only malloc for an album name once, then * write that pointer to the entrys using it. */ if(currententry->loadedartistname) return; loadsongdata(); currententry->artistname=(char *)my_malloc(rb->tagdbheader->artistlen); rb->lseek(*rb->tagdb_fd,currententry->artistoffset,SEEK_SET); rb->read(*rb->tagdb_fd,currententry->artistname,rb->tagdbheader->artistlen); currententry->loadedartistname=1; } void loadalbumname() { /* see the note at loadartistname */ if(currententry->loadedalbumname) return; loadsongdata(); currententry->albumname=(char *)my_malloc(rb->tagdbheader->albumlen); rb->lseek(*rb->tagdb_fd,currententry->albumoffset,SEEK_SET); rb->read(*rb->tagdb_fd,currententry->albumname,rb->tagdbheader->albumlen); currententry->loadedalbumname=1; } char *getfilename(int entry) { if(entryarray[entry].loadedfiledata==0) return "error O.o;;;"; else return entryarray[entry].filename; }