summaryrefslogtreecommitdiff
path: root/apps/tagdb/parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/tagdb/parser.c')
-rw-r--r--apps/tagdb/parser.c218
1 files changed, 218 insertions, 0 deletions
diff --git a/apps/tagdb/parser.c b/apps/tagdb/parser.c
new file mode 100644
index 0000000000..1d251dcbe3
--- /dev/null
+++ b/apps/tagdb/parser.c
@@ -0,0 +1,218 @@
1#include <stdio.h>
2#include <stdint.h>
3#include <stdlib.h>
4
5#include "config.h"
6
7int errno;
8
9int read_failure(FILE *fd) {
10 fprintf(stderr, "Could not read from file: errno: %u ", errno);
11 if( feof(fd) ) fprintf(stderr, "EOF");
12 fprintf(stderr, "\n");
13 return 1;
14}
15
16int mem_failure() {
17 fprintf(stderr, "Could not (re)allocate memory\n");
18 return 1;
19}
20
21int main(int argc, char *argv[]) {
22 FILE *fd;
23 uint32_t artist_start, album_start, song_start, file_start;
24 uint32_t artist_count, album_count, song_count, file_count;
25 uint32_t artist_len, album_array_count;
26 uint32_t album_len, song_array_count;
27 uint32_t song_len, genre_len;
28 uint32_t file_len;
29#define header_start 0
30#define header_len 68
31
32 uint32_t i, j;
33 char *ct1 = NULL, *ct2 = NULL; // char temp 1 and 2
34 uint32_t it = 0; // integer temp
35
36 // input validation
37 if( argc != 2 ) {
38 fprintf(stderr, "usage: parser dbfile\n");
39 return 1;
40 }
41
42 // open file
43 fd = fopen(argv[1], "r");
44 if( fd == NULL ) {
45 fprintf(stderr, "Could not open file \"%s\"\n", argv[1]);
46 return 1;
47 }
48
49 // read the header
50 ct1 = realloc(ct1, 4); if( ct1 == NULL ) return mem_failure();
51 if( fread(ct1, 4, 1, fd) != 1 ) return read_failure(fd);
52 if( ct1[0] != 'R' || ct1[1] != 'D' || ct1[2] != 'B' ) {
53 printf("No header found\n");
54 return 1;
55 }
56 if( ct1[3] != 0x03 ) {
57 printf("Not version 3\n");
58 return 1;
59 }
60
61 if( fread(&artist_start, 4, 1, fd) != 1 ) return read_failure(fd); artist_start = BE32(artist_start);
62 if( fread(&album_start, 4, 1, fd) != 1 ) return read_failure(fd); album_start = BE32(album_start);
63 if( fread(&song_start, 4, 1, fd) != 1 ) return read_failure(fd); song_start = BE32(song_start);
64 if( fread(&file_start, 4, 1, fd) != 1 ) return read_failure(fd); file_start = BE32(file_start);
65
66 if( fread(&artist_count, 4, 1, fd) != 1 ) return read_failure(fd); artist_count = BE32(artist_count);
67 if( fread(&album_count, 4, 1, fd) != 1 ) return read_failure(fd); album_count = BE32(album_count);
68 if( fread(&song_count, 4, 1, fd) != 1 ) return read_failure(fd); song_count = BE32(song_count);
69 if( fread(&file_count, 4, 1, fd) != 1 ) return read_failure(fd); file_count = BE32(file_count);
70
71 if( fread(&artist_len, 4, 1, fd) != 1 ) return read_failure(fd); artist_len = BE32(artist_len);
72 if( fread(&album_len, 4, 1, fd) != 1 ) return read_failure(fd); album_len = BE32(album_len);
73 if( fread(&song_len, 4, 1, fd) != 1 ) return read_failure(fd); song_len = BE32(song_len);
74 if( fread(&genre_len, 4, 1, fd) != 1 ) return read_failure(fd); genre_len = BE32(genre_len);
75 if( fread(&file_len, 4, 1, fd) != 1 ) return read_failure(fd); file_len = BE32(file_len);
76
77 if( fread(&song_array_count, 4, 1, fd) != 1 ) return read_failure(fd); song_array_count = BE32(song_array_count);
78 if( fread(&album_array_count, 4, 1, fd) != 1 ) return read_failure(fd); album_array_count = BE32(album_array_count);
79
80 if( fread(ct1, 4, 1, fd) != 1 ) return read_failure(fd);
81
82 // print header info
83 printf("HEADER");
84 printf("\n Artist start: 0x%08x = %u", artist_start, artist_start);
85 if( artist_start != header_start + header_len )
86 printf(" should be 0x%08x = %u", header_start + header_len, header_start + header_len);
87 printf("\n Album start: 0x%08x = %u", album_start, album_start);
88 if( album_start != artist_start + artist_count*(artist_len + 4*album_array_count) )
89 printf(" should be 0x%08x = %u", artist_start + artist_count*(artist_len + 4*album_array_count),
90 artist_start + artist_count*(artist_len + 4*album_array_count));
91 printf("\n Song start: 0x%08x = %u", song_start, song_start);
92 if( song_start != album_start + album_count*(album_len + 4 + 4*song_array_count) )
93 printf(" should be 0x%08x = %u", album_start + album_count*(album_len + 4 + 4*song_array_count),
94 album_start + album_count*(album_len + 4 + 4*song_array_count));
95 printf("\n File start: 0x%08x = %u", file_start, file_start);
96 if( file_start != song_start + song_count*(song_len + genre_len + 24) )
97 printf(" should be 0x%08x = %u", song_start + song_count*(song_len + genre_len + 24),
98 song_start + song_count*(song_len + genre_len + 24));
99
100 printf("\n Artist count: 0x%08x = %u\n", artist_count, artist_count);
101 printf(" Album count: 0x%08x = %u\n", album_count, album_count);
102 printf(" Song count: 0x%08x = %u\n", song_count, song_count);
103 printf(" File count: 0x%08x = %u\n", file_count, file_count);
104
105 printf(" Artist len: 0x%08x = %u\n", artist_len, artist_len);
106 printf(" Album len: 0x%08x = %u\n", album_len, album_len);
107 printf(" Song len: 0x%08x = %u\n", song_len, song_len);
108 printf(" Genre len: 0x%08x = %u\n", genre_len, genre_len);
109 printf(" File len: 0x%08x = %u\n", file_len, file_len);
110
111 printf(" Song[] count: 0x%08x = %u\n", song_array_count, song_array_count);
112 printf(" Album[] count: 0x%08x = %u\n", album_array_count, album_array_count);
113
114 printf(" Reserved: 0x%08x\n", ct1[0] & 0xFFFFFFFE);
115 printf(" Rundb dirty: 0x%01x\n", ct1[3] & 0x01);
116
117 // iterate over artists:
118 ct1 = realloc(ct1, artist_len); if( ct1 == NULL && artist_count!=0 ) return mem_failure();
119 for(i=0; i < artist_count; i++) {
120 printf("ARTIST %u/%u (offset 0x%08lx)\n", i, artist_count, (unsigned long)ftell(fd));
121
122 if( fread(ct1, artist_len, 1, fd) != 1 ) return read_failure(fd);
123 printf(" Name: \"%s\"\n", ct1);
124
125 printf(" Albums:\n");
126 for(j=0; j < album_array_count; j++) {
127 if( fread(&it, 4, 1, fd) != 1 ) return read_failure(fd); it = BE32(it);
128 printf(" Offset 0x%08x = ", it);
129 if(it != 0) {
130 printf("item %u\n", (it - album_start) / (album_len + 4 + 4*song_array_count));
131 } else {
132 printf("padding\n");
133 }
134 }
135 }
136
137 // iterate over albums:
138 ct1 = realloc(ct1, album_len); if( ct1 == NULL && album_count!=0) return mem_failure();
139 for(i=0; i < album_count; i++) {
140 printf("ALBUM %u/%u (offset 0x%08lx)\n", i, album_count, (unsigned long)ftell(fd));
141
142 if( fread(ct1, album_len, 1, fd) != 1 ) return read_failure(fd);
143 printf(" Name: \"%s\"\n", ct1);
144
145 if( fread(&it, 4, 1, fd) != 1 ) return read_failure(fd); it = BE32(it);
146 printf(" Artist offset: 0x%08x = item %u\n", it, (it - artist_start) / (artist_len + 4*album_array_count));
147
148 printf(" Songs:\n");
149 for(j=0; j < song_array_count; j++) {
150 if( fread(&it, 4, 1, fd) != 1 ) return read_failure(fd); it = BE32(it);
151 printf(" Offset 0x%08x = ", it);
152 if(it != 0) {
153 printf("item %u\n", (it - song_start) / (song_len + genre_len + 24));
154 } else {
155 printf("padding\n");
156 }
157 }
158 }
159
160 // iterate over songs:
161 ct1 = realloc(ct1, song_len); if( ct1 == NULL && song_count!=0) return mem_failure();
162 ct2 = realloc(ct2, genre_len); if( ct2 == NULL && song_count!=0) return mem_failure();
163 for(i=0; i < song_count; i++) {
164 printf("SONG %u/%u (offset 0x%08lx)\n", i, song_count, (unsigned long)ftell(fd));
165
166 if( fread(ct1, song_len, 1, fd) != 1 ) return read_failure(fd);
167 printf(" Name: \"%s\"\n", ct1);
168
169 if( fread(&it, 4, 1, fd) != 1 ) return read_failure(fd); it = BE32(it);
170 printf(" Artist offset: 0x%08x = item %u\n", it, (it - artist_start) / (artist_len + 4*album_array_count));
171
172 if( fread(&it, 4, 1, fd) != 1 ) return read_failure(fd); it = BE32(it);
173 printf(" Album offset: 0x%08x = item %u\n", it, (it - album_start) / (album_len + 4 + 4*song_array_count));
174
175 if( fread(&it, 4, 1, fd) != 1 ) return read_failure(fd); it = BE32(it);
176 printf(" File offset: 0x%08x = item %u\n", it, (it - file_start) / (file_len + 12));
177
178 if( fread(ct2, genre_len, 1, fd) != 1 ) return read_failure(fd);
179 printf(" Genre: \"%s\"\n", ct2);
180
181 if( fread(&it, 4, 1, fd) != 1 ) return read_failure(fd); it = BE32(it);
182 printf(" Bitrate: 0x%04x = %u\n", (it & 0xFFFF0000) >> 16, (it & 0xFFFF0000) >> 16);
183 printf(" Year: 0x%04x = %u\n", it & 0x0000FFFF, it & 0x0000FFFF);
184
185 if( fread(&it, 4, 1, fd) != 1 ) return read_failure(fd); it = BE32(it);
186 printf(" Playtime: 0x%08x = %u\n", it, it);
187
188 if( fread(&it, 4, 1, fd) != 1 ) return read_failure(fd); it = BE32(it);
189 printf(" Track: 0x%04x = %u\n", (it & 0xFFFF0000) >> 16, (it & 0xFFFF0000) >> 16);
190 printf(" Samplerate: 0x%04x = %u\n", it & 0x0000FFFF, it & 0x0000FFFF);
191 }
192
193 // iterate over file:
194 ct1 = realloc(ct1, file_len); if( ct1 == NULL && file_count!=0) return mem_failure();
195 for(i=0; i < file_count; i++) {
196 printf("FILE %u/%u (offset 0x%08lx)\n", i, file_count, (unsigned long)ftell(fd));
197
198 if( fread(ct1, file_len, 1, fd) != 1 ) return read_failure(fd);
199 printf(" Name: \"%s\"\n", ct1);
200
201 if( fread(&it, 4, 1, fd) != 1 ) return read_failure(fd); it = BE32(it);
202 printf(" Hash: 0x%08x = %u\n", it, it);
203
204 if( fread(&it, 4, 1, fd) != 1 ) return read_failure(fd); it = BE32(it);
205 printf(" Song offset: 0x%08x = item %u\n", it, (it - song_start) / (song_len + genre_len + 24));
206
207 if( fread(&it, 4, 1, fd) != 1 ) return read_failure(fd); it = BE32(it);
208 printf(" Rundb offset: 0x%08x = %u\n", it, it);
209 }
210
211 // close the file
212 if( fclose(fd) != 0 ) {
213 fprintf(stderr, "Could not close file\n");
214 return 1;
215 }
216
217 return 0;
218}