summaryrefslogtreecommitdiff
path: root/src/lib/efreet
diff options
context:
space:
mode:
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>2016-08-23 11:59:37 +0900
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>2016-08-23 12:04:06 +0900
commit561f8eaa8faebe32b9a03cf9674c147cf0d6d9ab (patch)
tree150e42dcb87333b146e884f6bf72dc5f561e7967 /src/lib/efreet
parent56c52311e5590543272b0465a750936475ad28e7 (diff)
efreet - save about 240-300k or so of memory used by efreet mime
so efreet mime was loading a bunch of mime type info files, parsing them on startup and allocating memory to store all this mime info - globs, mimetype strings and more. all a big waste of memory as its allocated on the heap per process where its the SAME data files loaded every time. so make an efreet mime cache file and a tool to create it from mime files. mmap this file with all the hashes/strings in it so all that data is mmaped once in memory and shared between all processes and it is only paged in on demand - as actually read/needed so if your process doesnt need to know about mime stuff.. it wont touch it anyway. this saves about 240-300k or so of memory in my tests. this has not covered the mime MAGIC files which still consume memory and are on the heap. this is more complex so it will take more time to come up with a nice file format for the data that is nicely mmaped etc. @optimize
Diffstat (limited to 'src/lib/efreet')
-rw-r--r--src/lib/efreet/efreet_cache.c6
-rw-r--r--src/lib/efreet/efreet_mime.c618
-rw-r--r--src/lib/efreet/efreet_private.h2
3 files changed, 251 insertions, 375 deletions
diff --git a/src/lib/efreet/efreet_cache.c b/src/lib/efreet/efreet_cache.c
index f8d5e5ce43..de4ca7440e 100644
--- a/src/lib/efreet/efreet_cache.c
+++ b/src/lib/efreet/efreet_cache.c
@@ -203,6 +203,8 @@ _icon_desktop_cache_update_event_add(int event_type)
203 ecore_event_add(event_type, ev, icon_cache_update_free, l); 203 ecore_event_add(event_type, ev, icon_cache_update_free, l);
204} 204}
205 205
206EAPI void (*_efreet_mime_update_func) (void) = NULL;
207
206static Eina_Bool 208static Eina_Bool
207_cb_server_data(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) 209_cb_server_data(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
208{ 210{
@@ -223,6 +225,10 @@ _cb_server_data(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
223 { 225 {
224 _icon_desktop_cache_update_event_add(EFREET_EVENT_DESKTOP_CACHE_UPDATE); 226 _icon_desktop_cache_update_event_add(EFREET_EVENT_DESKTOP_CACHE_UPDATE);
225 } 227 }
228 else if (e->major == 4) // mime cache update
229 {
230 if (_efreet_mime_update_func) _efreet_mime_update_func();
231 }
226 return ECORE_CALLBACK_DONE; 232 return ECORE_CALLBACK_DONE;
227} 233}
228 234
diff --git a/src/lib/efreet/efreet_mime.c b/src/lib/efreet/efreet_mime.c
index 87ca8ef414..4426b6a130 100644
--- a/src/lib/efreet/efreet_mime.c
+++ b/src/lib/efreet/efreet_mime.c
@@ -32,11 +32,8 @@ static int _efreet_mime_log_dom = -1;
32#include "Efreet_Mime.h" 32#include "Efreet_Mime.h"
33#include "efreet_private.h" 33#include "efreet_private.h"
34 34
35static Eina_List *globs = NULL; /* contains Efreet_Mime_Glob structs */ 35static Eina_List *magics = NULL; // contains Efreet_Mime_Magic structs
36static Eina_List *magics = NULL; /* contains Efreet_Mime_Magic structs */ 36static Eina_Hash *mime_icons = NULL; // contains cache with mime->icons
37static Eina_Hash *wild = NULL; /* contains *.ext and mime.types globs*/
38static Eina_Hash *monitors = NULL; /* contains file monitors */
39static Eina_Hash *mime_icons = NULL; /* contains cache with mime->icons */
40static Eina_Inlist *mime_icons_lru = NULL; 37static Eina_Inlist *mime_icons_lru = NULL;
41static unsigned int _efreet_mime_init_count = 0; 38static unsigned int _efreet_mime_init_count = 0;
42 39
@@ -89,13 +86,6 @@ static enum
89 */ 86 */
90//#define EFREET_MIME_ICONS_DEBUG 87//#define EFREET_MIME_ICONS_DEBUG
91 88
92typedef struct Efreet_Mime_Glob Efreet_Mime_Glob;
93struct Efreet_Mime_Glob
94{
95 const char *glob;
96 const char *mime;
97};
98
99typedef struct Efreet_Mime_Magic Efreet_Mime_Magic; 89typedef struct Efreet_Mime_Magic Efreet_Mime_Magic;
100struct Efreet_Mime_Magic 90struct Efreet_Mime_Magic
101{ 91{
@@ -134,9 +124,6 @@ struct Efreet_Mime_Icon_Entry
134 unsigned int size; 124 unsigned int size;
135}; 125};
136 126
137static int efreet_mime_glob_remove(const char *glob);
138static void efreet_mime_mime_types_load(const char *file);
139static void efreet_mime_shared_mimeinfo_globs_load(const char *file);
140static void efreet_mime_shared_mimeinfo_magic_load(const char *file); 127static void efreet_mime_shared_mimeinfo_magic_load(const char *file);
141static void efreet_mime_shared_mimeinfo_magic_parse(char *data, int size); 128static void efreet_mime_shared_mimeinfo_magic_parse(char *data, int size);
142static const char *efreet_mime_magic_check_priority(const char *file, 129static const char *efreet_mime_magic_check_priority(const char *file,
@@ -145,19 +132,12 @@ static const char *efreet_mime_magic_check_priority(const char *file,
145static int efreet_mime_init_files(void); 132static int efreet_mime_init_files(void);
146static const char *efreet_mime_special_check(const char *file); 133static const char *efreet_mime_special_check(const char *file);
147static const char *efreet_mime_fallback_check(const char *file); 134static const char *efreet_mime_fallback_check(const char *file);
148static void efreet_mime_glob_free(void *data);
149static void efreet_mime_magic_free(void *data); 135static void efreet_mime_magic_free(void *data);
150static void efreet_mime_magic_entry_free(void *data); 136static void efreet_mime_magic_entry_free(void *data);
151static int efreet_mime_glob_match(const char *str, const char *glob); 137static int efreet_mime_glob_match(const char *str, const char *glob);
152static int efreet_mime_glob_case_match(char *str, const char *glob); 138static int efreet_mime_glob_case_match(char *str, const char *glob);
153static int efreet_mime_endian_check(void); 139static int efreet_mime_endian_check(void);
154 140
155static void efreet_mime_monitor_add(const char *file);
156static void efreet_mime_cb_update_file(void *data,
157 Ecore_File_Monitor *monitor,
158 Ecore_File_Event event,
159 const char *path);
160
161static void efreet_mime_icons_flush(double now); 141static void efreet_mime_icons_flush(double now);
162static void efreet_mime_icon_entry_head_free(Efreet_Mime_Icon_Entry_Head *entry); 142static void efreet_mime_icon_entry_head_free(Efreet_Mime_Icon_Entry_Head *entry);
163static void efreet_mime_icon_entry_add(const char *mime, 143static void efreet_mime_icon_entry_add(const char *mime,
@@ -169,6 +149,218 @@ static const char *efreet_mime_icon_entry_find(const char *mime,
169 unsigned int size); 149 unsigned int size);
170static void efreet_mime_icons_debug(void); 150static void efreet_mime_icons_debug(void);
171 151
152
153
154
155
156
157
158
159
160
161
162
163static Eina_File *mimedb = NULL;
164static unsigned char *mimedb_ptr = NULL;
165static size_t mimedb_size = 0;
166
167static void
168_efreet_mimedb_shutdown(void)
169{
170 if (mimedb)
171 {
172 if (mimedb_ptr) eina_file_map_free(mimedb, mimedb_ptr);
173 eina_file_close(mimedb);
174 mimedb = NULL;
175 mimedb_ptr = NULL;
176 mimedb_size = 0;
177 }
178}
179
180static void
181_efreet_mimedb_update(void)
182{
183 char buf[PATH_MAX];
184
185 if (mimedb)
186 {
187 if (mimedb_ptr) eina_file_map_free(mimedb, mimedb_ptr);
188 eina_file_close(mimedb);
189 mimedb = NULL;
190 mimedb_ptr = NULL;
191 mimedb_size = 0;
192 }
193#ifdef WORDS_BIGENDIAN
194 snprintf(buf, sizeof(buf), "%s/efreet/mime_cache_%s.be.dat",
195 efreet_cache_home_get(), efreet_hostname_get());
196#else
197 snprintf(buf, sizeof(buf), "%s/efreet/mime_cache_%s.le.dat",
198 efreet_cache_home_get(), efreet_hostname_get());
199#endif
200 mimedb = eina_file_open(buf, EINA_FALSE);
201 if (mimedb)
202 {
203 mimedb_ptr = eina_file_map_all(mimedb, EINA_FILE_POPULATE);
204 if (mimedb_ptr)
205 {
206 mimedb_size = eina_file_size_get(mimedb);
207 if ((mimedb_size > (16 + 4 + 4 + 4) &&
208 (!strncmp((char *)mimedb_ptr, "EfrEeT-MiMeS-001", 16))))
209 {
210 // load ok - magic fine. more sanity checks?
211 }
212 else
213 {
214 eina_file_map_free(mimedb, mimedb_ptr);
215 mimedb_ptr = NULL;
216 eina_file_close(mimedb);
217 mimedb = NULL;
218 mimedb_size = 0;
219 }
220 }
221 else
222 {
223 eina_file_close(mimedb);
224 mimedb = NULL;
225 }
226 }
227}
228
229static const char *
230_efreet_mimedb_str_get(unsigned int offset)
231{
232 if (offset < (16 + 4 + 4 + 4)) return NULL;
233 if (offset >= mimedb_size) return NULL;
234 return (const char *)(mimedb_ptr + offset);
235}
236
237static unsigned int
238_efreet_mimedb_uint_get(unsigned int index)
239// index is the unit NUMBER AFTER the header
240{
241 unsigned int *ptr;
242 ptr = ((unsigned int *)(mimedb_ptr + 16)) + index;
243 if ((size_t)(((unsigned char *)ptr) - mimedb_ptr) >= (mimedb_size - 4))
244 return 0;
245 return *ptr;
246}
247
248static unsigned int
249_efreet_mimedb_mime_count(void)
250{
251 return _efreet_mimedb_uint_get(0);
252}
253
254/**** currently unused - here for symmetry and future use
255static const char *
256_efreet_mimedb_mime_get(unsigned int num)
257{
258 unsigned int offset = _efreet_mimedb_uint_get
259 (1 + num);
260 return _efreet_mimedb_str_get(offset);
261}
262*/
263
264static unsigned int
265_efreet_mimedb_extn_count(void)
266{
267 return _efreet_mimedb_uint_get(1 + _efreet_mimedb_mime_count());
268}
269
270static const char *
271_efreet_mimedb_extn_get(unsigned int num)
272{
273 unsigned int offset = _efreet_mimedb_uint_get
274 (1 + _efreet_mimedb_mime_count() + 1 + (num * 2));
275 return _efreet_mimedb_str_get(offset);
276}
277
278static const char *
279_efreet_mimedb_extn_mime_get(unsigned int num)
280{
281 unsigned int offset = _efreet_mimedb_uint_get
282 (1 + _efreet_mimedb_mime_count() + 1 + (num * 2) + 1);
283 return _efreet_mimedb_str_get(offset);
284}
285
286static const char *
287_efreet_mimedb_extn_find(const char *extn)
288{
289 unsigned int i, begin, end;
290 const char *s;
291
292 // binary search keys to get value
293 begin = 0;
294 end = _efreet_mimedb_extn_count();
295 i = (begin + end) / 2;
296 for (;;)
297 {
298 s = _efreet_mimedb_extn_get(i);
299 if (s)
300 {
301 int v = strcmp(extn, s);
302 if (v < 0)
303 {
304 end = i;
305 i = (begin + end) / 2;
306 if ((end - begin) == 0) break;
307 }
308 else if (v > 0)
309 {
310 if ((end - begin) > 1)
311 {
312 begin = i;
313 i = (begin + end) / 2;
314 if (i == end) break;
315 }
316 else
317 {
318 if ((end - begin) == 0) break;
319 begin = end;
320 i = end;
321 }
322 }
323 else if (v == 0)
324 return _efreet_mimedb_extn_mime_get(i);
325 }
326 else
327 {
328 break;
329 }
330 }
331 return NULL;
332}
333
334static unsigned int
335_efreet_mimedb_glob_count(void)
336{
337 return _efreet_mimedb_uint_get
338 (1 + _efreet_mimedb_mime_count() +
339 1 + (_efreet_mimedb_extn_count() * 2));
340}
341
342static const char *
343_efreet_mimedb_glob_get(unsigned int num)
344{
345 unsigned int offset = _efreet_mimedb_uint_get
346 (1 + _efreet_mimedb_mime_count() +
347 1 + (_efreet_mimedb_extn_count() * 2) +
348 1 + (num * 2));
349 return _efreet_mimedb_str_get(offset);
350}
351
352static const char *
353_efreet_mimedb_glob_mime_get(unsigned int num)
354{
355 unsigned int offset = _efreet_mimedb_uint_get
356 (1 + _efreet_mimedb_mime_count() +
357 1 + (_efreet_mimedb_extn_count() * 2) +
358 1 + (num * 2) + 1);
359 return _efreet_mimedb_str_get(offset);
360}
361
362/** --------------------------------- **/
363
172EAPI int 364EAPI int
173efreet_mime_init(void) 365efreet_mime_init(void)
174{ 366{
@@ -194,14 +386,15 @@ efreet_mime_init(void)
194 } 386 }
195 387
196 efreet_mime_endianess = efreet_mime_endian_check(); 388 efreet_mime_endianess = efreet_mime_endian_check();
197
198 monitors = eina_hash_string_superfast_new(EINA_FREE_CB(ecore_file_monitor_del));
199
200 efreet_mime_type_cache_clear(); 389 efreet_mime_type_cache_clear();
201 390
391 _efreet_mimedb_update();
392
202 if (!efreet_mime_init_files()) 393 if (!efreet_mime_init_files())
203 goto unregister_log_domain; 394 goto unregister_log_domain;
204 395
396 _efreet_mime_update_func = _efreet_mimedb_update;
397
205 return _efreet_mime_init_count; 398 return _efreet_mime_init_count;
206 399
207unregister_log_domain: 400unregister_log_domain:
@@ -228,6 +421,9 @@ efreet_mime_shutdown(void)
228 if (--_efreet_mime_init_count != 0) 421 if (--_efreet_mime_init_count != 0)
229 return _efreet_mime_init_count; 422 return _efreet_mime_init_count;
230 423
424 _efreet_mimedb_shutdown();
425 _efreet_mime_update_func = NULL;
426
231 efreet_mime_icons_debug(); 427 efreet_mime_icons_debug();
232 428
233 IF_RELEASE(_mime_inode_symlink); 429 IF_RELEASE(_mime_inode_symlink);
@@ -241,10 +437,7 @@ efreet_mime_shutdown(void)
241 IF_RELEASE(_mime_application_octet_stream); 437 IF_RELEASE(_mime_application_octet_stream);
242 IF_RELEASE(_mime_text_plain); 438 IF_RELEASE(_mime_text_plain);
243 439
244 IF_FREE_LIST(globs, efreet_mime_glob_free);
245 IF_FREE_LIST(magics, efreet_mime_magic_free); 440 IF_FREE_LIST(magics, efreet_mime_magic_free);
246 IF_FREE_HASH(monitors);
247 IF_FREE_HASH(wild);
248 IF_FREE_HASH(mime_icons); 441 IF_FREE_HASH(mime_icons);
249 eina_log_domain_unregister(_efreet_mime_log_dom); 442 eina_log_domain_unregister(_efreet_mime_log_dom);
250 _efreet_mime_log_dom = -1; 443 _efreet_mime_log_dom = -1;
@@ -387,11 +580,10 @@ efreet_mime_magic_type_get(const char *file)
387EAPI const char * 580EAPI const char *
388efreet_mime_globs_type_get(const char *file) 581efreet_mime_globs_type_get(const char *file)
389{ 582{
390 Eina_List *l;
391 Efreet_Mime_Glob *g;
392 char *sl, *p; 583 char *sl, *p;
393 const char *s; 584 const char *s, *mime;
394 char *ext, *mime; 585 char *ext;
586 unsigned int i, n;
395 587
396 EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL); 588 EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL);
397 589
@@ -406,25 +598,27 @@ efreet_mime_globs_type_get(const char *file)
406 while (p) 598 while (p)
407 { 599 {
408 p++; 600 p++;
409 if (p && (mime = eina_hash_find(wild, p))) return mime; 601 if (p && (mime = _efreet_mimedb_extn_find(p))) return mime;
410 p = strchr(p, '.'); 602 p = strchr(p, '.');
411 } 603 }
412 } 604 }
413 605
414 /* Fallback to the other globs if not found */ 606 // Fallback to the other globs if not found
415 EINA_LIST_FOREACH(globs, l, g) 607 n = _efreet_mimedb_glob_count();
608 for (i = 0; i < n; i++)
416 { 609 {
417 if (efreet_mime_glob_match(file, g->glob)) 610 s = _efreet_mimedb_glob_get(i);
418 return g->mime; 611 if (efreet_mime_glob_match(file, s))
612 return _efreet_mimedb_glob_mime_get(i);
419 } 613 }
420
421 ext = alloca(strlen(file) + 1); 614 ext = alloca(strlen(file) + 1);
422 for (s = file, p = ext; *s; s++, p++) *p = tolower(*s); 615 for (s = file, p = ext; *s; s++, p++) *p = tolower(*s);
423 *p = 0; 616 *p = 0;
424 EINA_LIST_FOREACH(globs, l, g) 617 for (i = 0; i < n; i++)
425 { 618 {
426 if (efreet_mime_glob_case_match(ext, g->glob)) 619 s = _efreet_mimedb_glob_get(i);
427 return g->mime; 620 if (efreet_mime_glob_case_match(ext, s))
621 return _efreet_mimedb_glob_mime_get(i);
428 } 622 }
429 return NULL; 623 return NULL;
430} 624}
@@ -457,72 +651,6 @@ efreet_mime_endian_check(void)
457 651
458/** 652/**
459 * @internal 653 * @internal
460 * @param file File to monitor
461 * @return Returns no value.
462 * @brief Creates a new file monitor if we aren't already monitoring the
463 * given file
464 */
465static void
466efreet_mime_monitor_add(const char *file)
467{
468 Ecore_File_Monitor *fm = NULL;
469
470 /* if this is already in our hash then we're already monitoring so no
471 * reason to re-monitor */
472 if (eina_hash_find(monitors, file))
473 return;
474
475 if ((fm = ecore_file_monitor_add(file, efreet_mime_cb_update_file, NULL)))
476 {
477 eina_hash_del(monitors, file, NULL);
478 eina_hash_add(monitors, file, fm);
479 }
480}
481
482/**
483 * @internal
484 * @param datadirs List of XDG data dirs
485 * @param datahome Path to XDG data home directory
486 * @return Returns no value
487 * @brief Read all glob files in XDG data/home dirs.
488 * Also reads the /etc/mime.types file.
489 */
490static void
491efreet_mime_load_globs(Eina_List *datadirs, const char *datahome)
492{
493 Eina_List *l;
494 char buf[4096];
495 const char *datadir = NULL;
496
497 IF_FREE_HASH(wild);
498 wild = eina_hash_string_superfast_new(EINA_FREE_CB(eina_stringshare_del));
499 while (globs)
500 {
501 efreet_mime_glob_free(eina_list_data_get(globs));
502 globs = eina_list_remove_list(globs, globs);
503 }
504
505 /*
506 * This is here for legacy reasons. It is mentioned briefly
507 * in the spec and seems to still be quite valid. It is
508 * loaded first so the globs files will override anything
509 * in here.
510 */
511 efreet_mime_mime_types_load("/etc/mime.types");
512
513 datadir = datahome;
514 snprintf(buf, sizeof(buf), "%s/mime/globs", datadir);
515 efreet_mime_shared_mimeinfo_globs_load(buf);
516
517 EINA_LIST_FOREACH(datadirs, l, datadir)
518 {
519 snprintf(buf, sizeof(buf), "%s/mime/globs", datadir);
520 efreet_mime_shared_mimeinfo_globs_load(buf);
521 }
522}
523
524/**
525 * @internal
526 * @param datadirs List of XDG data dirs 654 * @param datadirs List of XDG data dirs
527 * @param datahome Path to XDG data home directory 655 * @param datahome Path to XDG data home directory
528 * @return Returns no value 656 * @return Returns no value
@@ -554,39 +682,6 @@ efreet_mime_load_magics(Eina_List *datadirs, const char *datahome)
554 682
555/** 683/**
556 * @internal 684 * @internal
557 * @param data Data pointer passed to monitor_add
558 * @param monitor Ecore_File_Monitor associated with this event
559 * @param event The type of event
560 * @param path Path to the file that was updated
561 * @return Returns no value
562 * @brief Callback for all file monitors. Just reloads the appropriate
563 * list depending on which file changed. If it was a magic file
564 * only the magic list is updated. If it was a glob file or /etc/mime.types,
565 * the globs are updated.
566 */
567static void
568efreet_mime_cb_update_file(void *data EINA_UNUSED,
569 Ecore_File_Monitor *monitor EINA_UNUSED,
570 Ecore_File_Event event EINA_UNUSED,
571 const char *path)
572{
573 Eina_List *datadirs = NULL;
574 const char *datahome = NULL;
575
576 if (!(datahome = efreet_data_home_get()))
577 return;
578
579 if (!(datadirs = efreet_data_dirs_get()))
580 return;
581
582 if (strstr(path, "magic"))
583 efreet_mime_load_magics(datadirs, datahome);
584 else
585 efreet_mime_load_globs(datadirs, datahome);
586}
587
588/**
589 * @internal
590 * @param datadirs List of XDG data dirs 685 * @param datadirs List of XDG data dirs
591 * @param datahome Path to XDG data home directory 686 * @param datahome Path to XDG data home directory
592 * @return Returns 1 on success, 0 on failure 687 * @return Returns 1 on success, 0 on failure
@@ -595,10 +690,8 @@ efreet_mime_cb_update_file(void *data EINA_UNUSED,
595static int 690static int
596efreet_mime_init_files(void) 691efreet_mime_init_files(void)
597{ 692{
598 Eina_List *l;
599 Eina_List *datadirs = NULL; 693 Eina_List *datadirs = NULL;
600 char buf[PATH_MAX]; 694 const char *datahome;
601 const char *datahome, *datadir = NULL;
602 695
603 if (!(datahome = efreet_data_home_get())) 696 if (!(datahome = efreet_data_home_get()))
604 return 0; 697 return 0;
@@ -606,32 +699,15 @@ efreet_mime_init_files(void)
606 if (!(datadirs = efreet_data_dirs_get())) 699 if (!(datadirs = efreet_data_dirs_get()))
607 return 0; 700 return 0;
608 701
609 /*
610 * Add our file monitors
611 * We watch the directories so we can watch for new files
612 */
613 datadir = datahome;
614 snprintf(buf, sizeof(buf), "%s/mime", datadir);
615 efreet_mime_monitor_add(buf);
616
617 EINA_LIST_FOREACH(datadirs, l, datadir)
618 {
619 snprintf(buf, sizeof(buf), "%s/mime", datadir);
620 efreet_mime_monitor_add(buf);
621 }
622 efreet_mime_monitor_add("/etc/mime.types");
623
624 /* Load our mime information */
625 efreet_mime_load_globs(datadirs, datahome);
626 efreet_mime_load_magics(datadirs, datahome); 702 efreet_mime_load_magics(datadirs, datahome);
627 703
628 _mime_inode_symlink = eina_stringshare_add("inode/symlink"); 704 _mime_inode_symlink = eina_stringshare_add("inode/symlink");
629 _mime_inode_fifo = eina_stringshare_add("inode/fifo"); 705 _mime_inode_fifo = eina_stringshare_add("inode/fifo");
630 _mime_inode_chardevice = eina_stringshare_add("inode/chardevice"); 706 _mime_inode_chardevice = eina_stringshare_add("inode/chardevice");
631 _mime_inode_blockdevice = eina_stringshare_add("inode/blockdevice"); 707 _mime_inode_blockdevice = eina_stringshare_add("inode/blockdevice");
632 _mime_inode_socket = eina_stringshare_add("inode/socket"); 708 _mime_inode_socket = eina_stringshare_add("inode/socket");
633 _mime_inode_mountpoint = eina_stringshare_add("inode/mountpoint"); 709 _mime_inode_mountpoint = eina_stringshare_add("inode/mountpoint");
634 _mime_inode_directory = eina_stringshare_add("inode/directory"); 710 _mime_inode_directory = eina_stringshare_add("inode/directory");
635 _mime_application_x_executable = eina_stringshare_add("application/x-executable"); 711 _mime_application_x_executable = eina_stringshare_add("application/x-executable");
636 _mime_application_octet_stream = eina_stringshare_add("application/octet-stream"); 712 _mime_application_octet_stream = eina_stringshare_add("application/octet-stream");
637 _mime_text_plain = eina_stringshare_add("text/plain"); 713 _mime_text_plain = eina_stringshare_add("text/plain");
@@ -781,198 +857,6 @@ efreet_mime_fallback_check(const char *file)
781 857
782/** 858/**
783 * @internal 859 * @internal
784 * @param glob Glob to search for
785 * @return Returns 1 on success, 0 on failure
786 * @brief Removes a glob from the list
787 */
788static int
789efreet_mime_glob_remove(const char *glob)
790{
791 Efreet_Mime_Glob *mime = NULL;
792
793 if ((mime = eina_list_search_unsorted(globs, EINA_COMPARE_CB(strcmp), glob)))
794 {
795 globs = eina_list_remove(globs, mime);
796 IF_RELEASE(mime->glob);
797 IF_RELEASE(mime->mime);
798 FREE(mime);
799 return 1;
800 }
801
802 return 0;
803}
804
805static inline const char *
806efreet_eat_space(const char *head, const Eina_File_Line *ln, Eina_Bool not)
807{
808 if (not)
809 {
810 while (!isspace(*head) && (head < ln->end))
811 head++;
812 }
813 else
814 {
815 while (isspace(*head) && (head < ln->end))
816 head++;
817 }
818
819 return head;
820}
821
822/**
823 * @internal
824 * @param file mime.types file to load
825 * @return Returns no value
826 * @brief Loads values from a mime.types style file
827 * into the globs list.
828 * @note Format:
829 * application/msaccess mdb
830 * application/msword doc dot
831 */
832static void
833efreet_mime_mime_types_load(const char *file)
834{
835 const Eina_File_Line *ln;
836 Eina_Iterator *it;
837 Eina_File *f;
838 const char *head_line;
839 const char *word_start;
840 const char *mimetype;
841
842 EINA_SAFETY_ON_NULL_RETURN(file);
843 f = eina_file_open(file, 0);
844 if (!f) return;
845
846 it = eina_file_map_lines(f);
847 if (it)
848 {
849 Eina_Strbuf *ext;
850
851 ext = eina_strbuf_new();
852
853 EINA_ITERATOR_FOREACH(it, ln)
854 {
855 head_line = efreet_eat_space(ln->start, ln, EINA_FALSE);
856 if (head_line == ln->end) continue ;
857
858 if (*head_line == '#') continue ;
859
860 word_start = head_line;
861 head_line = efreet_eat_space(head_line, ln, EINA_TRUE);
862
863 if (head_line == ln->end) continue ;
864 mimetype = eina_stringshare_add_length(word_start, head_line - word_start);
865 do
866 {
867 head_line = efreet_eat_space(head_line, ln, EINA_FALSE);
868 if (head_line == ln->end) break ;
869
870 word_start = head_line;
871 head_line = efreet_eat_space(head_line, ln, EINA_TRUE);
872
873 eina_strbuf_append_length(ext, word_start, head_line - word_start);
874
875 eina_hash_del(wild,
876 eina_strbuf_string_get(ext),
877 NULL);
878 eina_hash_add(wild,
879 eina_strbuf_string_get(ext),
880 eina_stringshare_ref(mimetype));
881
882 eina_strbuf_reset(ext);
883 }
884 while (head_line < ln->end);
885
886 eina_stringshare_del(mimetype);
887 }
888
889 eina_strbuf_free(ext);
890 eina_iterator_free(it);
891 }
892 eina_file_close(f);
893}
894
895/**
896 * @internal
897 * @param file globs file to load
898 * @return Returns no value
899 * @brief Loads values from a mime.types style file
900 * into the globs list.
901 * @note Format:
902 * text/vnd.wap.wml:*.wml
903 * application/x-7z-compressed:*.7z
904 * application/vnd.corel-draw:*.cdr
905 * text/spreadsheet:*.sylk
906 */
907static void
908efreet_mime_shared_mimeinfo_globs_load(const char *file)
909{
910 FILE *f = NULL;
911 char buf[4096], mimetype[4096], ext[4096], *p, *pp;
912 Efreet_Mime_Glob *mime = NULL;
913
914 f = fopen(file, "rb");
915 if (!f) return;
916
917 while (fgets(buf, sizeof(buf), f))
918 {
919 p = buf;
920 while (isspace(*p) && (*p != 0) && (*p != '\n')) p++;
921
922 if (*p == '#') continue;
923 if ((*p == '\n') || (*p == 0)) continue;
924
925 pp = p;
926 while ((*p != ':') && (*p != 0) && (*p != '\n')) p++;
927
928 if ((*p == '\n') || (*p == 0)) continue;
929 strncpy(mimetype, pp, (p - pp));
930 mimetype[p - pp] = 0;
931 p++;
932 pp = ext;
933
934 while ((*p != 0) && (*p != '\n'))
935 {
936 *pp = *p;
937 pp++;
938 p++;
939 }
940
941 *pp = 0;
942
943 if (ext[0] == '*' && ext[1] == '.')
944 {
945 eina_hash_del(wild, &(ext[2]), NULL);
946 eina_hash_add(wild, &(ext[2]),
947 (void*)eina_stringshare_add(mimetype));
948 }
949 else
950 {
951 mime = NEW(Efreet_Mime_Glob, 1);
952 if (mime)
953 {
954 mime->mime = eina_stringshare_add(mimetype);
955 mime->glob = eina_stringshare_add(ext);
956 if ((!mime->mime) || (!mime->glob))
957 {
958 IF_RELEASE(mime->mime);
959 IF_RELEASE(mime->glob);
960 FREE(mime);
961 }
962 else
963 {
964 efreet_mime_glob_remove(ext);
965 globs = eina_list_append(globs, mime);
966 }
967 }
968 }
969 }
970
971 fclose(f);
972}
973
974/**
975 * @internal
976 * @param in Number to count the digits 860 * @param in Number to count the digits
977 * @return Returns number of digits 861 * @return Returns number of digits
978 * @brief Calculates and returns the number of digits 862 * @brief Calculates and returns the number of digits
@@ -1341,22 +1225,6 @@ efreet_mime_magic_check_priority(const char *file,
1341 * @internal 1225 * @internal
1342 * @param data Data pointer that is being destroyed 1226 * @param data Data pointer that is being destroyed
1343 * @return Returns no value 1227 * @return Returns no value
1344 * @brief Callback for globs destroy
1345 */
1346static void
1347efreet_mime_glob_free(void *data)
1348{
1349 Efreet_Mime_Glob *m = data;
1350
1351 IF_RELEASE(m->mime);
1352 IF_RELEASE(m->glob);
1353 IF_FREE(m);
1354}
1355
1356/**
1357 * @internal
1358 * @param data Data pointer that is being destroyed
1359 * @return Returns no value
1360 * @brief Callback for magics destroy 1228 * @brief Callback for magics destroy
1361 */ 1229 */
1362static void 1230static void
diff --git a/src/lib/efreet/efreet_private.h b/src/lib/efreet/efreet_private.h
index 139754d81a..47d6deae12 100644
--- a/src/lib/efreet/efreet_private.h
+++ b/src/lib/efreet/efreet_private.h
@@ -251,6 +251,8 @@ EAPI void efreet_fsetowner(int fd);
251 251
252EAPI extern int efreet_cache_update; 252EAPI extern int efreet_cache_update;
253 253
254EAPI extern void (*_efreet_mime_update_func) (void);
255
254#undef EAPI 256#undef EAPI
255#define EAPI 257#define EAPI
256 258