From 1459bbc45f728c610daba7c4b51d9494cb34760a Mon Sep 17 00:00:00 2001 From: Amaury Pouly Date: Mon, 1 Feb 2010 23:00:35 +0000 Subject: Various dircache improvements: reduce size of a path buffer to MAX_PATH and rewrote copy_path to improve stack usage. Also simplified get_entry. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@24445 a1c6a512-1295-4272-9138-f99709370657 --- firmware/common/dircache.c | 64 +++++++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/firmware/common/dircache.c b/firmware/common/dircache.c index 7ff497790e..66189c48a8 100644 --- a/firmware/common/dircache.c +++ b/firmware/common/dircache.c @@ -71,7 +71,7 @@ static unsigned long entry_count = 0; static unsigned long reserve_used = 0; static unsigned int cache_build_ticks = 0; static unsigned long appflags = 0; -static char dircache_cur_path[MAX_PATH*2]; +static char dircache_cur_path[MAX_PATH]; static struct event_queue dircache_queue; static long dircache_stack[(DEFAULT_STACK_SIZE + 0x900)/sizeof(long)]; @@ -393,7 +393,8 @@ static int dircache_travel(IF_MV2(int volume,) struct fat_dir *dir, struct dirca * path: Absolute path to a file or directory (see comment) * go_down: Returns the first entry of the directory given by the path (see comment) * - * As a a special case to handle buggy code, accept path="" as an alias for "/" + * As a a special case, accept path="" as an alias for "/". + * Also if the path omits the first '/', it will be accepted. * * * If get_down=true: * If path="/", the returned entry is the first of root directory (ie dircache_root) @@ -420,16 +421,7 @@ static struct dircache_entry* dircache_get_entry(const char *path, bool go_down) bool at_root = true; struct dircache_entry *cache_entry = dircache_root; - /* check that the path is absolute (accept empty path also) */ - if(path[0] != '/' && path[0] != 0) - return NULL; - - /* make a copy of the path because strok_r modifies the path */ - /* also handle the weird "" alias for "/" */ - if(path[0] != 0) - strlcpy(namecopy, path, sizeof(namecopy)); - else - strlcpy(namecopy, "/", sizeof(namecopy)); + strlcpy(namecopy, path, sizeof(namecopy)); for(part = strtok_r(namecopy, "/", &end); part; part = strtok_r(NULL, "/", &end)) { @@ -913,31 +905,39 @@ const struct dircache_entry *dircache_get_entry_ptr(const char *filename) */ void dircache_copy_path(const struct dircache_entry *entry, char *buf, int size) { - const struct dircache_entry *down[MAX_SCAN_DEPTH]; - int depth = 0; + int path_size = 0; + int idx; + const struct dircache_entry *temp = entry; if (size <= 0) return ; + + /* first compute the necessary size */ + while(temp != NULL) + { + path_size += temp->name_len; /* '/' + d_name */ + temp = temp->up; + } - buf[0] = '\0'; - - if (entry == NULL) - return ; - - do { - down[depth] = entry; - entry = entry->up; - depth++; - } while (entry != NULL && depth < MAX_SCAN_DEPTH); - - while (--depth >= 0) + /* now copy the path */ + /* doesn't matter with trailing 0 because it's added later */ + idx = path_size; + while(entry != NULL) { - snprintf(buf, size, "/%s", down[depth]->d_name); - buf += down[depth]->name_len; /* '/' + d_name */ - size -= down[depth]->name_len; - if (size <= 0) - break ; + idx -= entry->name_len; + /* available size */ + int rem = size - idx; + + if(rem >= 1) + { + buf[idx] = '/'; + memcpy(buf + idx + 1, entry->d_name, MIN((size_t)(rem - 1), (size_t)(entry->name_len - 1))); + } + entry = entry->up; } + + /* add trailing 0 */ + buf[MIN(path_size, size-1)] = 0; } /* --- Directory cache live updating functions --- */ @@ -1060,7 +1060,7 @@ void dircache_update_filesize(int fd, long newsize, long startcluster) if (fd_bindings[fd] == NULL) { - logf("dircache fd access error"); + logf("dircache fd(%d) access error", fd); dircache_initialized = false; return ; } -- cgit v1.2.3