summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTeruaki Kawashima <teru@rockbox.org>2010-11-09 14:35:19 +0000
committerTeruaki Kawashima <teru@rockbox.org>2010-11-09 14:35:19 +0000
commit7d3f8c0921630caaaaa95edd3bd8b8d177780ebf (patch)
treeeed5ac89b6ab16818f588f70802fb2b3c0f4c4cb
parent598f56ecb241fa65f0e13e826add006e9cc55676 (diff)
downloadrockbox-7d3f8c0921630caaaaa95edd3bd8b8d177780ebf.tar.gz
rockbox-7d3f8c0921630caaaaa95edd3bd8b8d177780ebf.zip
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
-rw-r--r--apps/filetypes.c104
1 files 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 @@
46#else 46#else
47#define MAX_FILETYPES 128 47#define MAX_FILETYPES 128
48#endif 48#endif
49/* max viewer plugins */
50#ifdef HAVE_LCD_BITMAP
51#define MAX_VIEWERS 56
52#else
53#define MAX_VIEWERS 24
54#endif
49 55
50/* a table for the know file types */ 56/* a table for the known file types */
51static const struct filetype inbuilt_filetypes[] = { 57static const struct filetype inbuilt_filetypes[] = {
52 { "mp3", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA }, 58 { "mp3", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
53 { "mp2", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA }, 59 { "mp2", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
@@ -134,7 +140,7 @@ static const struct filetype inbuilt_filetypes[] = {
134 { "rsbs", FILE_ATTR_RSBS, Icon_Wps, VOICE_EXT_RSBS }, 140 { "rsbs", FILE_ATTR_RSBS, Icon_Wps, VOICE_EXT_RSBS },
135#if CONFIG_TUNER 141#if CONFIG_TUNER
136 { "rfms", FILE_ATTR_RFMS, Icon_Wps, VOICE_EXT_RFMS }, 142 { "rfms", FILE_ATTR_RFMS, Icon_Wps, VOICE_EXT_RFMS },
137#endif 143#endif
138#endif 144#endif
139#ifdef BOOTFILE_EXT 145#ifdef BOOTFILE_EXT
140 { BOOTFILE_EXT, FILE_ATTR_MOD, Icon_Firmware, VOICE_EXT_AJZ }, 146 { BOOTFILE_EXT, FILE_ATTR_MOD, Icon_Firmware, VOICE_EXT_AJZ },
@@ -150,7 +156,6 @@ void tree_get_filetypes(const struct filetype** types, int* count)
150 *count = sizeof(inbuilt_filetypes) / sizeof(*inbuilt_filetypes); 156 *count = sizeof(inbuilt_filetypes) / sizeof(*inbuilt_filetypes);
151} 157}
152 158
153/* mask for dynamic filetype info in attribute */
154#define ROCK_EXTENSION "rock" 159#define ROCK_EXTENSION "rock"
155 160
156struct file_type { 161struct file_type {
@@ -165,8 +170,11 @@ static bool custom_icons_loaded = false;
165#ifdef HAVE_LCD_COLOR 170#ifdef HAVE_LCD_COLOR
166static int custom_colors[MAX_FILETYPES+1]; 171static int custom_colors[MAX_FILETYPES+1];
167#endif 172#endif
173/* index array to filetypes used in open with list. */
174static int viewers[MAX_VIEWERS];
168static int filetype_count = 0; 175static int filetype_count = 0;
169static unsigned char highest_attr = 0; 176static unsigned char highest_attr = 0;
177static int viewer_count = 0;
170 178
171static char *filetypes_strdup(char* string) 179static char *filetypes_strdup(char* string)
172{ 180{
@@ -174,6 +182,20 @@ static char *filetypes_strdup(char* string)
174 strcpy(buffer, string); 182 strcpy(buffer, string);
175 return buffer; 183 return buffer;
176} 184}
185static char *filetypes_store_plugin(char *plugin, int n)
186{
187 int i;
188 /* if the plugin is in the list already, use it. */
189 for (i=0; i<viewer_count; i++)
190 {
191 if (!strcmp(filetypes[viewers[i]].plugin, plugin))
192 return filetypes[viewers[i]].plugin;
193 }
194 /* otherwise, allocate buffer */
195 if (viewer_count < MAX_VIEWERS)
196 viewers[viewer_count++] = n;
197 return filetypes_strdup(plugin);
198}
177static void read_builtin_types(void); 199static void read_builtin_types(void);
178static void read_config(const char* config_file); 200static void read_config(const char* config_file);
179#ifdef HAVE_LCD_COLOR 201#ifdef HAVE_LCD_COLOR
@@ -279,7 +301,8 @@ void filetype_init(void)
279 filetypes[0].plugin = NULL; 301 filetypes[0].plugin = NULL;
280 filetypes[0].attr = 0; 302 filetypes[0].attr = 0;
281 filetypes[0].icon = Icon_Folder; 303 filetypes[0].icon = Icon_Folder;
282 304
305 viewer_count = 0;
283 filetype_count = 1; 306 filetype_count = 1;
284 read_builtin_types(); 307 read_builtin_types();
285 read_config(get_user_file_path(VIEWERS_CONFIG, IS_FILE, path, sizeof(path))); 308 read_config(get_user_file_path(VIEWERS_CONFIG, IS_FILE, path, sizeof(path)));
@@ -325,14 +348,14 @@ static void read_builtin_types(void)
325static void read_config(const char* config_file) 348static void read_config(const char* config_file)
326{ 349{
327 char line[64], *s, *e; 350 char line[64], *s, *e;
328 char extension[8], plugin[32]; 351 char *extension, *plugin;
329 int fd = open(config_file, O_RDONLY); 352 int fd = open(config_file, O_RDONLY);
330 if (fd < 0) 353 if (fd < 0)
331 return; 354 return;
332 /* config file is in the for 355 /* config file is in the format
333 <extension>,<plugin>,<icon code> 356 <extension>,<plugin>,<icon code>
334 ignore line if either of the first two are missing */ 357 ignore line if either of the first two are missing */
335 while (read_line(fd, line, 64) > 0) 358 while (read_line(fd, line, sizeof line) > 0)
336 { 359 {
337 if (filetype_count >= MAX_FILETYPES) 360 if (filetype_count >= MAX_FILETYPES)
338 { 361 {
@@ -346,30 +369,31 @@ static void read_config(const char* config_file)
346 if (!e) 369 if (!e)
347 continue; 370 continue;
348 *e = '\0'; 371 *e = '\0';
349 strcpy(extension, s); 372 extension = s;
350 373
351 /* get the plugin */ 374 /* get the plugin */
352 s = e+1; 375 s = e+1;
353 e = strchr(s, ','); 376 e = strchr(s, ',');
354 if (!e) 377 if (!e)
355 continue; 378 continue;
356 *e = '\0'; 379 *e = '\0';
357 380 plugin = s;
358 strcpy(plugin, s); 381
359 /* ok, store this plugin/extension, check icon after */ 382 /* ok, store this plugin/extension, check icon after */
360 filetypes[filetype_count].extension = filetypes_strdup(extension); 383 struct file_type *file_type = &filetypes[filetype_count];
361 filetypes[filetype_count].plugin = filetypes_strdup(plugin); 384 file_type->extension = filetypes_strdup(extension);
362 filetypes[filetype_count].attr = highest_attr +1; 385 file_type->plugin = filetypes_store_plugin(plugin, filetype_count);
363 filetypes[filetype_count].icon = Icon_Questionmark; 386 file_type->attr = highest_attr +1;
387 file_type->icon = Icon_Questionmark;
364 highest_attr++; 388 highest_attr++;
365 /* get the icon */ 389 /* get the icon */
366 s = e+1; 390 s = e+1;
367 if (*s == '*') 391 if (*s == '*')
368 filetypes[filetype_count].icon = atoi(s+1); 392 file_type->icon = atoi(s+1);
369 else if (*s == '-') 393 else if (*s == '-')
370 filetypes[filetype_count].icon = Icon_NOICON; 394 file_type->icon = Icon_NOICON;
371 else if (*s >= '0' && *s <= '9') 395 else if (*s >= '0' && *s <= '9')
372 filetypes[filetype_count].icon = Icon_Last_Themeable + atoi(s); 396 file_type->icon = Icon_Last_Themeable + atoi(s);
373 filetype_count++; 397 filetype_count++;
374 } 398 }
375 close(fd); 399 close(fd);
@@ -450,45 +474,40 @@ char* filetype_get_plugin(const struct entry* file)
450 return plugin_name; 474 return plugin_name;
451} 475}
452 476
453bool filetype_supported(int attr) 477bool filetype_supported(int attr)
454{ 478{
455 return find_attr(attr) >= 0; 479 return find_attr(attr) >= 0;
456} 480}
457 481
458/**** Open With Screen ****/ 482/**** Open With Screen ****/
459struct cb_data { 483struct cb_data {
460 int *items;
461 const char *current_file; 484 const char *current_file;
462}; 485};
463 486
464static enum themable_icons openwith_get_icon(int selected_item, void * data) 487static enum themable_icons openwith_get_icon(int selected_item, void * data)
465{ 488{
466 struct cb_data *info = (struct cb_data *)data; 489 (void)data;
467 int *items = info->items; 490 return filetypes[viewers[selected_item]].icon;
468 return filetypes[items[selected_item]].icon;
469} 491}
470 492
471static const char* openwith_get_name(int selected_item, void * data, 493static const char* openwith_get_name(int selected_item, void * data,
472 char * buffer, size_t buffer_len) 494 char * buffer, size_t buffer_len)
473{ 495{
474 (void)buffer; (void)buffer_len; 496 (void)data; (void)buffer; (void)buffer_len;
475 struct cb_data *info = (struct cb_data *)data; 497 const char *s = strrchr(filetypes[viewers[selected_item]].plugin, '/');
476 int *items = info->items;
477 const char *s = strrchr(filetypes[items[selected_item]].plugin, '/');
478 if (s) 498 if (s)
479 return s+1; 499 return s+1;
480 else return filetypes[items[selected_item]].plugin; 500 else return filetypes[viewers[selected_item]].plugin;
481} 501}
482 502
483static int openwith_action_callback(int action, struct gui_synclist *lists) 503static int openwith_action_callback(int action, struct gui_synclist *lists)
484{ 504{
485 struct cb_data *info = (struct cb_data *)lists->data; 505 struct cb_data *info = (struct cb_data *)lists->data;
486 int *items = info->items;
487 int i; 506 int i;
488 if (action == ACTION_STD_OK) 507 if (action == ACTION_STD_OK)
489 { 508 {
490 char plugin[MAX_PATH]; 509 char plugin[MAX_PATH];
491 i = items[gui_synclist_get_sel_pos(lists)]; 510 i = viewers[gui_synclist_get_sel_pos(lists)];
492 snprintf(plugin, MAX_PATH, "%s/%s.%s", 511 snprintf(plugin, MAX_PATH, "%s/%s.%s",
493 PLUGIN_DIR, filetypes[i].plugin, ROCK_EXTENSION); 512 PLUGIN_DIR, filetypes[i].plugin, ROCK_EXTENSION);
494 plugin_load(plugin, info->current_file); 513 plugin_load(plugin, info->current_file);
@@ -499,34 +518,17 @@ static int openwith_action_callback(int action, struct gui_synclist *lists)
499 518
500int filetype_list_viewers(const char* current_file) 519int filetype_list_viewers(const char* current_file)
501{ 520{
502 int i, count = 0;
503 int items[MAX_FILETYPES];
504 struct simplelist_info info; 521 struct simplelist_info info;
505 struct cb_data data = { items, current_file }; 522 struct cb_data data = { current_file };
506 for (i=0; i<filetype_count && count < MAX_FILETYPES; i++)
507 {
508 if (filetypes[i].plugin)
509 {
510 int j;
511 for (j=0;j<count;j++) /* check if the plugin is in the list yet */
512 {
513 if (!strcmp(filetypes[i].plugin,filetypes[items[j]].plugin))
514 break;
515 }
516 if (j<count)
517 continue; /* it is so grab the next plugin */
518 items[count++] = i;
519 }
520 }
521#ifndef HAVE_LCD_BITMAP 523#ifndef HAVE_LCD_BITMAP
522 if (count == 0) 524 if (viewer_count == 0)
523 { 525 {
524 /* FIX: translation! */ 526 /* FIX: translation! */
525 splash(HZ*2, "No viewers found"); 527 splash(HZ*2, "No viewers found");
526 return PLUGIN_OK; 528 return PLUGIN_OK;
527 } 529 }
528#endif 530#endif
529 simplelist_info_init(&info, str(LANG_ONPLAY_OPEN_WITH), count, &data); 531 simplelist_info_init(&info, str(LANG_ONPLAY_OPEN_WITH), viewer_count, &data);
530 info.action_callback = openwith_action_callback; 532 info.action_callback = openwith_action_callback;
531 info.get_name = openwith_get_name; 533 info.get_name = openwith_get_name;
532 info.get_icon = global_settings.show_icons?openwith_get_icon:NULL; 534 info.get_icon = global_settings.show_icons?openwith_get_icon:NULL;
@@ -538,7 +540,7 @@ int filetype_load_plugin(const char* plugin, char* file)
538 int i; 540 int i;
539 char plugin_name[MAX_PATH]; 541 char plugin_name[MAX_PATH];
540 char *s; 542 char *s;
541 543
542 for (i=0;i<filetype_count;i++) 544 for (i=0;i<filetype_count;i++)
543 { 545 {
544 if (filetypes[i].plugin) 546 if (filetypes[i].plugin)