rockbox/tools/testdbv2.c
Michiel Van Der Kolk c735ed7914 First runtime database support, self repairing, only playcount works for now,
which is still rather crude; playcount gets increased even if the song started playback but was skipped... track rating should be trivial to add, autorating also works since its based on playcount.


git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6969 a1c6a512-1295-4272-9138-f99709370657
2005-07-01 17:29:44 +00:00

253 lines
7.6 KiB
C

#include <stdlib.h>
#include <stdio.h>
#define ARTISTLEN 60
#define ALBUMLEN 64
#define SONGLEN 120
#define GENRELEN 28
#define FILELEN 176
#define SONGARRAYLEN 715
#define ALBUMARRAYLEN 186
#define BE32(_x_) (((_x_ & 0xff000000) >> 24) | \
((_x_ & 0x00ff0000) >> 8) | \
((_x_ & 0x0000ff00) << 8) | \
((_x_ & 0x000000ff) << 24))
#define BE16(_x_) ( ((_x_&0xff00) >> 8) | ((_x_&0xff)<<8))
struct header {
int version;
int artiststart;
int albumstart;
int songstart;
int filestart;
int artistcount;
int albumcount;
int songcount;
int filecount;
int artistlen;
int albumlen;
int songlen;
int genrelen;
int filelen;
int songarraylen;
int albumarraylen;
int rundbdirty;
} header;
struct FileEntry {
char name[FILELEN];
int hash;
int tagoffset;
int rundboffset;
} FileEntry;
struct SongEntry {
char name[SONGLEN];
int artist;
int album;
int file;
char genre[GENRELEN];
short bitrate;
short year;
} SongEntry;
struct ArtistEntry {
char name[ARTISTLEN];
int album[ALBUMARRAYLEN];
} ArtistEntry;
struct AlbumEntry {
char name[ALBUMLEN];
int artist;
int song[SONGARRAYLEN];
} AlbumEntry;
struct RundbHeader {
int version;
int entrycount;
} RundbHeader;
struct RundbEntry {
int file;
int hash;
short rating;
short voladj;
int playcount;
int lastplayed;
} RundbEntry;
FILE *fp,*fp2;
void showsong(int offset) {
fseek(fp,offset,SEEK_SET);
fread(&SongEntry,sizeof(struct SongEntry),1,fp);
SongEntry.artist=BE32(SongEntry.artist);
SongEntry.album=BE32(SongEntry.album);
SongEntry.file=BE32(SongEntry.file);
SongEntry.year=BE16(SongEntry.year);
SongEntry.bitrate=BE16(SongEntry.bitrate);
printf("Offset: 0x%x\nName: %s\nArtist: 0x%x\nAlbum: 0x%x\nFile: 0x%x\nGenre: %s\nBitrate: %d\nYear: %d\n\n",offset,SongEntry.name,SongEntry.artist,SongEntry.album,SongEntry.file,SongEntry.genre,SongEntry.bitrate,SongEntry.year);
}
void showalbum(int offset) {
int i;
fseek(fp,offset,SEEK_SET);
fread(&AlbumEntry,sizeof(struct AlbumEntry),1,fp);
AlbumEntry.artist=BE32(AlbumEntry.artist);
printf("Offset: 0x%x\nAlbum: %s\nArtist: 0x%x\n",offset,AlbumEntry.name,AlbumEntry.artist);
for(i=0;i<header.songarraylen;i++) {
AlbumEntry.song[i]=BE32(AlbumEntry.song[i]);
printf("Song %d: 0x%x\n",i,AlbumEntry.song[i]);
}
}
void showfile(int offset) {
fseek(fp,offset,SEEK_SET);
fread(&FileEntry,sizeof(struct FileEntry),1,fp);
FileEntry.hash=BE32(FileEntry.hash);
FileEntry.tagoffset=BE32(FileEntry.tagoffset);
FileEntry.rundboffset=BE32(FileEntry.rundboffset);
printf("Offset: 0x%x\nFilename: %s\nHash: 0x%x\nTag: 0x%x\nRunDB: 0x%x\n",
offset,FileEntry.name,FileEntry.hash,
FileEntry.tagoffset, FileEntry.rundboffset);
}
void showartist(int offset) {
int i;
fseek(fp,offset,SEEK_SET);
fread(&ArtistEntry,sizeof(struct ArtistEntry),1,fp);
printf("Offset: 0x%x\nArtist: %s\n",offset,ArtistEntry.name);
for(i=0;i<header.albumarraylen;i++) {
ArtistEntry.album[i]=BE32(ArtistEntry.album[i]);
printf("Album %d: 0x%x\n",i,ArtistEntry.album[i]);
}
}
void showrundb(int offset) {
fseek(fp2,offset,SEEK_SET);
fread(&RundbEntry,sizeof(struct RundbEntry),1,fp2);
RundbEntry.file=BE32(RundbEntry.file);
RundbEntry.hash=BE32(RundbEntry.hash);
RundbEntry.playcount=BE32(RundbEntry.playcount);
RundbEntry.lastplayed=BE32(RundbEntry.lastplayed);
RundbEntry.rating=BE16(RundbEntry.rating);
RundbEntry.voladj=BE16(RundbEntry.voladj);
printf("Offset: 0x%x\nFileEntry: 0x%x\nHash: 0x%x\nRating: %d\nVoladj: 0x%x\n",offset,RundbEntry.file,RundbEntry.hash,RundbEntry.rating,RundbEntry.voladj);
printf("Playcount: 0x%x\nLastplayed: %d\n",RundbEntry.playcount,RundbEntry.lastplayed);
}
int main() {
fp=fopen("rockbox.tagdb","r");
fp2=fopen("rockbox.rundb","r");
int *p,i,temp,temp2,temp3,temp4;
if(fp<0) return -1;
fread(&header,sizeof(header),1,fp);
p=&header;
for(i=0;i<17;i++) {
*p=BE32(*p);
p++;
}
if(fp2>=0) {
fread(&RundbHeader,sizeof(RundbHeader),1,fp2);
p=&RundbHeader;
for(i=0;i<2;i++) {
*p=BE32(*p);
p++;
}
}
printf("db version : 0x%x\n",header.version&0xFF);
printf("Artist start : 0x%x\n",header.artiststart);
printf("Album start : 0x%x\n",header.albumstart);
printf("Song start : 0x%x\n",header.songstart);
printf("File start : 0x%x\n",header.filestart);
printf("Artist count : %d\n",header.artistcount);
printf("Album count : %d\n",header.albumcount);
printf("Song count : %d\n",header.songcount);
printf("File count : %d\n",header.filecount);
printf("Artist len : %d\n",header.artistlen);
printf("Album len : %d\n",header.albumlen);
printf("Song len : %d\n",header.songlen);
printf("Genre len : %d\n",header.genrelen);
printf("File len : %d\n",header.filelen);
printf("Songarraylen : %d\n",header.songarraylen);
printf("Albumarraylen : %d\n",header.albumarraylen);
printf("Rundb dirty : %d\n",header.rundbdirty);
if(fp2>=0) {
printf("Rundb version : 0x%x\n",RundbHeader.version&0xFF);
printf("Rundb entrys : %d\n",RundbHeader.entrycount);
}
if( sizeof(struct SongEntry)!=(header.songlen+header.genrelen+16)) {
printf("Song Entry Size mismatch.. update the code to correct size.\n");
return;
}
if(sizeof(struct AlbumEntry)!=(header.albumlen+4+header.songarraylen*4)) {
printf("Album Entry Size mismatch.. update the code to correct size.\n");
return;
}
if(sizeof(struct ArtistEntry)!=(header.artistlen+header.albumarraylen*4)) {
printf("Artist Entry Size mismatch.. update the code to correct size.\n");
return;
}
if(sizeof(struct FileEntry)!=(header.filelen+12)) {
printf("File Entry Size mismatch.. update the code to correct size.\n");
return;
}
do {
printf("\n\nShow artist(1)/album(2)/song(3)/file(4)");
if(fp2>=0) printf("/rundb(5)");
printf(" ? ");
fflush(stdout);
temp=temp2=temp3=0;
scanf("%d",&temp);
printf("Record (-1 for offset) ? ");
fflush(stdout);
scanf("%d",&temp2);
if(temp2==-1) {
printf("Offset ? 0x");
fflush(stdout);
scanf("%x",&temp3);
}
switch(temp) {
case 1:
if(temp2==-1)
showartist(temp3);
else
showartist(header.artiststart +
temp2*sizeof(struct ArtistEntry));
break;
case 2:
if(temp2==-1)
showalbum(temp3);
else
showalbum(header.albumstart +
temp2*sizeof(struct AlbumEntry));
break;
case 3:
if(temp2==-1)
showsong(temp3);
else
showsong(header.songstart +
temp2*sizeof(struct SongEntry));
break;
case 4:
if(temp2==-1)
showfile(temp3);
else
showfile(header.filestart +
temp2*sizeof(struct FileEntry));
break;
case 5: if(temp2==-1)
showrundb(temp3);
else
showrundb(8+temp2*sizeof(struct RundbEntry));
break;
default:
return;
break;
}
} while(1);
fclose(fp);
}