diff options
Diffstat (limited to 'firmware/common/dircache.c')
-rw-r--r-- | firmware/common/dircache.c | 32 |
1 files changed, 27 insertions, 5 deletions
diff --git a/firmware/common/dircache.c b/firmware/common/dircache.c index 9e96404dd6..fbd7fab188 100644 --- a/firmware/common/dircache.c +++ b/firmware/common/dircache.c | |||
@@ -55,6 +55,7 @@ static bool dircache_initialized = false; | |||
55 | static bool thread_enabled = false; | 55 | static bool thread_enabled = false; |
56 | static unsigned long allocated_size = DIRCACHE_LIMIT; | 56 | static unsigned long allocated_size = DIRCACHE_LIMIT; |
57 | static unsigned long dircache_size = 0; | 57 | static unsigned long dircache_size = 0; |
58 | static unsigned long entry_count = 0; | ||
58 | static unsigned long reserve_used = 0; | 59 | static unsigned long reserve_used = 0; |
59 | static unsigned int cache_build_ticks = 0; | 60 | static unsigned int cache_build_ticks = 0; |
60 | static char dircache_cur_path[MAX_PATH]; | 61 | static char dircache_cur_path[MAX_PATH]; |
@@ -79,12 +80,22 @@ static struct dircache_entry* allocate_entry(void) | |||
79 | } | 80 | } |
80 | 81 | ||
81 | next_entry = (struct dircache_entry *)((char *)dircache_root+dircache_size); | 82 | next_entry = (struct dircache_entry *)((char *)dircache_root+dircache_size); |
82 | dircache_size += sizeof(struct dircache_entry); | 83 | #ifdef ROCKBOX_STRICT_ALIGN |
84 | /* Make sure the entry is long aligned. */ | ||
85 | if ((long)next_entry & 0x03) | ||
86 | { | ||
87 | next_entry = (struct dircache_entry *)(((long)next_entry & ~0x03) + 0x04); | ||
88 | dircache_size += 4 - ((long)next_entry & 0x03); | ||
89 | } | ||
90 | #endif | ||
83 | next_entry->name_len = 0; | 91 | next_entry->name_len = 0; |
84 | next_entry->d_name = NULL; | 92 | next_entry->d_name = NULL; |
85 | next_entry->up = NULL; | 93 | next_entry->up = NULL; |
86 | next_entry->down = NULL; | 94 | next_entry->down = NULL; |
87 | next_entry->next = NULL; | 95 | next_entry->next = NULL; |
96 | |||
97 | dircache_size += sizeof(struct dircache_entry); | ||
98 | entry_count++; | ||
88 | 99 | ||
89 | return next_entry; | 100 | return next_entry; |
90 | } | 101 | } |
@@ -306,16 +317,17 @@ int dircache_load(const char *path) | |||
306 | if (fd < 0) | 317 | if (fd < 0) |
307 | return -2; | 318 | return -2; |
308 | 319 | ||
320 | dircache_root = (struct dircache_entry *)(((long)audiobuf & ~0x03) + 0x04); | ||
309 | bytes_read = read(fd, &maindata, sizeof(struct dircache_maindata)); | 321 | bytes_read = read(fd, &maindata, sizeof(struct dircache_maindata)); |
310 | if (bytes_read != sizeof(struct dircache_maindata) | 322 | if (bytes_read != sizeof(struct dircache_maindata) |
311 | || (long)maindata.root_entry != (long)audiobuf | 323 | || (long)maindata.root_entry != (long)dircache_root |
312 | || maindata.size <= 0) | 324 | || maindata.size <= 0) |
313 | { | 325 | { |
314 | close(fd); | 326 | close(fd); |
315 | return -3; | 327 | return -3; |
316 | } | 328 | } |
317 | 329 | ||
318 | dircache_root = (struct dircache_entry *)audiobuf; | 330 | entry_count = maindata.entry_count; |
319 | bytes_read = read(fd, dircache_root, MIN(DIRCACHE_LIMIT, maindata.size)); | 331 | bytes_read = read(fd, dircache_root, MIN(DIRCACHE_LIMIT, maindata.size)); |
320 | close(fd); | 332 | close(fd); |
321 | 333 | ||
@@ -359,6 +371,7 @@ int dircache_save(const char *path) | |||
359 | maindata.magic = DIRCACHE_MAGIC; | 371 | maindata.magic = DIRCACHE_MAGIC; |
360 | maindata.size = dircache_size; | 372 | maindata.size = dircache_size; |
361 | maindata.root_entry = dircache_root; | 373 | maindata.root_entry = dircache_root; |
374 | maindata.entry_count = entry_count; | ||
362 | 375 | ||
363 | /* Save the info structure */ | 376 | /* Save the info structure */ |
364 | bytes_written = write(fd, &maindata, sizeof(struct dircache_maindata)); | 377 | bytes_written = write(fd, &maindata, sizeof(struct dircache_maindata)); |
@@ -491,7 +504,7 @@ int dircache_build(int last_size) | |||
491 | } | 504 | } |
492 | else | 505 | else |
493 | { | 506 | { |
494 | dircache_root = (struct dircache_entry *)audiobuf; | 507 | dircache_root = (struct dircache_entry *)(((long)audiobuf & ~0x03) + 0x04); |
495 | dircache_size = 0; | 508 | dircache_size = 0; |
496 | } | 509 | } |
497 | 510 | ||
@@ -541,6 +554,14 @@ bool dircache_is_enabled(void) | |||
541 | } | 554 | } |
542 | 555 | ||
543 | /** | 556 | /** |
557 | * Returns the current number of entries (directories and files) in the cache. | ||
558 | */ | ||
559 | int dircache_get_entry_count(void) | ||
560 | { | ||
561 | return entry_count; | ||
562 | } | ||
563 | |||
564 | /** | ||
544 | * Returns the allocated space for dircache (without reserve space). | 565 | * Returns the allocated space for dircache (without reserve space). |
545 | */ | 566 | */ |
546 | int dircache_get_cache_size(void) | 567 | int dircache_get_cache_size(void) |
@@ -896,7 +917,7 @@ struct dircache_entry* readdir_cached(DIRCACHED* dir) | |||
896 | regentry = readdir(dir->regulardir); | 917 | regentry = readdir(dir->regulardir); |
897 | if (regentry == NULL) | 918 | if (regentry == NULL) |
898 | return NULL; | 919 | return NULL; |
899 | 920 | ||
900 | strncpy(dir->secondary_entry.d_name, regentry->d_name, MAX_PATH-1); | 921 | strncpy(dir->secondary_entry.d_name, regentry->d_name, MAX_PATH-1); |
901 | dir->secondary_entry.size = regentry->size; | 922 | dir->secondary_entry.size = regentry->size; |
902 | dir->secondary_entry.startcluster = regentry->startcluster; | 923 | dir->secondary_entry.startcluster = regentry->startcluster; |
@@ -928,6 +949,7 @@ struct dircache_entry* readdir_cached(DIRCACHED* dir) | |||
928 | dir->secondary_entry.wrttime = ce->wrttime; | 949 | dir->secondary_entry.wrttime = ce->wrttime; |
929 | dir->secondary_entry.wrtdate = ce->wrtdate; | 950 | dir->secondary_entry.wrtdate = ce->wrtdate; |
930 | dir->secondary_entry.next = NULL; | 951 | dir->secondary_entry.next = NULL; |
952 | dir->internal_entry = ce; | ||
931 | 953 | ||
932 | //logf("-> %s", ce->name); | 954 | //logf("-> %s", ce->name); |
933 | return &dir->secondary_entry; | 955 | return &dir->secondary_entry; |