Considerable speedups in mime type resolving

This commit is contained in:
Vedran Ljubovic 2006-09-02 12:54:42 +00:00
parent 211dc2d94a
commit 66d358a034
4 changed files with 66 additions and 33 deletions

View File

@ -17,7 +17,6 @@
#include "Run.h" #include "Run.h"
#include "Config.h" #include "Config.h"
#include "Util.h" #include "Util.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -170,9 +169,15 @@ void MimeType::set_found(char *id) {
} }
void MimeType::set(const char* filename, bool usefind) {
MimeType::MimeType(const char* filename, bool usefind) { // Drop any previous data from memory
if (cur_id) free(cur_id);
if (cur_typestr) free(cur_typestr);
if (cur_command) free(cur_command);
if (cur_iconname) free(cur_iconname);
if (cur_filename) free(cur_filename);
cur_id=cur_typestr=cur_command=cur_iconname=cur_filename=0; cur_id=cur_typestr=cur_command=cur_iconname=cur_filename=0;
if (filename && filename_exist(filename)) { if (filename && filename_exist(filename)) {
cur_filename=strdup(filename); cur_filename=strdup(filename);
@ -222,21 +227,10 @@ MimeType::MimeType(const char* filename, bool usefind) {
if (!usefind) goto nofind; // using goto here makes less indentation ;) if (!usefind) goto nofind; // using goto here makes less indentation ;)
// execute file command // execute file command through libmagic
// TODO: save cookie in a static variable buffer = strdup(magic_file(magic_cookie, filename));
magic_t cookie = magic_open(MAGIC_NONE);
magic_load(cookie, NULL);
buffer = strdup(magic_file(cookie, filename));
/* const int ourpid = getpid();
run_program(tsprintf("%s -bLnNp '%s' >/tmp/ede-%d", GFILE, filename, ourpid));
// read cmd output from temp file fprintf (stderr,"(%s) File said: %s (Error: %s)\n",filename,buffer,magic_error(magic_cookie));
FILE *f = fopen (tsprintf("/tmp/ede-%d",ourpid),"r");
fgets(buffer,255,f);
fclose(f); // won't be more than 255 chars*/
fprintf (stderr,"(%s) File said: %s (Error: %s)\n",filename,buffer,magic_error(cookie));
magic_close(cookie);
// find matches for 'file' command output // find matches for 'file' command output
// TODO: add wildcard matching // TODO: add wildcard matching
@ -349,6 +343,21 @@ fprintf(stderr, "Foundext: %d\n", foundext);
cur_typestr = strdup("Unknown"); cur_typestr = strdup("Unknown");
cur_iconname = strdup(DEFAULT_ICON); cur_iconname = strdup(DEFAULT_ICON);
} }
}
MimeType::MimeType(const char* filename, bool usefind) {
cur_id=cur_typestr=cur_command=cur_iconname=cur_filename=0;
// Load mime settings file
if (!mime_first) get_mimedata();
// Have libmagic read its configuration data
magic_cookie = magic_open(MAGIC_NONE);
magic_load(magic_cookie, NULL);
if (filename) set(filename,usefind);
} }
@ -358,5 +367,11 @@ MimeType::~MimeType() {
if (cur_command) free(cur_command); if (cur_command) free(cur_command);
if (cur_iconname) free(cur_iconname); if (cur_iconname) free(cur_iconname);
if (cur_filename) free(cur_filename); if (cur_filename) free(cur_filename);
// free_mimedata() - should we? mimedata is static for a reason...
// Free memory used by mimetype configuration
free_mimedata(); //- should we? mimedata is static for a reason...
// Free memory used by libmagic
magic_close(magic_cookie);
} }

View File

@ -26,6 +26,10 @@ Also this class suggests the command to be used for opening.
#ifndef _edelib_MimeType_h_ #ifndef _edelib_MimeType_h_
#define _edelib_MimeType_h_ #define _edelib_MimeType_h_
// TODO: have configure script detect libmagic and don't use
// it if its not present
#include <magic.h>
#include "Icon.h" #include "Icon.h"
namespace edelib { namespace edelib {
@ -37,13 +41,19 @@ public:
/*! Constructor takes filename and all interesting data is /*! Constructor takes filename and all interesting data is
returned with methods listed below. filename must contain returned with methods listed below. filename must contain
full path. Set usefind to false to avoid using GNU/find full path. Set usefind to false to avoid using GNU/find
command.*/ command.
MimeType(const char* filename, bool usefind=true); Note: We advise using empty constructor and set method in loops.*/
MimeType(const char* filename=0, bool usefind=true);
// Silence compiler warning // Silence compiler warning
virtual ~MimeType(); virtual ~MimeType();
/*! Scan file with given full path and store the results until
next call of set() */
void set(const char* filename, bool usefind=true);
/*! Returns a string describing file type i.e. "PNG Image" */ /*! Returns a string describing file type i.e. "PNG Image" */
const char* type_string() { if (cur_typestr) return cur_typestr; else return 0;} const char* type_string() { if (cur_typestr) return cur_typestr; else return 0;}
@ -61,6 +71,7 @@ public:
private: private:
char *cur_id, *cur_typestr, *cur_command, *cur_iconname, *cur_filename; char *cur_id, *cur_typestr, *cur_command, *cur_iconname, *cur_filename;
void set_found(char *id); void set_found(char *id);
magic_t magic_cookie; //handle for libmagic
}; };
} }

View File

@ -96,7 +96,7 @@
#include <errno.h> #include <errno.h>
using namespace fltk; using namespace fltk;
using namespace edelib;
@ -128,13 +128,13 @@ int EditBox::handle(int event) {
char oldname[PATH_MAX]; char oldname[PATH_MAX];
strcpy(oldname, (char*)editing_->user_data()); strcpy(oldname, (char*)editing_->user_data());
if (rename(oldname, path) == -1) { if (rename(oldname, path) == -1) {
alert(edelib::tsprintf(_("Could not rename file! Error was:\n\t%s"), strerror(errno))); alert(tsprintf(_("Could not rename file! Error was:\n\t%s"), strerror(errno)));
} else { } else {
// Update browser // Update browser
free(editing_->user_data()); free(editing_->user_data());
editing_->user_data(strdup(path)); editing_->user_data(strdup(path));
const char* l = editing_->label(); const char* l = editing_->label();
editing_->label(edelib::tasprintf("%s%s",text(),strchr(l, '\t'))); editing_->label(tasprintf("%s%s",text(),strchr(l, '\t')));
} }
} }
@ -253,7 +253,7 @@ FileBrowser::load(const char *directory,// I - Directory to load
num_dirs = 0; num_dirs = 0;
if (show_dotdot_ && strcmp(directory_,"/") != 0) { if (show_dotdot_ && strcmp(directory_,"/") != 0) {
num_dirs++; num_dirs++;
Item* o = new Item ( edelib::Icon::get ( UPDIR_ICON, edelib::Icon::TINY ), "..\tGo up" ); Item* o = new Item ( Icon::get ( UPDIR_ICON, Icon::TINY ), "..\tGo up" );
Menu::add(*o); Menu::add(*o);
snprintf(filename, PATH_MAX, "%s../", directory_); snprintf(filename, PATH_MAX, "%s../", directory_);
o->user_data(strdup(filename)); o->user_data(strdup(filename));
@ -270,6 +270,7 @@ FileBrowser::load(const char *directory,// I - Directory to load
if (strcmp(n, ".")==0 || strcmp(n, "./")==0 || (!show_hidden_ && (n[0]=='.' || n[strlen(n)-1]=='~') ) ) if (strcmp(n, ".")==0 || strcmp(n, "./")==0 || (!show_hidden_ && (n[0]=='.' || n[strlen(n)-1]=='~') ) )
continue; continue;
fltk::check(); //update interface
// Add directory // Add directory
if (filetype_ != FILES && fltk::filename_isdir(filename)) { if (filetype_ != FILES && fltk::filename_isdir(filename)) {
@ -280,14 +281,14 @@ FileBrowser::load(const char *directory,// I - Directory to load
if (fn[strlen(fn)-1] == '/') if (fn[strlen(fn)-1] == '/')
fn[strlen(fn)-1] = '\0'; fn[strlen(fn)-1] = '\0';
Item* o = new Item ( edelib::Icon::get ( FOLDER_ICON,edelib::Icon::TINY ), fn); Item* o = new Item ( Icon::get ( FOLDER_ICON,Icon::TINY ), fn);
Menu::insert(*o, num_dirs-1); Menu::insert(*o, num_dirs-1);
o->user_data(strdup(filename)); // we keep full path for callback o->user_data(strdup(filename)); // we keep full path for callback
icon_array[i]=o; icon_array[i]=o;
// Add file // Add file
} else if (filetype_ != DIRECTORIES && fltk::filename_match(n, pattern_)) { } else if (filetype_ != DIRECTORIES && fltk::filename_match(n, pattern_)) {
Item* o = new Item(edelib::Icon::get(DEFAULT_ICON,edelib::Icon::TINY), strdup(n)); Item* o = new Item(Icon::get(DEFAULT_ICON,Icon::TINY), strdup(n));
Menu::add(*o); Menu::add(*o);
o->user_data(strdup(filename)); // we keep full path for callback o->user_data(strdup(filename)); // we keep full path for callback
icon_array[i]=o; icon_array[i]=o;
@ -300,6 +301,8 @@ FileBrowser::load(const char *directory,// I - Directory to load
// Detect icon mimetypes etc. // Detect icon mimetypes etc.
// //
MimeType *m = new MimeType();
for (i=0; i<num_files; i++) { for (i=0; i<num_files; i++) {
// ignored files // ignored files
if (!icon_array[i]) continue; if (!icon_array[i]) continue;
@ -307,7 +310,7 @@ FileBrowser::load(const char *directory,// I - Directory to load
// get mime data // get mime data
snprintf (filename,4095,"%s%s",directory_,files[i]->d_name); snprintf (filename,4095,"%s%s",directory_,files[i]->d_name);
edelib::MimeType *m = new edelib::MimeType(filename); m->set(filename);
// change label to complete data in various tabs // change label to complete data in various tabs
char *label; char *label;
@ -315,19 +318,19 @@ FileBrowser::load(const char *directory,// I - Directory to load
// Strip slash from filename // Strip slash from filename
char *n = strdup(files[i]->d_name); char *n = strdup(files[i]->d_name);
n[strlen(n)-1] = '\0'; n[strlen(n)-1] = '\0';
asprintf(&label, "%s\t%s\t\t%s", n, m->type_string(), edelib::nice_time(filename_mtime(filename))); asprintf(&label, "%s\t%s\t\t%s", n, m->type_string(), nice_time(filename_mtime(filename)));
free(n); free(n);
} else } else
asprintf(&label, "%s\t%s\t%s\t%s", files[i]->d_name, m->type_string(), edelib::nice_size(filename_size(filename)), edelib::nice_time(filename_mtime(filename))); asprintf(&label, "%s\t%s\t%s\t%s", files[i]->d_name, m->type_string(), nice_size(filename_size(filename)), nice_time(filename_mtime(filename)));
icon_array[i]->label(label); icon_array[i]->label(label);
// icon // icon
icon_array[i]->image(m->icon(edelib::Icon::TINY)); icon_array[i]->image(m->icon(Icon::TINY));
icon_array[i]->redraw(); icon_array[i]->redraw();
delete m;
free(files[i]); free(files[i]);
} }
delete m;
free(files); free(files);
return (num_files); return (num_files);

View File

@ -189,6 +189,9 @@ fprintf (stderr, "loaddir(%s) = (%s)\n",path,current_dir);
sgroup->redraw(); sgroup->redraw();
// Init mimetypes
MimeType *m = new MimeType;
// Detect icon mimetypes etc. // Detect icon mimetypes etc.
for (int i=0; i<icon_num; i++) { for (int i=0; i<icon_num; i++) {
// ignored files // ignored files
@ -198,7 +201,7 @@ fprintf (stderr, "loaddir(%s) = (%s)\n",path,current_dir);
// get mime data // get mime data
char fullpath[PATH_MAX]; char fullpath[PATH_MAX];
snprintf (fullpath,PATH_MAX-1,"%s%s",current_dir,files[i]->d_name); snprintf (fullpath,PATH_MAX-1,"%s%s",current_dir,files[i]->d_name);
MimeType *m = new MimeType(fullpath); m->set(fullpath);
fprintf(stderr,"Adding: %s (%s), cmd: '%s'\n", fullpath, m->id(), m->command()); fprintf(stderr,"Adding: %s (%s), cmd: '%s'\n", fullpath, m->id(), m->command());
@ -251,8 +254,9 @@ fprintf(stderr,"Adding: %s (%s), cmd: '%s'\n", fullpath, m->id(), m->command());
pos--; pos--;
} }
icon_array[i]->redraw(); icon_array[i]->redraw();
delete m;
} }
// MimeType destructor
delete m;
sgroup->redraw(); sgroup->redraw();
semaphore=false; semaphore=false;