summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/playlist.c19
-rw-r--r--apps/playlist.h2
-rw-r--r--apps/tagcache.c57
-rw-r--r--firmware/common/dircache.c73
-rw-r--r--firmware/common/file.c13
-rw-r--r--firmware/common/filefuncs.c2
-rw-r--r--firmware/include/dircache.h26
-rw-r--r--uisimulator/common/io.c7
8 files changed, 104 insertions, 95 deletions
diff --git a/apps/playlist.c b/apps/playlist.c
index dcf2fe1..ea183d7 100644
--- a/apps/playlist.c
+++ b/apps/playlist.c
@@ -575,7 +575,7 @@ static int add_indices_to_playlist(struct playlist_info* playlist,
playlist->indices[ playlist->amount ] = i+count;
#ifdef HAVE_DIRCACHE
if (playlist->filenames)
- playlist->filenames[ playlist->amount ] = NULL;
+ playlist->filenames[ playlist->amount ] = -1;
#endif
playlist->amount++;
}
@@ -816,7 +816,7 @@ static int add_track_to_playlist(struct playlist_info* playlist,
#ifdef HAVE_DIRCACHE
if (playlist->filenames)
- playlist->filenames[insert_position] = NULL;
+ playlist->filenames[insert_position] = -1;
#endif
playlist->amount++;
@@ -958,9 +958,9 @@ static int randomise_playlist(struct playlist_info* playlist,
#ifdef HAVE_DIRCACHE
if (playlist->filenames)
{
- store = (long)playlist->filenames[candidate];
+ store = playlist->filenames[candidate];
playlist->filenames[candidate] = playlist->filenames[count];
- playlist->filenames[count] = (struct dircache_entry *)store;
+ playlist->filenames[count] = store;
}
#endif
}
@@ -1298,7 +1298,7 @@ static void playlist_thread(void)
&& queue_empty(&playlist_queue); index++)
{
/* Process only pointers that are not already loaded. */
- if (playlist->filenames[index])
+ if (playlist->filenames[index] >= 0)
continue ;
control_file = playlist->indices[index] & PLAYLIST_INSERT_TYPE_MASK;
@@ -1310,7 +1310,7 @@ static void playlist_thread(void)
break ;
/* Set the dircache entry pointer. */
- playlist->filenames[index] = dircache_get_entry_ptr(tmp);
+ playlist->filenames[index] = dircache_get_entry_id(tmp);
/* And be on background so user doesn't notice any delays. */
yield();
@@ -1351,7 +1351,7 @@ static int get_filename(struct playlist_info* playlist, int index, int seek,
#ifdef HAVE_DIRCACHE
if (dircache_is_enabled() && playlist->filenames)
{
- if (playlist->filenames[index] != NULL)
+ if (playlist->filenames[index] >= 0)
{
max = dircache_copy_path(playlist->filenames[index],
tmp_buf, sizeof(tmp_buf)-1);
@@ -2389,7 +2389,7 @@ int playlist_add(const char *filename)
playlist->indices[playlist->amount] = playlist->buffer_end_pos;
#ifdef HAVE_DIRCACHE
- playlist->filenames[playlist->amount] = NULL;
+ playlist->filenames[playlist->amount] = -1;
#endif
playlist->amount++;
@@ -2713,8 +2713,7 @@ int playlist_create_ex(struct playlist_info* playlist,
playlist->max_playlist_size = num_indices;
playlist->indices = index_buffer;
#ifdef HAVE_DIRCACHE
- playlist->filenames = (const struct dircache_entry **)
- &playlist->indices[num_indices];
+ playlist->filenames = (int*)&playlist->indices[num_indices];
#endif
playlist->buffer_size = 0;
diff --git a/apps/playlist.h b/apps/playlist.h
index 9c45769..d994f6e 100644
--- a/apps/playlist.h
+++ b/apps/playlist.h
@@ -81,7 +81,7 @@ struct playlist_info
bool control_created; /* has control file been created? */
int dirlen; /* Length of the path to the playlist file */
unsigned long *indices; /* array of indices */
- const struct dircache_entry **filenames; /* Entries from dircache */
+ int *filenames; /* Array of dircache indices */
int max_playlist_size; /* Max number of files in playlist. Mirror of
global_settings.max_files_in_playlist */
bool in_ram; /* playlist stored in ram (dirplay) */
diff --git a/apps/tagcache.c b/apps/tagcache.c
index 080f419..c5a8dcb 100644
--- a/apps/tagcache.c
+++ b/apps/tagcache.c
@@ -383,8 +383,9 @@ static bool do_timed_yield(void)
#endif
#if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE)
-static long find_entry_ram(const char *filename,
- const struct dircache_entry *dc)
+/* find the ramcache entry corresponding to the file indicated by
+ * filename and dc (it's corresponding dircache id). */
+static long find_entry_ram(const char *filename, int dc)
{
static long last_pos = 0;
int i;
@@ -393,10 +394,10 @@ static long find_entry_ram(const char *filename,
if (!tc_stat.ramcache)
return -1;
- if (dc == NULL)
- dc = dircache_get_entry_ptr(filename);
+ if (dc < 0)
+ dc = dircache_get_entry_id(filename);
- if (dc == NULL)
+ if (dc < 0)
{
logf("tagcache: file not found.");
return -1;
@@ -411,7 +412,7 @@ static long find_entry_ram(const char *filename,
for (; i < current_tcmh.tch.entry_count; i++)
{
- if (hdr->indices[i].tag_seek[tag_filename] == (long)dc)
+ if (hdr->indices[i].tag_seek[tag_filename] == dc)
{
last_pos = MAX(0, i - 3);
return i;
@@ -539,7 +540,7 @@ static int find_index(const char *filename)
#if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE)
if (tc_stat.ramcache && is_dircache_intact())
- idx_id = find_entry_ram(filename, NULL);
+ idx_id = find_entry_ram(filename, -1);
#endif
if (idx_id < 0)
@@ -723,8 +724,8 @@ static bool retrieve(struct tagcache_search *tcs, struct index_entry *idx,
if (tag == tag_filename && (idx->flag & FLAG_DIRCACHE)
&& is_dircache_intact())
{
- dircache_copy_path((struct dircache_entry *)seek,
- buf, size);
+ /* for tag_filename, seek is a dircache index */
+ dircache_copy_path(seek, buf, size);
return true;
}
else
@@ -1481,8 +1482,7 @@ static bool get_next(struct tagcache_search *tcs)
if (tcs->type == tag_filename && (flag & FLAG_DIRCACHE)
&& is_dircache_intact())
{
- size_t len = dircache_copy_path((struct dircache_entry *)tcs->position,
- buf, sizeof buf);
+ size_t len = dircache_copy_path(tcs->position, buf, sizeof buf);
tcs->result_len = len + 1;
tcs->result = buf;
tcs->ramresult = false;
@@ -1599,29 +1599,6 @@ static bool update_master_header(void)
return true;
}
-#if 0
-
-void tagcache_modify(struct tagcache_search *tcs, int type, const char *text)
-{
- struct tagentry *entry;
-
- if (tcs->type != tag_title)
- return ;
-
- /* We will need reserve buffer for this. */
- if (tcs->ramcache)
- {
- struct tagfile_entry *ep;
-
- ep = (struct tagfile_entry *)&hdr->tags[tcs->type][tcs->result_seek];
- tcs->seek_list[tcs->seek_list_count];
- }
-
- entry = find_entry_ram();
-
-}
-#endif
-
void tagcache_search_finish(struct tagcache_search *tcs)
{
int i;
@@ -1677,7 +1654,7 @@ bool tagcache_fill_tags(struct mp3entry *id3, const char *filename)
return false;
/* Find the corresponding entry in tagcache. */
- idx_id = find_entry_ram(filename, NULL);
+ idx_id = find_entry_ram(filename, -1);
if (idx_id < 0)
return false;
@@ -1761,7 +1738,7 @@ static int check_if_empty(char **tag)
static void __attribute__ ((noinline)) add_tagcache(char *path,
unsigned long mtime
#if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE)
- ,const struct dircache_entry *dc
+ ,int dc
#endif
)
{
@@ -4017,7 +3994,7 @@ static bool load_tagcache(void)
if (tag == tag_filename)
{
# ifdef HAVE_DIRCACHE
- const struct dircache_entry *dc;
+ int dc;
# endif
// FIXME: This is wrong!
@@ -4064,8 +4041,8 @@ static bool load_tagcache(void)
# ifdef HAVE_DIRCACHE
if (dircache_is_enabled())
{
- dc = dircache_get_entry_ptr(buf);
- if (dc == NULL)
+ dc = dircache_get_entry_id(buf);
+ if (dc < 0)
{
logf("Entry no longer valid.");
logf("-> %s", buf);
@@ -4075,7 +4052,7 @@ static bool load_tagcache(void)
}
idx->flag |= FLAG_DIRCACHE;
- idx->tag_seek[tag_filename] = (long)dc;
+ idx->tag_seek[tag_filename] = dc;
}
else
# endif
diff --git a/firmware/common/dircache.c b/firmware/common/dircache.c
index 0f3c453..bff9c2f 100644
--- a/firmware/common/dircache.c
+++ b/firmware/common/dircache.c
@@ -57,7 +57,23 @@
#else
#define MAX_OPEN_DIRS 8
#endif
-static DIR_CACHED opendirs[MAX_OPEN_DIRS];
+
+#define MAX_PENDING_BINDINGS 2
+struct fdbind_queue {
+ char path[MAX_PATH];
+ int fd;
+};
+
+/* Exported structures. */
+struct dircache_entry {
+ struct dirinfo info;
+ struct dircache_entry *next;
+ struct dircache_entry *up;
+ struct dircache_entry *down;
+ long startcluster;
+ char *d_name;
+};
+
/* Cache Layout:
*
* x - array of struct dircache_entry
@@ -75,7 +91,6 @@ static DIR_CACHED opendirs[MAX_OPEN_DIRS];
* total allocation size grows
* |xxxxxxxx|rrrrrrrrr|dddddddd|
*/
-static struct dircache_entry *fd_bindings[MAX_OPEN_FILES];
/* this points to the beginnging of the buffer and the first entry */
static struct dircache_entry *dircache_root;
/* these point to the start and end of the name buffer (d above) */
@@ -86,6 +101,9 @@ static char *dot, *dotdot;
static struct dircache_entry *append_position;
#endif
+static DIR_CACHED opendirs[MAX_OPEN_DIRS];
+static struct dircache_entry *fd_bindings[MAX_OPEN_FILES];
+
static bool dircache_initialized = false;
static bool dircache_initializing = false;
static bool thread_enabled = false;
@@ -105,6 +123,11 @@ static int fdbind_idx = 0;
/* --- Internal cache structure control functions --- */
+static inline struct dircache_entry* get_entry(int id)
+{
+ return &dircache_root[id];
+}
+
#ifdef HAVE_EEPROM_SETTINGS
/**
* Open the dircache file to save a snapshot on disk
@@ -1012,14 +1035,36 @@ void dircache_disable(void)
}
/**
- * Usermode function to return dircache_entry pointer to the given path.
+ * Usermode function to return dircache_entry index to the given path.
*/
-const struct dircache_entry *dircache_get_entry_ptr(const char *filename)
+static int dircache_get_entry_id_ex(const char *filename, bool go_down)
{
if (!dircache_initialized || filename == NULL)
- return NULL;
+ return -1;
- return dircache_get_entry(filename, false);
+ struct dircache_entry* res = dircache_get_entry(filename, go_down);
+ return res ? res - dircache_root : -1;
+}
+
+int dircache_get_entry_id(const char* filename)
+{
+ return dircache_get_entry_id_ex(filename, false);
+}
+
+/**
+ * Internal: Get the startcluster for the index
+ */
+long _dircache_get_entry_startcluster(int id)
+{
+ return get_entry(id)->startcluster;
+}
+
+/**
+ * Internal: Get the struct dirinfo for the index
+ */
+struct dirinfo* _dircache_get_entry_dirinfo(int id)
+{
+ return &get_entry(id)->info;
}
/*
@@ -1050,13 +1095,13 @@ static size_t copy_path_helper(const struct dircache_entry *entry, char *buf, si
*
* Returns the size of the resulting string, or 0 if an error occured
*/
-size_t dircache_copy_path(const struct dircache_entry *entry, char *buf, size_t size)
+size_t dircache_copy_path(int index, char *buf, size_t size)
{
- if (!size || !buf)
+ if (!size || !buf || index < 0)
return 0;
buf[0] = '/';
- size_t res = copy_path_helper(entry, buf, size);
+ size_t res = copy_path_helper(&dircache_root[index], buf, size);
/* fixup trailing '/' */
buf[res] = '\0';
return res;
@@ -1373,17 +1418,17 @@ DIR_CACHED* opendir_cached(const char* name)
if (!dircache_initialized || is_disable_msg_pending())
{
- pdir->internal_entry = NULL;
+ pdir->internal_entry = -1;
pdir->regulardir = opendir_uncached(name);
}
else
{
pdir->regulardir = NULL;
- pdir->internal_entry = dircache_get_entry(name, true);
+ pdir->internal_entry = dircache_get_entry_id_ex(name, true);
pdir->theent.info.attribute = -1; /* used to make readdir_cached aware of the first call */
}
- if (pdir->internal_entry == NULL && pdir->regulardir == NULL)
+ if (pdir->internal_entry == -1 && pdir->regulardir == NULL)
{
pdir->busy = false;
return NULL;
@@ -1394,7 +1439,7 @@ DIR_CACHED* opendir_cached(const char* name)
struct dirent_cached* readdir_cached(DIR_CACHED* dir)
{
- struct dircache_entry *ce = dir->internal_entry;
+ struct dircache_entry *ce = get_entry(dir->internal_entry);
struct dirent_uncached *regentry;
if (!dir->busy)
@@ -1430,7 +1475,7 @@ struct dirent_cached* readdir_cached(DIR_CACHED* dir)
because that modifies the d_name pointer. */
dir->theent.startcluster = ce->startcluster;
dir->theent.info = ce->info;
- dir->internal_entry = ce;
+ dir->internal_entry = ce - dircache_root;
//logf("-> %s", ce->d_name);
return &dir->theent;
diff --git a/firmware/common/file.c b/firmware/common/file.c
index 8f6bfa0..cfebd06 100644
--- a/firmware/common/file.c
+++ b/firmware/common/file.c
@@ -108,25 +108,26 @@ static int open_internal(const char* pathname, int flags, bool use_cache)
#ifdef HAVE_DIRCACHE
if (dircache_is_enabled() && !file->write && use_cache)
{
- const struct dircache_entry *ce;
# ifdef HAVE_MULTIVOLUME
int volume = strip_volume(pathname, pathnamecopy);
# endif
- ce = dircache_get_entry_ptr(pathname);
- if (!ce)
+ int ce = dircache_get_entry_id(pathname);
+ if (ce < 0)
{
errno = ENOENT;
file->busy = false;
return -7;
}
+ long startcluster = _dircache_get_entry_startcluster(ce);
fat_open(IF_MV2(volume,)
- ce->startcluster,
+ startcluster,
&(file->fatfile),
NULL);
- file->size = ce->info.size;
- file->attr = ce->info.attribute;
+ struct dirinfo *info = _dircache_get_entry_dirinfo(ce);
+ file->size = info->size;
+ file->attr = info->attribute;
file->cacheoffset = -1;
file->fileoffset = 0;
diff --git a/firmware/common/filefuncs.c b/firmware/common/filefuncs.c
index 6eb2baf..fd33f3c 100644
--- a/firmware/common/filefuncs.c
+++ b/firmware/common/filefuncs.c
@@ -70,7 +70,7 @@ bool file_exists(const char *file)
#ifdef HAVE_DIRCACHE
if (dircache_is_enabled())
- return (dircache_get_entry_ptr(file) != NULL);
+ return (dircache_get_entry_id(file) >= 0);
#endif
fd = open(file, O_RDONLY);
diff --git a/firmware/include/dircache.h b/firmware/include/dircache.h
index 908165c..585bb10 100644
--- a/firmware/include/dircache.h
+++ b/firmware/include/dircache.h
@@ -47,22 +47,6 @@ struct travel_data {
int pathpos;
};
-#define MAX_PENDING_BINDINGS 2
-struct fdbind_queue {
- char path[MAX_PATH];
- int fd;
-};
-
-/* Exported structures. */
-struct dircache_entry {
- struct dirinfo info;
- struct dircache_entry *next;
- struct dircache_entry *up;
- struct dircache_entry *down;
- long startcluster;
- char *d_name;
-};
-
struct dirent_cached {
struct dirinfo info;
char *d_name;
@@ -72,7 +56,7 @@ struct dirent_cached {
typedef struct {
bool busy;
struct dirent_cached theent; /* .attribute is set to -1 on init(opendir) */
- struct dircache_entry *internal_entry; /* the current entry in the directory */
+ int internal_entry; /* the current entry in the directory */
DIR_UNCACHED *regulardir;
} DIR_CACHED;
@@ -90,8 +74,12 @@ int dircache_get_cache_size(void);
int dircache_get_reserve_used(void);
int dircache_get_build_ticks(void);
void dircache_disable(void);
-const struct dircache_entry *dircache_get_entry_ptr(const char *filename);
-size_t dircache_copy_path(const struct dircache_entry *entry, char *buf, size_t size);
+int dircache_get_entry_id(const char *filename);
+size_t dircache_copy_path(int index, char *buf, size_t size);
+
+/* the next two are internal for file.c */
+long _dircache_get_entry_startcluster(int id);
+struct dirinfo* _dircache_get_entry_dirinfo(int id);
void dircache_bind(int fd, const char *path);
void dircache_update_filesize(int fd, long newsize, long startcluster);
diff --git a/uisimulator/common/io.c b/uisimulator/common/io.c
index d094fee..71da4fc 100644
--- a/uisimulator/common/io.c
+++ b/uisimulator/common/io.c
@@ -148,8 +148,7 @@ extern int _wrmdir(const wchar_t*);
#ifdef HAVE_DIRCACHE
-struct dircache_entry;
-const struct dircache_entry *dircache_get_entry_ptr(const char *filename);
+int dircache_get_entry_id(const char *filename);
void dircache_add_file(const char *name, long startcluster);
void dircache_remove(const char *name);
void dircache_rename(const char *oldname, const char *newname);
@@ -409,7 +408,7 @@ int sim_open(const char *name, int o, ...)
mode_t mode = va_arg(ap, unsigned int);
ret = OPEN(get_sim_pathname(name), opts, mode);
#ifdef HAVE_DIRCACHE
- if (ret >= 0 && !dircache_get_entry_ptr(name))
+ if (ret >= 0 && (dircache_get_entry_id(name) < 0))
dircache_add_file(name, 0);
#endif
va_end(ap);
@@ -436,7 +435,7 @@ int sim_creat(const char *name, mode_t mode)
int ret = OPEN(get_sim_pathname(name),
O_BINARY | O_WRONLY | O_CREAT | O_TRUNC, mode);
#ifdef HAVE_DIRCACHE
- if (ret >= 0 && !dircache_get_entry_ptr(name))
+ if (ret >= 0 && (dircache_get_entry_id(name) < 0))
dircache_add_file(name, 0);
#endif
return ret;