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 "Config.h"
#include "Util.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -170,9 +169,15 @@ void MimeType::set_found(char *id) {
}
MimeType::MimeType(const char* filename, bool usefind) {
void MimeType::set(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;
if (filename && filename_exist(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 ;)
// execute file command
// TODO: save cookie in a static variable
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));
// execute file command through libmagic
buffer = strdup(magic_file(magic_cookie, filename));
// read cmd output from temp file
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);
fprintf (stderr,"(%s) File said: %s (Error: %s)\n",filename,buffer,magic_error(magic_cookie));
// find matches for 'file' command output
// TODO: add wildcard matching
@ -349,6 +343,21 @@ fprintf(stderr, "Foundext: %d\n", foundext);
cur_typestr = strdup("Unknown");
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_iconname) free(cur_iconname);
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_
#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"
namespace edelib {
@ -37,13 +41,19 @@ public:
/*! Constructor takes filename and all interesting data is
returned with methods listed below. filename must contain
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
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" */
const char* type_string() { if (cur_typestr) return cur_typestr; else return 0;}
@ -61,6 +71,7 @@ public:
private:
char *cur_id, *cur_typestr, *cur_command, *cur_iconname, *cur_filename;
void set_found(char *id);
magic_t magic_cookie; //handle for libmagic
};
}

View File

@ -96,7 +96,7 @@
#include <errno.h>
using namespace fltk;
using namespace edelib;
@ -128,13 +128,13 @@ int EditBox::handle(int event) {
char oldname[PATH_MAX];
strcpy(oldname, (char*)editing_->user_data());
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 {
// Update browser
free(editing_->user_data());
editing_->user_data(strdup(path));
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;
if (show_dotdot_ && strcmp(directory_,"/") != 0) {
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);
snprintf(filename, PATH_MAX, "%s../", directory_);
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]=='~') ) )
continue;
fltk::check(); //update interface
// Add directory
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] == '/')
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);
o->user_data(strdup(filename)); // we keep full path for callback
icon_array[i]=o;
// Add file
} 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);
o->user_data(strdup(filename)); // we keep full path for callback
icon_array[i]=o;
@ -300,6 +301,8 @@ FileBrowser::load(const char *directory,// I - Directory to load
// Detect icon mimetypes etc.
//
MimeType *m = new MimeType();
for (i=0; i<num_files; i++) {
// ignored files
if (!icon_array[i]) continue;
@ -307,7 +310,7 @@ FileBrowser::load(const char *directory,// I - Directory to load
// get mime data
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
char *label;
@ -315,19 +318,19 @@ FileBrowser::load(const char *directory,// I - Directory to load
// Strip slash from filename
char *n = strdup(files[i]->d_name);
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);
} 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
icon_array[i]->image(m->icon(edelib::Icon::TINY));
icon_array[i]->image(m->icon(Icon::TINY));
icon_array[i]->redraw();
delete m;
free(files[i]);
}
delete m;
free(files);
return (num_files);

View File

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