summaryrefslogtreecommitdiff
path: root/apps/dbtree.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/dbtree.c')
-rw-r--r--apps/dbtree.c81
1 files changed, 45 insertions, 36 deletions
diff --git a/apps/dbtree.c b/apps/dbtree.c
index 68a211a836..abe8aed647 100644
--- a/apps/dbtree.c
+++ b/apps/dbtree.c
@@ -121,18 +121,21 @@ int db_init(void)
121 return 0; 121 return 0;
122} 122}
123 123
124int db_load(struct tree_context* c, bool* dir_buffer_full) 124int db_load(struct tree_context* c)
125{ 125{
126 int i, offset, len, rc; 126 int i, offset, rc;
127 int dcachesize = global_settings.max_files_in_dir * sizeof(struct entry); 127 int dcachesize = global_settings.max_files_in_dir * sizeof(struct entry);
128 int max_items, itemcount, stringlen; 128 int max_items, itemcount, stringlen;
129 unsigned int* nptr = (void*) c->name_buffer; 129 unsigned int* nptr = (void*) c->name_buffer;
130 unsigned int* dptr = c->dircache; 130 unsigned int* dptr = c->dircache;
131 unsigned int* safeplace = NULL; 131 unsigned int* safeplace = NULL;
132 int safeplacelen = 0;
132 133
133 int table = c->currtable; 134 int table = c->currtable;
134 int extra = c->currextra; 135 int extra = c->currextra;
135 136
137 char* end_of_nbuf = c->name_buffer + c->name_buffer_size;
138
136 if (!initialized) { 139 if (!initialized) {
137 DEBUGF("ID3 database is not initialized.\n"); 140 DEBUGF("ID3 database is not initialized.\n");
138 c->filesindir = 0; 141 c->filesindir = 0;
@@ -140,8 +143,9 @@ int db_load(struct tree_context* c, bool* dir_buffer_full)
140 } 143 }
141 144
142 c->dentry_size = 2 * sizeof(int); 145 c->dentry_size = 2 * sizeof(int);
143 146 c->dirfull = false;
144 DEBUGF("db_load(%d, %x)\n", table, extra); 147
148 DEBUGF("db_load(%d, %x, %d)\n", table, extra, c->firstpos);
145 149
146 if (!table) { 150 if (!table) {
147 table = allartists; 151 table = allartists;
@@ -150,51 +154,50 @@ int db_load(struct tree_context* c, bool* dir_buffer_full)
150 154
151 switch (table) { 155 switch (table) {
152 case allsongs: 156 case allsongs:
153 offset = songstart; 157 offset = songstart + c->firstpos * (songlen + 12);
154 itemcount = songcount; 158 itemcount = songcount;
155 stringlen = songlen; 159 stringlen = songlen;
156 break; 160 break;
157 161
158 case allalbums: 162 case allalbums:
159 offset = albumstart; 163 offset = albumstart +
164 c->firstpos * (albumlen + 4 + songarraylen * 4);
160 itemcount = albumcount; 165 itemcount = albumcount;
161 stringlen = albumlen; 166 stringlen = albumlen;
162 break; 167 break;
163 168
164 case allartists: 169 case allartists:
165 offset = artiststart; 170 offset = artiststart +
171 c->firstpos * (artistlen + albumarraylen * 4);
166 itemcount = artistcount; 172 itemcount = artistcount;
167 stringlen = artistlen; 173 stringlen = artistlen;
168 break; 174 break;
169 175
170 case albums: 176 case albums4artist:
171 /* 'extra' is offset to the artist */ 177 /* 'extra' is offset to the artist */
172 len = albumarraylen * 4; 178 safeplacelen = albumarraylen * 4;
173 safeplace = (void*)(c->name_buffer + c->name_buffer_size - len); 179 safeplace = (void*)(end_of_nbuf - safeplacelen);
174 //DEBUGF("Seeking to %x\n", extra + artistlen);
175 lseek(fd, extra + artistlen, SEEK_SET); 180 lseek(fd, extra + artistlen, SEEK_SET);
176 rc = read(fd, safeplace, len); 181 rc = read(fd, safeplace, safeplacelen);
177 if (rc < len) 182 if (rc < safeplacelen)
178 return -1; 183 return -1;
179 184
180#ifdef LITTLE_ENDIAN 185#ifdef LITTLE_ENDIAN
181 for (i=0; i<albumarraylen; i++) 186 for (i=0; i<albumarraylen; i++)
182 safeplace[i] = BE32(safeplace[i]); 187 safeplace[i] = BE32(safeplace[i]);
183#endif 188#endif
184
185 offset = safeplace[0]; 189 offset = safeplace[0];
186 itemcount = albumarraylen; 190 itemcount = albumarraylen;
187 stringlen = albumlen; 191 stringlen = albumlen;
188 break; 192 break;
189 193
190 case songs: 194 case songs4album:
191 /* 'extra' is offset to the album */ 195 /* 'extra' is offset to the album */
192 len = songarraylen * 4; 196 safeplacelen = songarraylen * 4;
193 safeplace = (void*)(c->name_buffer + c->name_buffer_size - len); 197 safeplace = (void*)(end_of_nbuf - safeplacelen);
194 //DEBUGF("Seeking to %x\n", extra + albumlen + 4);
195 lseek(fd, extra + albumlen + 4, SEEK_SET); 198 lseek(fd, extra + albumlen + 4, SEEK_SET);
196 rc = read(fd, safeplace, len); 199 rc = read(fd, safeplace, safeplacelen);
197 if (rc < len) 200 if (rc < safeplacelen)
198 return -1; 201 return -1;
199 202
200#ifdef LITTLE_ENDIAN 203#ifdef LITTLE_ENDIAN
@@ -211,6 +214,10 @@ int db_load(struct tree_context* c, bool* dir_buffer_full)
211 return -1; 214 return -1;
212 } 215 }
213 max_items = dcachesize / c->dentry_size; 216 max_items = dcachesize / c->dentry_size;
217 end_of_nbuf -= safeplacelen;
218
219 c->dirlength = itemcount;
220 itemcount -= c->firstpos;
214 221
215 if (!safeplace) { 222 if (!safeplace) {
216 //DEBUGF("Seeking to %x\n", offset); 223 //DEBUGF("Seeking to %x\n", offset);
@@ -222,8 +229,7 @@ int db_load(struct tree_context* c, bool* dir_buffer_full)
222 the rest is table specific. see below. */ 229 the rest is table specific. see below. */
223 230
224 if (itemcount > max_items) 231 if (itemcount > max_items)
225 if (dir_buffer_full) 232 c->dirfull = true;
226 *dir_buffer_full = true;
227 233
228 if (max_items > itemcount) { 234 if (max_items > itemcount) {
229 max_items = itemcount; 235 max_items = itemcount;
@@ -233,8 +239,10 @@ int db_load(struct tree_context* c, bool* dir_buffer_full)
233 int rc, skip=0; 239 int rc, skip=0;
234 240
235 if (safeplace) { 241 if (safeplace) {
236 if (!safeplace[i]) 242 if (!safeplace[i]) {
243 c->dirlength = i;
237 break; 244 break;
245 }
238 //DEBUGF("Seeking to %x\n", safeplace[i]); 246 //DEBUGF("Seeking to %x\n", safeplace[i]);
239 lseek(fd, safeplace[i], SEEK_SET); 247 lseek(fd, safeplace[i], SEEK_SET);
240 offset = safeplace[i]; 248 offset = safeplace[i];
@@ -252,15 +260,15 @@ int db_load(struct tree_context* c, bool* dir_buffer_full)
252 dptr[0] = (unsigned int)nptr; 260 dptr[0] = (unsigned int)nptr;
253 261
254 switch (table) { 262 switch (table) {
255 case songs:
256 case allsongs: 263 case allsongs:
264 case songs4album:
257 /* save offset of this song */ 265 /* save offset of this song */
258 skip = 12; 266 skip = 12;
259 dptr[1] = offset; 267 dptr[1] = offset;
260 break; 268 break;
261 269
262 case allalbums: 270 case allalbums:
263 case albums: 271 case albums4artist:
264 /* save offset of this album */ 272 /* save offset of this album */
265 skip = songarraylen * 4 + 4; 273 skip = songarraylen * 4 + 4;
266 dptr[1] = offset; 274 dptr[1] = offset;
@@ -273,15 +281,14 @@ int db_load(struct tree_context* c, bool* dir_buffer_full)
273 break; 281 break;
274 } 282 }
275 283
276 //DEBUGF("%x: %s\n", dptr[1], dptr[0]);
277
278 if (skip) 284 if (skip)
279 lseek(fd, skip, SEEK_CUR); 285 lseek(fd, skip, SEEK_CUR);
280 286
281 /* next name is stored immediately after this */ 287 /* next name is stored immediately after this */
282 nptr = (void*)nptr + strlen((char*)nptr) + 1; 288 nptr = (void*)nptr + strlen((char*)nptr) + 1;
283 if ((void*)nptr > (void*)c->name_buffer + c->name_buffer_size) { 289 if ((void*)nptr > (void*)end_of_nbuf) {
284 DEBUGF("Name buffer overflow (%d)\n",i); 290 DEBUGF("Name buffer overflow (%d)\n",i);
291 c->dirfull = true;
285 break; 292 break;
286 } 293 }
287 dptr = (void*)dptr + c->dentry_size; 294 dptr = (void*)dptr + c->dentry_size;
@@ -299,11 +306,12 @@ void db_enter(struct tree_context* c)
299{ 306{
300 switch (c->currtable) { 307 switch (c->currtable) {
301 case allartists: 308 case allartists:
302 case albums: 309 case albums4artist:
303 c->dirpos[c->dirlevel] = c->dirstart; 310 c->dirpos[c->dirlevel] = c->dirstart;
304 c->cursorpos[c->dirlevel] = c->dircursor; 311 c->cursorpos[c->dirlevel] = c->dircursor;
305 c->table_history[c->dirlevel] = c->currtable; 312 c->table_history[c->dirlevel] = c->currtable;
306 c->extra_history[c->dirlevel] = c->currextra; 313 c->extra_history[c->dirlevel] = c->currextra;
314 c->pos_history[c->dirlevel] = c->firstpos;
307 c->dirlevel++; 315 c->dirlevel++;
308 break; 316 break;
309 317
@@ -313,16 +321,16 @@ void db_enter(struct tree_context* c)
313 321
314 switch (c->currtable) { 322 switch (c->currtable) {
315 case allartists: 323 case allartists:
316 c->currtable = albums; 324 c->currtable = albums4artist;
317 c->currextra = ((int*)c->dircache)[(c->dircursor + c->dirstart)*2 + 1]; 325 c->currextra = ((int*)c->dircache)[(c->dircursor + c->dirstart)*2 + 1];
318 break; 326 break;
319 327
320 case albums: 328 case albums4artist:
321 c->currtable = songs; 329 c->currtable = songs4album;
322 c->currextra = ((int*)c->dircache)[(c->dircursor + c->dirstart)*2 + 1]; 330 c->currextra = ((int*)c->dircache)[(c->dircursor + c->dirstart)*2 + 1];
323 break; 331 break;
324 332
325 case songs: 333 case songs4album:
326 splash(HZ,true,"No playing implemented yet"); 334 splash(HZ,true,"No playing implemented yet");
327#if 0 335#if 0
328 /* find filenames, build playlist, play */ 336 /* find filenames, build playlist, play */
@@ -334,7 +342,7 @@ void db_enter(struct tree_context* c)
334 break; 342 break;
335 } 343 }
336 344
337 c->dirstart = c->dircursor = 0; 345 c->dirstart = c->dircursor = c->firstpos = 0;
338} 346}
339 347
340void db_exit(struct tree_context* c) 348void db_exit(struct tree_context* c)
@@ -344,6 +352,7 @@ void db_exit(struct tree_context* c)
344 c->dircursor = c->cursorpos[c->dirlevel]; 352 c->dircursor = c->cursorpos[c->dirlevel];
345 c->currtable = c->table_history[c->dirlevel]; 353 c->currtable = c->table_history[c->dirlevel];
346 c->currextra = c->extra_history[c->dirlevel]; 354 c->currextra = c->extra_history[c->dirlevel];
355 c->firstpos = c->pos_history[c->dirlevel];
347} 356}
348 357
349#ifdef HAVE_LCD_BITMAP 358#ifdef HAVE_LCD_BITMAP
@@ -354,7 +363,7 @@ const char* db_get_icon(struct tree_context* c)
354 switch (c->currtable) 363 switch (c->currtable)
355 { 364 {
356 case allsongs: 365 case allsongs:
357 case songs: 366 case songs4album:
358 icon = File; 367 icon = File;
359 break; 368 break;
360 369
@@ -372,7 +381,7 @@ int db_get_icon(struct tree_context* c)
372 switch (c->currtable) 381 switch (c->currtable)
373 { 382 {
374 case allsongs: 383 case allsongs:
375 case songs: 384 case songs4album:
376 icon = File; 385 icon = File;
377 break; 386 break;
378 387