diff options
Diffstat (limited to 'apps/dbtree.c')
-rw-r--r-- | apps/dbtree.c | 81 |
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 | ||
124 | int db_load(struct tree_context* c, bool* dir_buffer_full) | 124 | int 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 | ||
340 | void db_exit(struct tree_context* c) | 348 | void 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 | ||