summaryrefslogtreecommitdiff
path: root/apps/dbtree.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/dbtree.c')
-rw-r--r--apps/dbtree.c64
1 files changed, 45 insertions, 19 deletions
diff --git a/apps/dbtree.c b/apps/dbtree.c
index ef8d2e5628..58f70e2d2b 100644
--- a/apps/dbtree.c
+++ b/apps/dbtree.c
@@ -130,7 +130,7 @@ int db_load(struct tree_context* c)
130{ 130{
131 int i, offset, rc; 131 int i, offset, rc;
132 int dcachesize = global_settings.max_files_in_dir * sizeof(struct entry); 132 int dcachesize = global_settings.max_files_in_dir * sizeof(struct entry);
133 int max_items, itemcount, stringlen; 133 int itemcount, stringlen, hits=0;
134 unsigned int* nptr = (void*) c->name_buffer; 134 unsigned int* nptr = (void*) c->name_buffer;
135 unsigned int* dptr = c->dircache; 135 unsigned int* dptr = c->dircache;
136 unsigned int* safeplace = NULL; 136 unsigned int* safeplace = NULL;
@@ -269,33 +269,30 @@ int db_load(struct tree_context* c)
269 stringlen = songlen; 269 stringlen = songlen;
270 break; 270 break;
271 271
272 case songs4artist:
273 /* 'extra' is offset to the artist, used as filter */
274 offset = songstart;
275 itemcount = songcount;
276 stringlen = songlen;
277 break;
278
272 default: 279 default:
273 DEBUGF("Unsupported table %d\n", table); 280 DEBUGF("Unsupported table %d\n", table);
274 return -1; 281 return -1;
275 } 282 }
276 max_items = dcachesize / (c->dentry_size * sizeof(int));
277 end_of_nbuf -= safeplacelen; 283 end_of_nbuf -= safeplacelen;
278 284
279 c->dirlength = itemcount; 285 c->dirlength = itemcount;
280 itemcount -= c->firstpos; 286 itemcount -= c->firstpos;
281 287
282 if (!safeplace) { 288 if (!safeplace)
283 //DEBUGF("Seeking to %x\n", offset);
284 lseek(fd, offset, SEEK_SET); 289 lseek(fd, offset, SEEK_SET);
285 }
286 290
287 /* name_buffer (nptr) contains only names, null terminated. 291 /* name_buffer (nptr) contains only names, null terminated.
288 the first word of dcache (dptr) is a pointer to the name, 292 the first word of dcache (dptr) is a pointer to the name,
289 the rest is table specific. see below. */ 293 the rest is table specific. see below. */
290 294
291 if (itemcount > max_items) 295 for ( i=0; i < itemcount; i++ ) {
292 c->dirfull = true;
293
294 if (max_items > itemcount) {
295 max_items = itemcount;
296 }
297
298 for ( i=0; i < max_items; i++ ) {
299 int rc, skip=0; 296 int rc, skip=0;
300 int intbuf[4]; 297 int intbuf[4];
301 298
@@ -316,17 +313,19 @@ int db_load(struct tree_context* c)
316 return -1; 313 return -1;
317 } 314 }
318 315
319 /* store name pointer in dir cache */
320 dptr[0] = (unsigned int)nptr;
321
322 switch (table) { 316 switch (table) {
323 case allsongs: 317 case allsongs:
324 case songs4album: 318 case songs4album:
319 case songs4artist:
325 rc = read(fd, intbuf, 12); 320 rc = read(fd, intbuf, 12);
326 if (rc < 12) { 321 if (rc < 12) {
327 DEBUGF("%d read(%d) returned %d\n", i, 12, rc); 322 DEBUGF("%d read(%d) returned %d\n", i, 12, rc);
328 return -1; 323 return -1;
329 } 324 }
325 /* continue to next song if wrong artist */
326 if (table == songs4artist && (int)BE32(intbuf[0]) != extra)
327 continue;
328
330 /* save offset of filename */ 329 /* save offset of filename */
331 dptr[1] = BE32(intbuf[2]); 330 dptr[1] = BE32(intbuf[2]);
332 break; 331 break;
@@ -345,8 +344,13 @@ int db_load(struct tree_context* c)
345 break; 344 break;
346 } 345 }
347 346
347 /* store name pointer in dir cache */
348 dptr[0] = (unsigned int)nptr;
349
348 if (skip) 350 if (skip)
349 lseek(fd, skip, SEEK_CUR); 351 lseek(fd, skip, SEEK_CUR);
352
353 hits++;
350 354
351 /* next name is stored immediately after this */ 355 /* next name is stored immediately after this */
352 nptr = (void*)nptr + strlen((char*)nptr) + 1; 356 nptr = (void*)nptr + strlen((char*)nptr) + 1;
@@ -354,15 +358,30 @@ int db_load(struct tree_context* c)
354 c->dirfull = true; 358 c->dirfull = true;
355 break; 359 break;
356 } 360 }
361
362 /* limit dir buffer */
357 dptr = (void*)dptr + c->dentry_size * sizeof(int); 363 dptr = (void*)dptr + c->dentry_size * sizeof(int);
364 if ((void*)(dptr + c->dentry_size) >
365 (void*)(c->dircache + dcachesize))
366 {
367 c->dirfull = true;
368 break;
369 }
358 370
359 if (!safeplace) 371 if (!safeplace)
360 offset += stringlen + skip; 372 offset += stringlen + skip;
361 } 373 }
362 374
363 c->filesindir = i; 375 if (c->currtable == albums4artist && !c->dirfull) {
376 strcpy((char*)nptr, str(LANG_ID3DB_ALL_SONGS));
377 dptr[0] = (unsigned int)nptr;
378 dptr[1] = extra; /* offset to artist */
379 hits++;
380 }
381
382 c->filesindir = hits;
364 383
365 return i; 384 return hits;
366} 385}
367 386
368static int db_search(struct tree_context* c, char* string) 387static int db_search(struct tree_context* c, char* string)
@@ -476,7 +495,13 @@ int db_enter(struct tree_context* c)
476 case allalbums: 495 case allalbums:
477 case albums4artist: 496 case albums4artist:
478 case searchalbums: 497 case searchalbums:
479 c->currtable = songs4album; 498 /* virtual <all albums> entry points to the artist,
499 all normal entries point to the album */
500 if (newextra >= artiststart)
501 c->currtable = songs4artist;
502 else
503 c->currtable = songs4album;
504
480 c->currextra = newextra; 505 c->currextra = newextra;
481 break; 506 break;
482 507
@@ -563,6 +588,7 @@ int db_get_icon(struct tree_context* c)
563 { 588 {
564 case allsongs: 589 case allsongs:
565 case songs4album: 590 case songs4album:
591 case songs4artist:
566 case searchsongs: 592 case searchsongs:
567 icon = File; 593 icon = File;
568 break; 594 break;