From 7d3f8c0921630caaaaa95edd3bd8b8d177780ebf Mon Sep 17 00:00:00 2001 From: Teruaki Kawashima Date: Tue, 9 Nov 2010 14:35:19 +0000 Subject: Create index array to filetypes used in the open with list while loading viewers.config. Reduced stack usage of filetype_list_viewers(). Additionally, do not allocate buffer twice for same plugin name. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@28538 a1c6a512-1295-4272-9138-f99709370657 --- apps/filetypes.c | 104 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 53 insertions(+), 51 deletions(-) diff --git a/apps/filetypes.c b/apps/filetypes.c index 28a2da65bb..cd4f4e79b7 100644 --- a/apps/filetypes.c +++ b/apps/filetypes.c @@ -46,8 +46,14 @@ #else #define MAX_FILETYPES 128 #endif +/* max viewer plugins */ +#ifdef HAVE_LCD_BITMAP +#define MAX_VIEWERS 56 +#else +#define MAX_VIEWERS 24 +#endif -/* a table for the know file types */ +/* a table for the known file types */ static const struct filetype inbuilt_filetypes[] = { { "mp3", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA }, { "mp2", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA }, @@ -134,7 +140,7 @@ static const struct filetype inbuilt_filetypes[] = { { "rsbs", FILE_ATTR_RSBS, Icon_Wps, VOICE_EXT_RSBS }, #if CONFIG_TUNER { "rfms", FILE_ATTR_RFMS, Icon_Wps, VOICE_EXT_RFMS }, -#endif +#endif #endif #ifdef BOOTFILE_EXT { BOOTFILE_EXT, FILE_ATTR_MOD, Icon_Firmware, VOICE_EXT_AJZ }, @@ -150,7 +156,6 @@ void tree_get_filetypes(const struct filetype** types, int* count) *count = sizeof(inbuilt_filetypes) / sizeof(*inbuilt_filetypes); } -/* mask for dynamic filetype info in attribute */ #define ROCK_EXTENSION "rock" struct file_type { @@ -165,8 +170,11 @@ static bool custom_icons_loaded = false; #ifdef HAVE_LCD_COLOR static int custom_colors[MAX_FILETYPES+1]; #endif +/* index array to filetypes used in open with list. */ +static int viewers[MAX_VIEWERS]; static int filetype_count = 0; static unsigned char highest_attr = 0; +static int viewer_count = 0; static char *filetypes_strdup(char* string) { @@ -174,6 +182,20 @@ static char *filetypes_strdup(char* string) strcpy(buffer, string); return buffer; } +static char *filetypes_store_plugin(char *plugin, int n) +{ + int i; + /* if the plugin is in the list already, use it. */ + for (i=0; i,, ignore line if either of the first two are missing */ - while (read_line(fd, line, 64) > 0) + while (read_line(fd, line, sizeof line) > 0) { if (filetype_count >= MAX_FILETYPES) { @@ -346,30 +369,31 @@ static void read_config(const char* config_file) if (!e) continue; *e = '\0'; - strcpy(extension, s); - + extension = s; + /* get the plugin */ s = e+1; e = strchr(s, ','); if (!e) continue; *e = '\0'; - - strcpy(plugin, s); + plugin = s; + /* ok, store this plugin/extension, check icon after */ - filetypes[filetype_count].extension = filetypes_strdup(extension); - filetypes[filetype_count].plugin = filetypes_strdup(plugin); - filetypes[filetype_count].attr = highest_attr +1; - filetypes[filetype_count].icon = Icon_Questionmark; + struct file_type *file_type = &filetypes[filetype_count]; + file_type->extension = filetypes_strdup(extension); + file_type->plugin = filetypes_store_plugin(plugin, filetype_count); + file_type->attr = highest_attr +1; + file_type->icon = Icon_Questionmark; highest_attr++; /* get the icon */ s = e+1; if (*s == '*') - filetypes[filetype_count].icon = atoi(s+1); + file_type->icon = atoi(s+1); else if (*s == '-') - filetypes[filetype_count].icon = Icon_NOICON; + file_type->icon = Icon_NOICON; else if (*s >= '0' && *s <= '9') - filetypes[filetype_count].icon = Icon_Last_Themeable + atoi(s); + file_type->icon = Icon_Last_Themeable + atoi(s); filetype_count++; } close(fd); @@ -450,45 +474,40 @@ char* filetype_get_plugin(const struct entry* file) return plugin_name; } -bool filetype_supported(int attr) +bool filetype_supported(int attr) { return find_attr(attr) >= 0; } /**** Open With Screen ****/ struct cb_data { - int *items; const char *current_file; }; static enum themable_icons openwith_get_icon(int selected_item, void * data) { - struct cb_data *info = (struct cb_data *)data; - int *items = info->items; - return filetypes[items[selected_item]].icon; + (void)data; + return filetypes[viewers[selected_item]].icon; } static const char* openwith_get_name(int selected_item, void * data, char * buffer, size_t buffer_len) { - (void)buffer; (void)buffer_len; - struct cb_data *info = (struct cb_data *)data; - int *items = info->items; - const char *s = strrchr(filetypes[items[selected_item]].plugin, '/'); + (void)data; (void)buffer; (void)buffer_len; + const char *s = strrchr(filetypes[viewers[selected_item]].plugin, '/'); if (s) return s+1; - else return filetypes[items[selected_item]].plugin; + else return filetypes[viewers[selected_item]].plugin; } static int openwith_action_callback(int action, struct gui_synclist *lists) { struct cb_data *info = (struct cb_data *)lists->data; - int *items = info->items; int i; if (action == ACTION_STD_OK) { char plugin[MAX_PATH]; - i = items[gui_synclist_get_sel_pos(lists)]; + i = viewers[gui_synclist_get_sel_pos(lists)]; snprintf(plugin, MAX_PATH, "%s/%s.%s", PLUGIN_DIR, filetypes[i].plugin, ROCK_EXTENSION); plugin_load(plugin, info->current_file); @@ -499,34 +518,17 @@ static int openwith_action_callback(int action, struct gui_synclist *lists) int filetype_list_viewers(const char* current_file) { - int i, count = 0; - int items[MAX_FILETYPES]; struct simplelist_info info; - struct cb_data data = { items, current_file }; - for (i=0; i