mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-04 18:26:19 +01:00
Sync with upstream
svn path=/trunk/; revision=6975
This commit is contained in:
parent
7bbfdf3c6b
commit
2bd31c9e6c
@ -1,3 +1,9 @@
|
|||||||
|
2008-06-09 Matthias Clasen <mclasen@redhat.com>
|
||||||
|
|
||||||
|
* xdgmime/*: Sync with upstream. This brings support for
|
||||||
|
glob weights, generic icons, and changes the cache format to
|
||||||
|
version 1.1.
|
||||||
|
|
||||||
2008-05-28 Michael Natterer <mitch@imendio.com>
|
2008-05-28 Michael Natterer <mitch@imendio.com>
|
||||||
|
|
||||||
* Makefile.am: don't define G_DISABLE_SINGLE_INCLUDES, it's in
|
* Makefile.am: don't define G_DISABLE_SINGLE_INCLUDES, it's in
|
||||||
@ -49,6 +55,13 @@
|
|||||||
|
|
||||||
* Makefile.am : EXTRA_DIST += makefile.msc
|
* Makefile.am : EXTRA_DIST += makefile.msc
|
||||||
|
|
||||||
|
2008-05-17 Matthias Clasen <mclasen@redhat.com>
|
||||||
|
|
||||||
|
* gcontenttype.h:
|
||||||
|
* gcontenttype.c: (g_content_type_from_mime_type):
|
||||||
|
New function to create a content type from a mime type. (#527175,
|
||||||
|
Milan Crha)
|
||||||
|
|
||||||
2008-05-17 Matthias Clasen <mclasen@redhat.com>
|
2008-05-17 Matthias Clasen <mclasen@redhat.com>
|
||||||
|
|
||||||
Bug 532965 – Should not return filesystem::free for certain file systems
|
Bug 532965 – Should not return filesystem::free for certain file systems
|
||||||
|
@ -113,7 +113,59 @@ test_subclassing (void)
|
|||||||
test_subclass ("image/vnd.djvu", "image/x-djvu", 1);
|
test_subclass ("image/vnd.djvu", "image/x-djvu", 1);
|
||||||
test_subclass ("image/vnd.djvu", "text/plain", 0);
|
test_subclass ("image/vnd.djvu", "text/plain", 0);
|
||||||
test_subclass ("image/vnd.djvu", "text/*", 0);
|
test_subclass ("image/vnd.djvu", "text/*", 0);
|
||||||
test_subclass ("text/*", "text/plain", 0);
|
test_subclass ("text/*", "text/plain", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_one_match (const char *filename, const char *expected)
|
||||||
|
{
|
||||||
|
const char *actual;
|
||||||
|
|
||||||
|
actual = xdg_mime_get_mime_type_from_file_name (filename);
|
||||||
|
|
||||||
|
if (strcmp (actual, expected) != 0)
|
||||||
|
{
|
||||||
|
printf ("Test Failed: mime type of %s is %s, expected %s\n",
|
||||||
|
filename, actual, expected);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_matches (void)
|
||||||
|
{
|
||||||
|
test_one_match ("foo.bar.epub", "application/epub+zip");
|
||||||
|
test_one_match ("core", "application/x-core");
|
||||||
|
test_one_match ("README.in", "text/x-readme");
|
||||||
|
test_one_match ("README.gz", "application/x-gzip");
|
||||||
|
test_one_match ("blabla.cs", "text/x-csharp");
|
||||||
|
test_one_match ("blabla.f90", "text/x-fortran");
|
||||||
|
test_one_match ("blabla.F95", "text/x-fortran");
|
||||||
|
test_one_match ("tarball.tar.gz", "application/x-compressed-tar");
|
||||||
|
test_one_match ("file.gz", "application/x-gzip");
|
||||||
|
test_one_match ("file.tar.lzo", "application/x-tzo");
|
||||||
|
test_one_match ("file.lzo", "application/x-lzop");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_one_icon (const char *mimetype, const char *expected)
|
||||||
|
{
|
||||||
|
const char *actual;
|
||||||
|
|
||||||
|
actual = xdg_mime_get_icon (mimetype);
|
||||||
|
|
||||||
|
if (actual != expected && strcmp (actual, expected) != 0)
|
||||||
|
{
|
||||||
|
printf ("Test Failed: icon of %s is %s, expected %s\n",
|
||||||
|
mimetype, actual, expected);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_icons (void)
|
||||||
|
{
|
||||||
|
test_one_icon ("application/x-font-ttx", "font-x-generic");
|
||||||
|
test_one_icon ("application/mathematica", "x-office-document");
|
||||||
|
test_one_icon ("text/plain", NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -126,6 +178,8 @@ main (int argc, char *argv[])
|
|||||||
test_glob_type ();
|
test_glob_type ();
|
||||||
test_aliasing ();
|
test_aliasing ();
|
||||||
test_subclassing ();
|
test_subclassing ();
|
||||||
|
test_matches ();
|
||||||
|
test_icons ();
|
||||||
|
|
||||||
for (i = 1; i < argc; i++)
|
for (i = 1; i < argc; i++)
|
||||||
{
|
{
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#include "xdgmimeglob.h"
|
#include "xdgmimeglob.h"
|
||||||
#include "xdgmimemagic.h"
|
#include "xdgmimemagic.h"
|
||||||
#include "xdgmimealias.h"
|
#include "xdgmimealias.h"
|
||||||
|
#include "xdgmimeicon.h"
|
||||||
#include "xdgmimeparent.h"
|
#include "xdgmimeparent.h"
|
||||||
#include "xdgmimecache.h"
|
#include "xdgmimecache.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -56,6 +57,8 @@ static XdgAliasList *alias_list = NULL;
|
|||||||
static XdgParentList *parent_list = NULL;
|
static XdgParentList *parent_list = NULL;
|
||||||
static XdgDirTimeList *dir_time_list = NULL;
|
static XdgDirTimeList *dir_time_list = NULL;
|
||||||
static XdgCallbackList *callback_list = NULL;
|
static XdgCallbackList *callback_list = NULL;
|
||||||
|
static XdgIconList *icon_list = NULL;
|
||||||
|
static XdgIconList *generic_icon_list = NULL;
|
||||||
|
|
||||||
XdgMimeCache **_caches = NULL;
|
XdgMimeCache **_caches = NULL;
|
||||||
static int n_caches = 0;
|
static int n_caches = 0;
|
||||||
@ -155,6 +158,16 @@ xdg_mime_init_from_directory (const char *directory)
|
|||||||
}
|
}
|
||||||
free (file_name);
|
free (file_name);
|
||||||
|
|
||||||
|
file_name = malloc (strlen (directory) + strlen ("/mime/globs2") + 1);
|
||||||
|
strcpy (file_name, directory); strcat (file_name, "/mime/globs2");
|
||||||
|
if (stat (file_name, &st) == 0)
|
||||||
|
{
|
||||||
|
_xdg_mime_glob_read_from_file (global_hash, file_name);
|
||||||
|
xdg_dir_time_list_add (file_name, st.st_mtime);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
free (file_name);
|
||||||
file_name = malloc (strlen (directory) + strlen ("/mime/globs") + 1);
|
file_name = malloc (strlen (directory) + strlen ("/mime/globs") + 1);
|
||||||
strcpy (file_name, directory); strcat (file_name, "/mime/globs");
|
strcpy (file_name, directory); strcat (file_name, "/mime/globs");
|
||||||
if (stat (file_name, &st) == 0)
|
if (stat (file_name, &st) == 0)
|
||||||
@ -166,6 +179,7 @@ xdg_mime_init_from_directory (const char *directory)
|
|||||||
{
|
{
|
||||||
free (file_name);
|
free (file_name);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
file_name = malloc (strlen (directory) + strlen ("/mime/magic") + 1);
|
file_name = malloc (strlen (directory) + strlen ("/mime/magic") + 1);
|
||||||
strcpy (file_name, directory); strcat (file_name, "/mime/magic");
|
strcpy (file_name, directory); strcat (file_name, "/mime/magic");
|
||||||
@ -189,6 +203,16 @@ xdg_mime_init_from_directory (const char *directory)
|
|||||||
_xdg_mime_parent_read_from_file (parent_list, file_name);
|
_xdg_mime_parent_read_from_file (parent_list, file_name);
|
||||||
free (file_name);
|
free (file_name);
|
||||||
|
|
||||||
|
file_name = malloc (strlen (directory) + strlen ("/mime/icons") + 1);
|
||||||
|
strcpy (file_name, directory); strcat (file_name, "/mime/icons");
|
||||||
|
_xdg_mime_icon_read_from_file (icon_list, file_name);
|
||||||
|
free (file_name);
|
||||||
|
|
||||||
|
file_name = malloc (strlen (directory) + strlen ("/mime/generic-icons") + 1);
|
||||||
|
strcpy (file_name, directory); strcat (file_name, "/mime/generic-icons");
|
||||||
|
_xdg_mime_icon_read_from_file (generic_icon_list, file_name);
|
||||||
|
free (file_name);
|
||||||
|
|
||||||
return FALSE; /* Keep processing */
|
return FALSE; /* Keep processing */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -423,6 +447,8 @@ xdg_mime_init (void)
|
|||||||
global_magic = _xdg_mime_magic_new ();
|
global_magic = _xdg_mime_magic_new ();
|
||||||
alias_list = _xdg_mime_alias_list_new ();
|
alias_list = _xdg_mime_alias_list_new ();
|
||||||
parent_list = _xdg_mime_parent_list_new ();
|
parent_list = _xdg_mime_parent_list_new ();
|
||||||
|
icon_list = _xdg_mime_icon_list_new ();
|
||||||
|
generic_icon_list = _xdg_mime_icon_list_new ();
|
||||||
|
|
||||||
xdg_run_command_on_dirs ((XdgDirectoryFunc) xdg_mime_init_from_directory,
|
xdg_run_command_on_dirs ((XdgDirectoryFunc) xdg_mime_init_from_directory,
|
||||||
NULL);
|
NULL);
|
||||||
@ -796,10 +822,18 @@ xdg_mime_get_mime_parents (const char *mime)
|
|||||||
void
|
void
|
||||||
xdg_mime_dump (void)
|
xdg_mime_dump (void)
|
||||||
{
|
{
|
||||||
|
xdg_mime_init();
|
||||||
|
|
||||||
printf ("*** ALIASES ***\n\n");
|
printf ("*** ALIASES ***\n\n");
|
||||||
_xdg_mime_alias_list_dump (alias_list);
|
_xdg_mime_alias_list_dump (alias_list);
|
||||||
printf ("\n*** PARENTS ***\n\n");
|
printf ("\n*** PARENTS ***\n\n");
|
||||||
_xdg_mime_parent_list_dump (parent_list);
|
_xdg_mime_parent_list_dump (parent_list);
|
||||||
|
printf ("\n*** CACHE ***\n\n");
|
||||||
|
_xdg_glob_hash_dump (global_hash);
|
||||||
|
printf ("\n*** GLOBS ***\n\n");
|
||||||
|
_xdg_glob_hash_dump (global_hash);
|
||||||
|
printf ("\n*** GLOBS REVERSE TREE ***\n\n");
|
||||||
|
_xdg_mime_cache_glob_dump ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -853,3 +887,32 @@ xdg_mime_remove_callback (int callback_id)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
xdg_mime_get_icon (const char *mime)
|
||||||
|
{
|
||||||
|
const char *icon;
|
||||||
|
|
||||||
|
xdg_mime_init ();
|
||||||
|
|
||||||
|
if (_caches)
|
||||||
|
return _xdg_mime_cache_get_icon (mime);
|
||||||
|
|
||||||
|
icon = _xdg_mime_icon_list_lookup (icon_list, mime);
|
||||||
|
|
||||||
|
if (!icon)
|
||||||
|
icon = xdg_mime_get_generic_icon (mime);
|
||||||
|
|
||||||
|
return icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
xdg_mime_get_generic_icon (const char *mime)
|
||||||
|
{
|
||||||
|
xdg_mime_init ();
|
||||||
|
|
||||||
|
if (_caches)
|
||||||
|
return _xdg_mime_cache_get_generic_icon (mime);
|
||||||
|
|
||||||
|
return _xdg_mime_icon_list_lookup (generic_icon_list, mime);
|
||||||
|
}
|
||||||
|
@ -40,6 +40,10 @@ extern "C" {
|
|||||||
#define XDG_ENTRY(func) _XDG_ENTRY2(XDG_PREFIX,func)
|
#define XDG_ENTRY(func) _XDG_ENTRY2(XDG_PREFIX,func)
|
||||||
#define _XDG_ENTRY2(prefix,func) _XDG_ENTRY3(prefix,func)
|
#define _XDG_ENTRY2(prefix,func) _XDG_ENTRY3(prefix,func)
|
||||||
#define _XDG_ENTRY3(prefix,func) prefix##_##func
|
#define _XDG_ENTRY3(prefix,func) prefix##_##func
|
||||||
|
|
||||||
|
#define XDG_RESERVED_ENTRY(func) _XDG_RESERVED_ENTRY2(XDG_PREFIX,func)
|
||||||
|
#define _XDG_RESERVED_ENTRY2(prefix,func) _XDG_RESERVED_ENTRY3(prefix,func)
|
||||||
|
#define _XDG_RESERVED_ENTRY3(prefix,func) _##prefix##_##func
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef void (*XdgMimeCallback) (void *user_data);
|
typedef void (*XdgMimeCallback) (void *user_data);
|
||||||
@ -53,20 +57,23 @@ typedef void (*XdgMimeDestroy) (void *user_data);
|
|||||||
#define xdg_mime_get_mime_types_from_file_name XDG_ENTRY(get_mime_types_from_file_name)
|
#define xdg_mime_get_mime_types_from_file_name XDG_ENTRY(get_mime_types_from_file_name)
|
||||||
#define xdg_mime_is_valid_mime_type XDG_ENTRY(is_valid_mime_type)
|
#define xdg_mime_is_valid_mime_type XDG_ENTRY(is_valid_mime_type)
|
||||||
#define xdg_mime_mime_type_equal XDG_ENTRY(mime_type_equal)
|
#define xdg_mime_mime_type_equal XDG_ENTRY(mime_type_equal)
|
||||||
#define _xdg_mime_mime_type_equal XDG_ENTRY(mime_type_equal_p)
|
|
||||||
#define xdg_mime_media_type_equal XDG_ENTRY(media_type_equal)
|
#define xdg_mime_media_type_equal XDG_ENTRY(media_type_equal)
|
||||||
#define xdg_mime_mime_type_subclass XDG_ENTRY(mime_type_subclass)
|
#define xdg_mime_mime_type_subclass XDG_ENTRY(mime_type_subclass)
|
||||||
#define _xdg_mime_mime_type_subclass XDG_ENTRY(mime_type_subclass_p)
|
|
||||||
#define xdg_mime_get_mime_parents XDG_ENTRY(get_mime_parents)
|
#define xdg_mime_get_mime_parents XDG_ENTRY(get_mime_parents)
|
||||||
#define xdg_mime_list_mime_parents XDG_ENTRY(list_mime_parents)
|
#define xdg_mime_list_mime_parents XDG_ENTRY(list_mime_parents)
|
||||||
#define xdg_mime_unalias_mime_type XDG_ENTRY(unalias_mime_type)
|
#define xdg_mime_unalias_mime_type XDG_ENTRY(unalias_mime_type)
|
||||||
#define _xdg_mime_unalias_mime_type XDG_ENTRY(unalias_mime_type_p)
|
|
||||||
#define xdg_mime_get_max_buffer_extents XDG_ENTRY(get_max_buffer_extents)
|
#define xdg_mime_get_max_buffer_extents XDG_ENTRY(get_max_buffer_extents)
|
||||||
#define xdg_mime_shutdown XDG_ENTRY(shutdown)
|
#define xdg_mime_shutdown XDG_ENTRY(shutdown)
|
||||||
#define xdg_mime_dump XDG_ENTRY(dump)
|
#define xdg_mime_dump XDG_ENTRY(dump)
|
||||||
#define xdg_mime_register_reload_callback XDG_ENTRY(register_reload_callback)
|
#define xdg_mime_register_reload_callback XDG_ENTRY(register_reload_callback)
|
||||||
#define xdg_mime_remove_callback XDG_ENTRY(remove_callback)
|
#define xdg_mime_remove_callback XDG_ENTRY(remove_callback)
|
||||||
#define xdg_mime_type_unknown XDG_ENTRY(type_unknown)
|
#define xdg_mime_type_unknown XDG_ENTRY(type_unknown)
|
||||||
|
#define xdg_mime_get_icon XDG_ENTRY(get_icon)
|
||||||
|
#define xdg_mime_get_generic_icon XDG_ENTRY(get_generic_icon)
|
||||||
|
|
||||||
|
#define _xdg_mime_mime_type_equal XDG_RESERVED_ENTRY(mime_type_equal)
|
||||||
|
#define _xdg_mime_mime_type_subclass XDG_RESERVED_ENTRY(mime_type_subclass)
|
||||||
|
#define _xdg_mime_unalias_mime_type XDG_RESERVED_ENTRY(unalias_mime_type)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern const char xdg_mime_type_unknown[];
|
extern const char xdg_mime_type_unknown[];
|
||||||
@ -96,6 +103,8 @@ int xdg_mime_mime_type_subclass (const char *mime_a,
|
|||||||
const char **xdg_mime_get_mime_parents (const char *mime);
|
const char **xdg_mime_get_mime_parents (const char *mime);
|
||||||
char ** xdg_mime_list_mime_parents (const char *mime);
|
char ** xdg_mime_list_mime_parents (const char *mime);
|
||||||
const char *xdg_mime_unalias_mime_type (const char *mime);
|
const char *xdg_mime_unalias_mime_type (const char *mime);
|
||||||
|
const char *xdg_mime_get_icon (const char *mime);
|
||||||
|
const char *xdg_mime_get_generic_icon (const char *mime);
|
||||||
int xdg_mime_get_max_buffer_extents (void);
|
int xdg_mime_get_max_buffer_extents (void);
|
||||||
void xdg_mime_shutdown (void);
|
void xdg_mime_shutdown (void);
|
||||||
void xdg_mime_dump (void);
|
void xdg_mime_dump (void);
|
||||||
|
@ -33,11 +33,11 @@
|
|||||||
typedef struct XdgAliasList XdgAliasList;
|
typedef struct XdgAliasList XdgAliasList;
|
||||||
|
|
||||||
#ifdef XDG_PREFIX
|
#ifdef XDG_PREFIX
|
||||||
#define _xdg_mime_alias_read_from_file XDG_ENTRY(alias_read_from_file)
|
#define _xdg_mime_alias_read_from_file XDG_RESERVED_ENTRY(alias_read_from_file)
|
||||||
#define _xdg_mime_alias_list_new XDG_ENTRY(alias_list_new)
|
#define _xdg_mime_alias_list_new XDG_RESERVED_ENTRY(alias_list_new)
|
||||||
#define _xdg_mime_alias_list_free XDG_ENTRY(alias_list_free)
|
#define _xdg_mime_alias_list_free XDG_RESERVED_ENTRY(alias_list_free)
|
||||||
#define _xdg_mime_alias_list_lookup XDG_ENTRY(alias_list_lookup)
|
#define _xdg_mime_alias_list_lookup XDG_RESERVED_ENTRY(alias_list_lookup)
|
||||||
#define _xdg_mime_alias_list_dump XDG_ENTRY(alias_list_dump)
|
#define _xdg_mime_alias_list_dump XDG_RESERVED_ENTRY(alias_list_dump)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void _xdg_mime_alias_read_from_file (XdgAliasList *list,
|
void _xdg_mime_alias_read_from_file (XdgAliasList *list,
|
||||||
|
@ -41,6 +41,8 @@
|
|||||||
|
|
||||||
#ifdef HAVE_MMAP
|
#ifdef HAVE_MMAP
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
#else
|
||||||
|
#warning Building xdgmime without MMAP support. Binary "mime.info" cache files will not be used.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
@ -70,7 +72,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MAJOR_VERSION 1
|
#define MAJOR_VERSION 1
|
||||||
#define MINOR_VERSION 0
|
#define MINOR_VERSION 1
|
||||||
|
|
||||||
struct _XdgMimeCache
|
struct _XdgMimeCache
|
||||||
{
|
{
|
||||||
@ -344,6 +346,11 @@ cache_alias_lookup (const char *alias)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char *mime;
|
||||||
|
int weight;
|
||||||
|
} MimeWeight;
|
||||||
|
|
||||||
static int
|
static int
|
||||||
cache_glob_lookup_literal (const char *file_name,
|
cache_glob_lookup_literal (const char *file_name,
|
||||||
const char *mime_types[],
|
const char *mime_types[],
|
||||||
@ -365,7 +372,7 @@ cache_glob_lookup_literal (const char *file_name,
|
|||||||
{
|
{
|
||||||
mid = (min + max) / 2;
|
mid = (min + max) / 2;
|
||||||
|
|
||||||
offset = GET_UINT32 (cache->buffer, list_offset + 4 + 8 * mid);
|
offset = GET_UINT32 (cache->buffer, list_offset + 4 + 12 * mid);
|
||||||
ptr = cache->buffer + offset;
|
ptr = cache->buffer + offset;
|
||||||
cmp = strcmp (ptr, file_name);
|
cmp = strcmp (ptr, file_name);
|
||||||
|
|
||||||
@ -375,7 +382,7 @@ cache_glob_lookup_literal (const char *file_name,
|
|||||||
max = mid - 1;
|
max = mid - 1;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
offset = GET_UINT32 (cache->buffer, list_offset + 4 + 8 * mid + 4);
|
offset = GET_UINT32 (cache->buffer, list_offset + 4 + 12 * mid + 4);
|
||||||
mime_types[0] = (const char *)(cache->buffer + offset);
|
mime_types[0] = (const char *)(cache->buffer + offset);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@ -388,7 +395,7 @@ cache_glob_lookup_literal (const char *file_name,
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
cache_glob_lookup_fnmatch (const char *file_name,
|
cache_glob_lookup_fnmatch (const char *file_name,
|
||||||
const char *mime_types[],
|
MimeWeight mime_types[],
|
||||||
int n_mime_types)
|
int n_mime_types)
|
||||||
{
|
{
|
||||||
const char *mime_type;
|
const char *mime_type;
|
||||||
@ -406,14 +413,19 @@ cache_glob_lookup_fnmatch (const char *file_name,
|
|||||||
|
|
||||||
for (j = 0; j < n_entries && n < n_mime_types; j++)
|
for (j = 0; j < n_entries && n < n_mime_types; j++)
|
||||||
{
|
{
|
||||||
xdg_uint32_t offset = GET_UINT32 (cache->buffer, list_offset + 4 + 8 * j);
|
xdg_uint32_t offset = GET_UINT32 (cache->buffer, list_offset + 4 + 12 * j);
|
||||||
xdg_uint32_t mimetype_offset = GET_UINT32 (cache->buffer, list_offset + 4 + 8 * j + 4);
|
xdg_uint32_t mimetype_offset = GET_UINT32 (cache->buffer, list_offset + 4 + 12 * j + 4);
|
||||||
|
int weight = GET_UINT32 (cache->buffer, list_offset + 4 + 12 * j + 8);
|
||||||
ptr = cache->buffer + offset;
|
ptr = cache->buffer + offset;
|
||||||
mime_type = cache->buffer + mimetype_offset;
|
mime_type = cache->buffer + mimetype_offset;
|
||||||
|
|
||||||
/* FIXME: Not UTF-8 safe */
|
/* FIXME: Not UTF-8 safe */
|
||||||
if (fnmatch (ptr, file_name, 0) == 0)
|
if (fnmatch (ptr, file_name, 0) == 0)
|
||||||
mime_types[n++] = mime_type;
|
{
|
||||||
|
mime_types[n].mime = mime_type;
|
||||||
|
mime_types[n].weight = weight;
|
||||||
|
n++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (n > 0)
|
if (n > 0)
|
||||||
@ -427,9 +439,10 @@ static int
|
|||||||
cache_glob_node_lookup_suffix (XdgMimeCache *cache,
|
cache_glob_node_lookup_suffix (XdgMimeCache *cache,
|
||||||
xdg_uint32_t n_entries,
|
xdg_uint32_t n_entries,
|
||||||
xdg_uint32_t offset,
|
xdg_uint32_t offset,
|
||||||
const char *suffix,
|
xdg_unichar_t *file_name,
|
||||||
|
int len,
|
||||||
int ignore_case,
|
int ignore_case,
|
||||||
const char *mime_types[],
|
MimeWeight mime_types[],
|
||||||
int n_mime_types)
|
int n_mime_types)
|
||||||
{
|
{
|
||||||
xdg_unichar_t character;
|
xdg_unichar_t character;
|
||||||
@ -437,72 +450,71 @@ cache_glob_node_lookup_suffix (XdgMimeCache *cache,
|
|||||||
xdg_uint32_t mimetype_offset;
|
xdg_uint32_t mimetype_offset;
|
||||||
xdg_uint32_t n_children;
|
xdg_uint32_t n_children;
|
||||||
xdg_uint32_t child_offset;
|
xdg_uint32_t child_offset;
|
||||||
|
int weight;
|
||||||
|
|
||||||
int min, max, mid, n, i;
|
int min, max, mid, n, i;
|
||||||
|
|
||||||
character = _xdg_utf8_to_ucs4 (suffix);
|
character = file_name[len - 1];
|
||||||
if (ignore_case)
|
if (ignore_case)
|
||||||
character = _xdg_ucs4_to_lower (character);
|
character = _xdg_ucs4_to_lower (character);
|
||||||
|
|
||||||
|
assert (character != 0);
|
||||||
|
|
||||||
min = 0;
|
min = 0;
|
||||||
max = n_entries - 1;
|
max = n_entries - 1;
|
||||||
while (max >= min)
|
while (max >= min)
|
||||||
{
|
{
|
||||||
mid = (min + max) / 2;
|
mid = (min + max) / 2;
|
||||||
|
match_char = GET_UINT32 (cache->buffer, offset + 12 * mid);
|
||||||
match_char = GET_UINT32 (cache->buffer, offset + 16 * mid);
|
|
||||||
|
|
||||||
if (match_char < character)
|
if (match_char < character)
|
||||||
min = mid + 1;
|
min = mid + 1;
|
||||||
else if (match_char > character)
|
else if (match_char > character)
|
||||||
max = mid - 1;
|
max = mid - 1;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
suffix = _xdg_utf8_next_char (suffix);
|
len--;
|
||||||
if (*suffix == '\0')
|
|
||||||
{
|
|
||||||
mimetype_offset = GET_UINT32 (cache->buffer, offset + 16 * mid + 4);
|
|
||||||
n = 0;
|
n = 0;
|
||||||
if (mimetype_offset)
|
n_children = GET_UINT32 (cache->buffer, offset + 12 * mid + 4);
|
||||||
mime_types[n++] = cache->buffer + mimetype_offset;
|
child_offset = GET_UINT32 (cache->buffer, offset + 12 * mid + 8);
|
||||||
|
|
||||||
n_children = GET_UINT32 (cache->buffer, offset + 16 * mid + 8);
|
if (len > 0)
|
||||||
child_offset = GET_UINT32 (cache->buffer, offset + 16 * mid + 12);
|
|
||||||
i = 0;
|
|
||||||
while (n < n_mime_types && i < n_children)
|
|
||||||
{
|
{
|
||||||
match_char = GET_UINT32 (cache->buffer, child_offset + 16 * i);
|
n = cache_glob_node_lookup_suffix (cache,
|
||||||
mimetype_offset = GET_UINT32 (cache->buffer, offset + 16 * i + 4);
|
|
||||||
if (match_char != 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
mime_types[n++] = cache->buffer + mimetype_offset;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
n_children = GET_UINT32 (cache->buffer, offset + 16 * mid + 8);
|
|
||||||
child_offset = GET_UINT32 (cache->buffer, offset + 16 * mid + 12);
|
|
||||||
|
|
||||||
return cache_glob_node_lookup_suffix (cache,
|
|
||||||
n_children, child_offset,
|
n_children, child_offset,
|
||||||
suffix, ignore_case,
|
file_name, len,
|
||||||
|
ignore_case,
|
||||||
mime_types,
|
mime_types,
|
||||||
n_mime_types);
|
n_mime_types);
|
||||||
}
|
}
|
||||||
}
|
if (n == 0)
|
||||||
}
|
{
|
||||||
|
i = 0;
|
||||||
|
while (n < n_mime_types && i < n_children)
|
||||||
|
{
|
||||||
|
match_char = GET_UINT32 (cache->buffer, child_offset + 12 * i);
|
||||||
|
if (match_char != 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
mimetype_offset = GET_UINT32 (cache->buffer, child_offset + 12 * i + 4);
|
||||||
|
weight = GET_UINT32 (cache->buffer, child_offset + 12 * i + 8);
|
||||||
|
|
||||||
|
mime_types[n].mime = cache->buffer + mimetype_offset;
|
||||||
|
mime_types[n].weight = weight;
|
||||||
|
n++;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
cache_glob_lookup_suffix (const char *suffix,
|
cache_glob_lookup_suffix (xdg_unichar_t *file_name,
|
||||||
|
int len,
|
||||||
int ignore_case,
|
int ignore_case,
|
||||||
const char *mime_types[],
|
MimeWeight mime_types[],
|
||||||
int n_mime_types)
|
int n_mime_types)
|
||||||
{
|
{
|
||||||
int i, n;
|
int i, n;
|
||||||
@ -517,7 +529,8 @@ cache_glob_lookup_suffix (const char *suffix,
|
|||||||
|
|
||||||
n = cache_glob_node_lookup_suffix (cache,
|
n = cache_glob_node_lookup_suffix (cache,
|
||||||
n_entries, offset,
|
n_entries, offset,
|
||||||
suffix, ignore_case,
|
file_name, len,
|
||||||
|
ignore_case,
|
||||||
mime_types,
|
mime_types,
|
||||||
n_mime_types);
|
n_mime_types);
|
||||||
if (n > 0)
|
if (n > 0)
|
||||||
@ -527,41 +540,12 @@ cache_glob_lookup_suffix (const char *suffix,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static int compare_mime_weight (const void *a, const void *b)
|
||||||
find_stopchars (char *stopchars)
|
|
||||||
{
|
{
|
||||||
int i, j, k, l;
|
const MimeWeight *aa = (const MimeWeight *)a;
|
||||||
|
const MimeWeight *bb = (const MimeWeight *)b;
|
||||||
|
|
||||||
k = 0;
|
return aa->weight - bb->weight;
|
||||||
for (i = 0; _caches[i]; i++)
|
|
||||||
{
|
|
||||||
XdgMimeCache *cache = _caches[i];
|
|
||||||
|
|
||||||
xdg_uint32_t list_offset = GET_UINT32 (cache->buffer, 16);
|
|
||||||
xdg_uint32_t n_entries = GET_UINT32 (cache->buffer, list_offset);
|
|
||||||
xdg_uint32_t offset = GET_UINT32 (cache->buffer, list_offset + 4);
|
|
||||||
|
|
||||||
for (j = 0; j < n_entries; j++)
|
|
||||||
{
|
|
||||||
xdg_uint32_t match_char = GET_UINT32 (cache->buffer, offset);
|
|
||||||
|
|
||||||
if (match_char < 128)
|
|
||||||
{
|
|
||||||
for (l = 0; l < k; l++)
|
|
||||||
if (stopchars[l] == match_char)
|
|
||||||
break;
|
|
||||||
if (l == k)
|
|
||||||
{
|
|
||||||
stopchars[k] = (char) match_char;
|
|
||||||
k++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
offset += 16;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
stopchars[k] = '\0';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -569,36 +553,40 @@ cache_glob_lookup_file_name (const char *file_name,
|
|||||||
const char *mime_types[],
|
const char *mime_types[],
|
||||||
int n_mime_types)
|
int n_mime_types)
|
||||||
{
|
{
|
||||||
const char *ptr;
|
|
||||||
char stopchars[128];
|
|
||||||
int n;
|
int n;
|
||||||
|
MimeWeight mimes[10];
|
||||||
|
int n_mimes = 10;
|
||||||
|
int i;
|
||||||
|
xdg_unichar_t *ucs4;
|
||||||
|
int len;
|
||||||
|
|
||||||
assert (file_name != NULL);
|
assert (file_name != NULL && n_mime_types > 0);
|
||||||
|
|
||||||
/* First, check the literals */
|
/* First, check the literals */
|
||||||
n = cache_glob_lookup_literal (file_name, mime_types, n_mime_types);
|
n = cache_glob_lookup_literal (file_name, mime_types, n_mime_types);
|
||||||
if (n > 0)
|
if (n > 0)
|
||||||
return n;
|
return n;
|
||||||
|
|
||||||
find_stopchars (stopchars);
|
ucs4 = _xdg_convert_to_ucs4 (file_name, &len);
|
||||||
|
n = cache_glob_lookup_suffix (ucs4, len, FALSE, mimes, n_mimes);
|
||||||
|
|
||||||
/* Next, check suffixes */
|
if (n == 0)
|
||||||
ptr = strpbrk (file_name, stopchars);
|
n = cache_glob_lookup_suffix (ucs4, len, TRUE, mimes, n_mimes);
|
||||||
while (ptr)
|
free(ucs4);
|
||||||
{
|
|
||||||
n = cache_glob_lookup_suffix (ptr, FALSE, mime_types, n_mime_types);
|
|
||||||
if (n > 0)
|
|
||||||
return n;
|
|
||||||
|
|
||||||
n = cache_glob_lookup_suffix (ptr, TRUE, mime_types, n_mime_types);
|
|
||||||
if (n > 0)
|
|
||||||
return n;
|
|
||||||
|
|
||||||
ptr = strpbrk (ptr + 1, stopchars);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Last, try fnmatch */
|
/* Last, try fnmatch */
|
||||||
return cache_glob_lookup_fnmatch (file_name, mime_types, n_mime_types);
|
if (n == 0)
|
||||||
|
n = cache_glob_lookup_fnmatch (file_name, mimes, n_mimes);
|
||||||
|
|
||||||
|
qsort (mimes, n, sizeof (MimeWeight), compare_mime_weight);
|
||||||
|
|
||||||
|
if (n_mime_types < n)
|
||||||
|
n = n_mime_types;
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
mime_types[i] = mimes[i].mime;
|
||||||
|
|
||||||
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -677,7 +665,7 @@ _xdg_mime_cache_get_mime_type_for_file (const char *file_name,
|
|||||||
struct stat *statbuf)
|
struct stat *statbuf)
|
||||||
{
|
{
|
||||||
const char *mime_type;
|
const char *mime_type;
|
||||||
const char *mime_types[2];
|
const char *mime_types[10];
|
||||||
FILE *file;
|
FILE *file;
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
int max_extent;
|
int max_extent;
|
||||||
@ -693,7 +681,7 @@ _xdg_mime_cache_get_mime_type_for_file (const char *file_name,
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
base_name = _xdg_get_base_name (file_name);
|
base_name = _xdg_get_base_name (file_name);
|
||||||
n = cache_glob_lookup_file_name (base_name, mime_types, 2);
|
n = cache_glob_lookup_file_name (base_name, mime_types, 10);
|
||||||
|
|
||||||
if (n == 1)
|
if (n == 1)
|
||||||
return mime_types[0];
|
return mime_types[0];
|
||||||
@ -918,3 +906,107 @@ _xdg_mime_cache_list_mime_parents (const char *mime)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
cache_lookup_icon (const char *mime, int header)
|
||||||
|
{
|
||||||
|
const char *ptr;
|
||||||
|
int i, min, max, mid, cmp;
|
||||||
|
|
||||||
|
for (i = 0; _caches[i]; i++)
|
||||||
|
{
|
||||||
|
XdgMimeCache *cache = _caches[i];
|
||||||
|
xdg_uint32_t list_offset = GET_UINT32 (cache->buffer, header);
|
||||||
|
xdg_uint32_t n_entries = GET_UINT32 (cache->buffer, list_offset);
|
||||||
|
xdg_uint32_t offset;
|
||||||
|
|
||||||
|
min = 0;
|
||||||
|
max = n_entries - 1;
|
||||||
|
while (max >= min)
|
||||||
|
{
|
||||||
|
mid = (min + max) / 2;
|
||||||
|
|
||||||
|
offset = GET_UINT32 (cache->buffer, list_offset + 4 + 8 * mid);
|
||||||
|
ptr = cache->buffer + offset;
|
||||||
|
cmp = strcmp (ptr, mime);
|
||||||
|
|
||||||
|
if (cmp < 0)
|
||||||
|
min = mid + 1;
|
||||||
|
else if (cmp > 0)
|
||||||
|
max = mid - 1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
offset = GET_UINT32 (cache->buffer, list_offset + 4 + 8 * mid + 4);
|
||||||
|
return cache->buffer + offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
_xdg_mime_cache_get_generic_icon (const char *mime)
|
||||||
|
{
|
||||||
|
return cache_lookup_icon (mime, 36);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
_xdg_mime_cache_get_icon (const char *mime)
|
||||||
|
{
|
||||||
|
const char *icon;
|
||||||
|
|
||||||
|
icon = cache_lookup_icon (mime, 32);
|
||||||
|
|
||||||
|
if (icon == NULL)
|
||||||
|
icon = _xdg_mime_cache_get_generic_icon (mime);
|
||||||
|
|
||||||
|
return icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dump_glob_node (XdgMimeCache *cache,
|
||||||
|
xdg_uint32_t offset,
|
||||||
|
int depth)
|
||||||
|
{
|
||||||
|
xdg_unichar_t character;
|
||||||
|
xdg_uint32_t mime_offset;
|
||||||
|
xdg_uint32_t n_children;
|
||||||
|
xdg_uint32_t child_offset;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
character = GET_UINT32 (cache->buffer, offset);
|
||||||
|
mime_offset = GET_UINT32 (cache->buffer, offset + 4);
|
||||||
|
n_children = GET_UINT32 (cache->buffer, offset + 8);
|
||||||
|
child_offset = GET_UINT32 (cache->buffer, offset + 12);
|
||||||
|
for (i = 0; i < depth; i++)
|
||||||
|
printf (" ");
|
||||||
|
printf ("%c", character);
|
||||||
|
if (mime_offset)
|
||||||
|
printf (" - %s", cache->buffer + mime_offset);
|
||||||
|
printf ("\n");
|
||||||
|
if (child_offset)
|
||||||
|
{
|
||||||
|
for (i = 0; i < n_children; i++)
|
||||||
|
dump_glob_node (cache, child_offset + 20 * i, depth + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_xdg_mime_cache_glob_dump (void)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
for (i = 0; _caches[i]; i++)
|
||||||
|
{
|
||||||
|
XdgMimeCache *cache = _caches[i];
|
||||||
|
xdg_uint32_t list_offset;
|
||||||
|
xdg_uint32_t n_entries;
|
||||||
|
xdg_uint32_t offset;
|
||||||
|
list_offset = GET_UINT32 (cache->buffer, 16);
|
||||||
|
n_entries = GET_UINT32 (cache->buffer, list_offset);
|
||||||
|
offset = GET_UINT32 (cache->buffer, list_offset + 4);
|
||||||
|
for (j = 0; j < n_entries; j++)
|
||||||
|
dump_glob_node (cache, offset + 20 * j, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -32,18 +32,20 @@
|
|||||||
typedef struct _XdgMimeCache XdgMimeCache;
|
typedef struct _XdgMimeCache XdgMimeCache;
|
||||||
|
|
||||||
#ifdef XDG_PREFIX
|
#ifdef XDG_PREFIX
|
||||||
#define _xdg_mime_cache_new_from_file XDG_ENTRY(cache_new_from_file)
|
#define _xdg_mime_cache_new_from_file XDG_RESERVED_ENTRY(cache_new_from_file)
|
||||||
#define _xdg_mime_cache_ref XDG_ENTRY(cache_ref)
|
#define _xdg_mime_cache_ref XDG_RESERVED_ENTRY(cache_ref)
|
||||||
#define _xdg_mime_cache_unref XDG_ENTRY(cache_unref)
|
#define _xdg_mime_cache_unref XDG_RESERVED_ENTRY(cache_unref)
|
||||||
#define _xdg_mime_cache_get_max_buffer_extents XDG_ENTRY(cache_get_max_buffer_extents)
|
#define _xdg_mime_cache_get_max_buffer_extents XDG_RESERVED_ENTRY(cache_get_max_buffer_extents)
|
||||||
#define _xdg_mime_cache_get_mime_type_for_data XDG_ENTRY(cache_get_mime_type_for_data)
|
#define _xdg_mime_cache_get_mime_type_for_data XDG_RESERVED_ENTRY(cache_get_mime_type_for_data)
|
||||||
#define _xdg_mime_cache_get_mime_type_for_file XDG_ENTRY(cache_get_mime_type_for_file)
|
#define _xdg_mime_cache_get_mime_type_for_file XDG_RESERVED_ENTRY(cache_get_mime_type_for_file)
|
||||||
#define _xdg_mime_cache_get_mime_type_from_file_name XDG_ENTRY(cache_get_mime_type_from_file_name)
|
#define _xdg_mime_cache_get_mime_type_from_file_name XDG_RESERVED_ENTRY(cache_get_mime_type_from_file_name)
|
||||||
#define _xdg_mime_cache_get_mime_types_from_file_name XDG_ENTRY(cache_get_mime_types_from_file_name)
|
#define _xdg_mime_cache_get_mime_types_from_file_name XDG_RESERVED_ENTRY(cache_get_mime_types_from_file_name)
|
||||||
#define _xdg_mime_cache_list_mime_parents XDG_ENTRY(cache_list_mime_parents)
|
#define _xdg_mime_cache_list_mime_parents XDG_RESERVED_ENTRY(cache_list_mime_parents)
|
||||||
#define _xdg_mime_cache_mime_type_subclass XDG_ENTRY(cache_mime_type_subclass)
|
#define _xdg_mime_cache_mime_type_subclass XDG_RESERVED_ENTRY(cache_mime_type_subclass)
|
||||||
#define _xdg_mime_cache_unalias_mime_type XDG_ENTRY(cache_unalias_mime_type)
|
#define _xdg_mime_cache_unalias_mime_type XDG_RESERVED_ENTRY(cache_unalias_mime_type)
|
||||||
|
#define _xdg_mime_cache_get_icon XDG_RESERVED_ENTRY(cache_get_icon)
|
||||||
|
#define _xdg_mime_cache_get_generic_icon XDG_RESERVED_ENTRY(cache_get_generic_icon)
|
||||||
|
#define _xdg_mime_cache_glob_dump XDG_RESERVED_ENTRY(cache_glob_dump)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern XdgMimeCache **_caches;
|
extern XdgMimeCache **_caches;
|
||||||
@ -72,5 +74,8 @@ int _xdg_mime_cache_mime_type_subclass (const char *mime_a,
|
|||||||
char **_xdg_mime_cache_list_mime_parents (const char *mime);
|
char **_xdg_mime_cache_list_mime_parents (const char *mime);
|
||||||
const char *_xdg_mime_cache_unalias_mime_type (const char *mime);
|
const char *_xdg_mime_cache_unalias_mime_type (const char *mime);
|
||||||
int _xdg_mime_cache_get_max_buffer_extents (void);
|
int _xdg_mime_cache_get_max_buffer_extents (void);
|
||||||
|
const char *_xdg_mime_cache_get_icon (const char *mime);
|
||||||
|
const char *_xdg_mime_cache_get_generic_icon (const char *mime);
|
||||||
|
void _xdg_mime_cache_glob_dump (void);
|
||||||
|
|
||||||
#endif /* __XDG_MIME_CACHE_H__ */
|
#endif /* __XDG_MIME_CACHE_H__ */
|
||||||
|
@ -52,6 +52,7 @@ struct XdgGlobHashNode
|
|||||||
{
|
{
|
||||||
xdg_unichar_t character;
|
xdg_unichar_t character;
|
||||||
const char *mime_type;
|
const char *mime_type;
|
||||||
|
int weight;
|
||||||
XdgGlobHashNode *next;
|
XdgGlobHashNode *next;
|
||||||
XdgGlobHashNode *child;
|
XdgGlobHashNode *child;
|
||||||
};
|
};
|
||||||
@ -59,6 +60,7 @@ struct XdgGlobList
|
|||||||
{
|
{
|
||||||
const char *data;
|
const char *data;
|
||||||
const char *mime_type;
|
const char *mime_type;
|
||||||
|
int weight;
|
||||||
XdgGlobList *next;
|
XdgGlobList *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -107,7 +109,8 @@ _xdg_glob_list_free (XdgGlobList *glob_list)
|
|||||||
static XdgGlobList *
|
static XdgGlobList *
|
||||||
_xdg_glob_list_append (XdgGlobList *glob_list,
|
_xdg_glob_list_append (XdgGlobList *glob_list,
|
||||||
void *data,
|
void *data,
|
||||||
const char *mime_type)
|
const char *mime_type,
|
||||||
|
int weight)
|
||||||
{
|
{
|
||||||
XdgGlobList *new_element;
|
XdgGlobList *new_element;
|
||||||
XdgGlobList *tmp_element;
|
XdgGlobList *tmp_element;
|
||||||
@ -115,6 +118,7 @@ _xdg_glob_list_append (XdgGlobList *glob_list,
|
|||||||
new_element = _xdg_glob_list_new ();
|
new_element = _xdg_glob_list_new ();
|
||||||
new_element->data = data;
|
new_element->data = data;
|
||||||
new_element->mime_type = mime_type;
|
new_element->mime_type = mime_type;
|
||||||
|
new_element->weight = weight;
|
||||||
if (glob_list == NULL)
|
if (glob_list == NULL)
|
||||||
return new_element;
|
return new_element;
|
||||||
|
|
||||||
@ -127,23 +131,6 @@ _xdg_glob_list_append (XdgGlobList *glob_list,
|
|||||||
return glob_list;
|
return glob_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
static XdgGlobList *
|
|
||||||
_xdg_glob_list_prepend (XdgGlobList *glob_list,
|
|
||||||
void *data,
|
|
||||||
const char *mime_type)
|
|
||||||
{
|
|
||||||
XdgGlobList *new_element;
|
|
||||||
|
|
||||||
new_element = _xdg_glob_list_new ();
|
|
||||||
new_element->data = data;
|
|
||||||
new_element->next = glob_list;
|
|
||||||
new_element->mime_type = mime_type;
|
|
||||||
|
|
||||||
return new_element;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* XdgGlobHashNode
|
/* XdgGlobHashNode
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -167,7 +154,7 @@ _xdg_glob_hash_node_dump (XdgGlobHashNode *glob_hash_node,
|
|||||||
|
|
||||||
printf ("%c", (char)glob_hash_node->character);
|
printf ("%c", (char)glob_hash_node->character);
|
||||||
if (glob_hash_node->mime_type)
|
if (glob_hash_node->mime_type)
|
||||||
printf (" - %s\n", glob_hash_node->mime_type);
|
printf (" - %s %d\n", glob_hash_node->mime_type, glob_hash_node->weight);
|
||||||
else
|
else
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
if (glob_hash_node->child)
|
if (glob_hash_node->child)
|
||||||
@ -177,14 +164,15 @@ _xdg_glob_hash_node_dump (XdgGlobHashNode *glob_hash_node,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static XdgGlobHashNode *
|
static XdgGlobHashNode *
|
||||||
_xdg_glob_hash_insert_text (XdgGlobHashNode *glob_hash_node,
|
_xdg_glob_hash_insert_ucs4 (XdgGlobHashNode *glob_hash_node,
|
||||||
const char *text,
|
xdg_unichar_t *text,
|
||||||
const char *mime_type)
|
const char *mime_type,
|
||||||
|
int weight)
|
||||||
{
|
{
|
||||||
XdgGlobHashNode *node;
|
XdgGlobHashNode *node;
|
||||||
xdg_unichar_t character;
|
xdg_unichar_t character;
|
||||||
|
|
||||||
character = _xdg_utf8_to_ucs4 (text);
|
character = text[0];
|
||||||
|
|
||||||
if ((glob_hash_node == NULL) ||
|
if ((glob_hash_node == NULL) ||
|
||||||
(character < glob_hash_node->character))
|
(character < glob_hash_node->character))
|
||||||
@ -238,8 +226,8 @@ _xdg_glob_hash_insert_text (XdgGlobHashNode *glob_hash_node,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
text = _xdg_utf8_next_char (text);
|
text++;
|
||||||
if (*text == '\000')
|
if (*text == 0)
|
||||||
{
|
{
|
||||||
if (node->mime_type)
|
if (node->mime_type)
|
||||||
{
|
{
|
||||||
@ -249,7 +237,7 @@ _xdg_glob_hash_insert_text (XdgGlobHashNode *glob_hash_node,
|
|||||||
int found_node = FALSE;
|
int found_node = FALSE;
|
||||||
|
|
||||||
child = node->child;
|
child = node->child;
|
||||||
while (child && child->character == '\0')
|
while (child && child->character == 0)
|
||||||
{
|
{
|
||||||
if (strcmp (child->mime_type, mime_type) == 0)
|
if (strcmp (child->mime_type, mime_type) == 0)
|
||||||
{
|
{
|
||||||
@ -262,8 +250,9 @@ _xdg_glob_hash_insert_text (XdgGlobHashNode *glob_hash_node,
|
|||||||
if (!found_node)
|
if (!found_node)
|
||||||
{
|
{
|
||||||
child = _xdg_glob_hash_node_new ();
|
child = _xdg_glob_hash_node_new ();
|
||||||
child->character = '\000';
|
child->character = 0;
|
||||||
child->mime_type = strdup (mime_type);
|
child->mime_type = strdup (mime_type);
|
||||||
|
child->weight = weight;
|
||||||
child->child = NULL;
|
child->child = NULL;
|
||||||
child->next = node->child;
|
child->next = node->child;
|
||||||
node->child = child;
|
node->child = child;
|
||||||
@ -273,20 +262,45 @@ _xdg_glob_hash_insert_text (XdgGlobHashNode *glob_hash_node,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
node->mime_type = strdup (mime_type);
|
node->mime_type = strdup (mime_type);
|
||||||
|
node->weight = weight;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
node->child = _xdg_glob_hash_insert_text (node->child, text, mime_type);
|
node->child = _xdg_glob_hash_insert_ucs4 (node->child, text, mime_type, weight);
|
||||||
}
|
}
|
||||||
return glob_hash_node;
|
return glob_hash_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* glob must be valid UTF-8 */
|
||||||
|
static XdgGlobHashNode *
|
||||||
|
_xdg_glob_hash_insert_text (XdgGlobHashNode *glob_hash_node,
|
||||||
|
const char *text,
|
||||||
|
const char *mime_type,
|
||||||
|
int weight)
|
||||||
|
{
|
||||||
|
XdgGlobHashNode *node;
|
||||||
|
xdg_unichar_t *unitext;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
unitext = _xdg_convert_to_ucs4 (text, &len);
|
||||||
|
_xdg_reverse_ucs4 (unitext, len);
|
||||||
|
node = _xdg_glob_hash_insert_ucs4 (glob_hash_node, unitext, mime_type, weight);
|
||||||
|
free (unitext);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char *mime;
|
||||||
|
int weight;
|
||||||
|
} MimeWeight;
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_xdg_glob_hash_node_lookup_file_name (XdgGlobHashNode *glob_hash_node,
|
_xdg_glob_hash_node_lookup_file_name (XdgGlobHashNode *glob_hash_node,
|
||||||
const char *file_name,
|
xdg_unichar_t *file_name,
|
||||||
|
int len,
|
||||||
int ignore_case,
|
int ignore_case,
|
||||||
const char *mime_types[],
|
MimeWeight mime_types[],
|
||||||
int n_mime_types)
|
int n_mime_types)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
@ -296,7 +310,7 @@ _xdg_glob_hash_node_lookup_file_name (XdgGlobHashNode *glob_hash_node,
|
|||||||
if (glob_hash_node == NULL)
|
if (glob_hash_node == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
character = _xdg_utf8_to_ucs4 (file_name);
|
character = file_name[len - 1];
|
||||||
if (ignore_case)
|
if (ignore_case)
|
||||||
character = _xdg_ucs4_to_lower(character);
|
character = _xdg_ucs4_to_lower(character);
|
||||||
|
|
||||||
@ -304,28 +318,37 @@ _xdg_glob_hash_node_lookup_file_name (XdgGlobHashNode *glob_hash_node,
|
|||||||
{
|
{
|
||||||
if (character == node->character)
|
if (character == node->character)
|
||||||
{
|
{
|
||||||
file_name = _xdg_utf8_next_char (file_name);
|
len--;
|
||||||
if (*file_name == '\000')
|
|
||||||
{
|
|
||||||
n = 0;
|
n = 0;
|
||||||
|
if (len > 0)
|
||||||
|
{
|
||||||
|
n = _xdg_glob_hash_node_lookup_file_name (node->child,
|
||||||
|
file_name,
|
||||||
|
len,
|
||||||
|
ignore_case,
|
||||||
|
mime_types,
|
||||||
|
n_mime_types);
|
||||||
|
}
|
||||||
|
if (n == 0)
|
||||||
|
{
|
||||||
if (node->mime_type)
|
if (node->mime_type)
|
||||||
mime_types[n++] = node->mime_type;
|
{
|
||||||
|
mime_types[n].mime = node->mime_type;
|
||||||
|
mime_types[n].weight = node->weight;
|
||||||
|
n++;
|
||||||
|
}
|
||||||
node = node->child;
|
node = node->child;
|
||||||
while (n < n_mime_types && node && node->character == 0)
|
while (n < n_mime_types && node && node->character == 0)
|
||||||
{
|
{
|
||||||
if (node->mime_type)
|
if (node->mime_type)
|
||||||
mime_types[n++] = node->mime_type;
|
{
|
||||||
|
mime_types[n].mime = node->mime_type;
|
||||||
|
mime_types[n].weight = node->weight;
|
||||||
|
n++;
|
||||||
|
}
|
||||||
node = node->next;
|
node = node->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
n = _xdg_glob_hash_node_lookup_file_name (node->child,
|
|
||||||
file_name,
|
|
||||||
ignore_case,
|
|
||||||
mime_types,
|
|
||||||
n_mime_types);
|
|
||||||
}
|
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -333,6 +356,14 @@ _xdg_glob_hash_node_lookup_file_name (XdgGlobHashNode *glob_hash_node,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int compare_mime_weight (const void *a, const void *b)
|
||||||
|
{
|
||||||
|
const MimeWeight *aa = (const MimeWeight *)a;
|
||||||
|
const MimeWeight *bb = (const MimeWeight *)b;
|
||||||
|
|
||||||
|
return aa->weight - bb->weight;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
_xdg_glob_hash_lookup_file_name (XdgGlobHash *glob_hash,
|
_xdg_glob_hash_lookup_file_name (XdgGlobHash *glob_hash,
|
||||||
const char *file_name,
|
const char *file_name,
|
||||||
@ -340,15 +371,18 @@ _xdg_glob_hash_lookup_file_name (XdgGlobHash *glob_hash,
|
|||||||
int n_mime_types)
|
int n_mime_types)
|
||||||
{
|
{
|
||||||
XdgGlobList *list;
|
XdgGlobList *list;
|
||||||
const char *ptr;
|
|
||||||
char stopchars[128];
|
|
||||||
int i, n;
|
int i, n;
|
||||||
XdgGlobHashNode *node;
|
MimeWeight mimes[10];
|
||||||
|
int n_mimes = 10;
|
||||||
|
xdg_unichar_t *ucs4;
|
||||||
|
int len;
|
||||||
|
|
||||||
/* First, check the literals */
|
/* First, check the literals */
|
||||||
|
|
||||||
assert (file_name != NULL && n_mime_types > 0);
|
assert (file_name != NULL && n_mime_types > 0);
|
||||||
|
|
||||||
|
n = 0;
|
||||||
|
|
||||||
for (list = glob_hash->literal_list; list; list = list->next)
|
for (list = glob_hash->literal_list; list; list = list->next)
|
||||||
{
|
{
|
||||||
if (strcmp ((const char *)list->data, file_name) == 0)
|
if (strcmp ((const char *)list->data, file_name) == 0)
|
||||||
@ -358,37 +392,35 @@ _xdg_glob_hash_lookup_file_name (XdgGlobHash *glob_hash,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
i = 0;
|
ucs4 = _xdg_convert_to_ucs4 (file_name, &len);
|
||||||
for (node = glob_hash->simple_node; node; node = node->next)
|
n = _xdg_glob_hash_node_lookup_file_name (glob_hash->simple_node, ucs4, len, FALSE,
|
||||||
{
|
mimes, n_mimes);
|
||||||
if (node->character < 128)
|
if (n == 0)
|
||||||
stopchars[i++] = (char)node->character;
|
n = _xdg_glob_hash_node_lookup_file_name (glob_hash->simple_node, ucs4, len, TRUE,
|
||||||
}
|
mimes, n_mimes);
|
||||||
stopchars[i] = '\0';
|
free(ucs4);
|
||||||
|
|
||||||
ptr = strpbrk (file_name, stopchars);
|
|
||||||
while (ptr)
|
|
||||||
{
|
|
||||||
n = _xdg_glob_hash_node_lookup_file_name (glob_hash->simple_node, ptr, FALSE,
|
|
||||||
mime_types, n_mime_types);
|
|
||||||
if (n > 0)
|
|
||||||
return n;
|
|
||||||
|
|
||||||
n = _xdg_glob_hash_node_lookup_file_name (glob_hash->simple_node, ptr, TRUE,
|
|
||||||
mime_types, n_mime_types);
|
|
||||||
if (n > 0)
|
|
||||||
return n;
|
|
||||||
|
|
||||||
ptr = strpbrk (ptr + 1, stopchars);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* FIXME: Not UTF-8 safe */
|
/* FIXME: Not UTF-8 safe */
|
||||||
n = 0;
|
if (n == 0)
|
||||||
|
{
|
||||||
for (list = glob_hash->full_list; list && n < n_mime_types; list = list->next)
|
for (list = glob_hash->full_list; list && n < n_mime_types; list = list->next)
|
||||||
{
|
{
|
||||||
if (fnmatch ((const char *)list->data, file_name, 0) == 0)
|
if (fnmatch ((const char *)list->data, file_name, 0) == 0)
|
||||||
mime_types[n++] = list->mime_type;
|
{
|
||||||
|
mimes[n].mime = list->mime_type;
|
||||||
|
mimes[n].weight = list->weight;
|
||||||
|
n++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
qsort (mimes, n, sizeof (MimeWeight), compare_mime_weight);
|
||||||
|
|
||||||
|
if (n_mime_types < n)
|
||||||
|
n = n_mime_types;
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
mime_types[i] = mimes[i].mime;
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
@ -442,7 +474,7 @@ _xdg_glob_determine_type (const char *glob)
|
|||||||
|
|
||||||
ptr = glob;
|
ptr = glob;
|
||||||
|
|
||||||
while (*ptr != '\000')
|
while (*ptr != '\0')
|
||||||
{
|
{
|
||||||
if (*ptr == '*' && first_char)
|
if (*ptr == '*' && first_char)
|
||||||
maybe_in_simple_glob = TRUE;
|
maybe_in_simple_glob = TRUE;
|
||||||
@ -462,7 +494,8 @@ _xdg_glob_determine_type (const char *glob)
|
|||||||
void
|
void
|
||||||
_xdg_glob_hash_append_glob (XdgGlobHash *glob_hash,
|
_xdg_glob_hash_append_glob (XdgGlobHash *glob_hash,
|
||||||
const char *glob,
|
const char *glob,
|
||||||
const char *mime_type)
|
const char *mime_type,
|
||||||
|
int weight)
|
||||||
{
|
{
|
||||||
XdgGlobType type;
|
XdgGlobType type;
|
||||||
|
|
||||||
@ -474,13 +507,13 @@ _xdg_glob_hash_append_glob (XdgGlobHash *glob_hash,
|
|||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case XDG_GLOB_LITERAL:
|
case XDG_GLOB_LITERAL:
|
||||||
glob_hash->literal_list = _xdg_glob_list_append (glob_hash->literal_list, strdup (glob), strdup (mime_type));
|
glob_hash->literal_list = _xdg_glob_list_append (glob_hash->literal_list, strdup (glob), strdup (mime_type), weight);
|
||||||
break;
|
break;
|
||||||
case XDG_GLOB_SIMPLE:
|
case XDG_GLOB_SIMPLE:
|
||||||
glob_hash->simple_node = _xdg_glob_hash_insert_text (glob_hash->simple_node, glob + 1, mime_type);
|
glob_hash->simple_node = _xdg_glob_hash_insert_text (glob_hash->simple_node, glob + 1, mime_type, weight);
|
||||||
break;
|
break;
|
||||||
case XDG_GLOB_FULL:
|
case XDG_GLOB_FULL:
|
||||||
glob_hash->full_list = _xdg_glob_list_append (glob_hash->full_list, strdup (glob), strdup (mime_type));
|
glob_hash->full_list = _xdg_glob_list_append (glob_hash->full_list, strdup (glob), strdup (mime_type), weight);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -490,27 +523,34 @@ _xdg_glob_hash_dump (XdgGlobHash *glob_hash)
|
|||||||
{
|
{
|
||||||
XdgGlobList *list;
|
XdgGlobList *list;
|
||||||
printf ("LITERAL STRINGS\n");
|
printf ("LITERAL STRINGS\n");
|
||||||
if (glob_hash->literal_list == NULL)
|
if (!glob_hash || glob_hash->literal_list == NULL)
|
||||||
{
|
{
|
||||||
printf (" None\n");
|
printf (" None\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (list = glob_hash->literal_list; list; list = list->next)
|
for (list = glob_hash->literal_list; list; list = list->next)
|
||||||
printf (" %s - %s\n", (char *)list->data, list->mime_type);
|
printf (" %s - %s %d\n", (char *)list->data, list->mime_type, list->weight);
|
||||||
}
|
}
|
||||||
printf ("\nSIMPLE GLOBS\n");
|
printf ("\nSIMPLE GLOBS\n");
|
||||||
|
if (!glob_hash || glob_hash->simple_node == NULL)
|
||||||
|
{
|
||||||
|
printf (" None\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
_xdg_glob_hash_node_dump (glob_hash->simple_node, 4);
|
_xdg_glob_hash_node_dump (glob_hash->simple_node, 4);
|
||||||
|
}
|
||||||
|
|
||||||
printf ("\nFULL GLOBS\n");
|
printf ("\nFULL GLOBS\n");
|
||||||
if (glob_hash->full_list == NULL)
|
if (!glob_hash || glob_hash->full_list == NULL)
|
||||||
{
|
{
|
||||||
printf (" None\n");
|
printf (" None\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (list = glob_hash->full_list; list; list = list->next)
|
for (list = glob_hash->full_list; list; list = list->next)
|
||||||
printf (" %s - %s\n", (char *)list->data, list->mime_type);
|
printf (" %s - %s %d\n", (char *)list->data, list->mime_type, list->weight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -531,16 +571,33 @@ _xdg_mime_glob_read_from_file (XdgGlobHash *glob_hash,
|
|||||||
* Blah */
|
* Blah */
|
||||||
while (fgets (line, 255, glob_file) != NULL)
|
while (fgets (line, 255, glob_file) != NULL)
|
||||||
{
|
{
|
||||||
char *colon;
|
char *colon, *colon2;
|
||||||
|
char *mimetype, *glob;
|
||||||
|
int weight;
|
||||||
|
|
||||||
if (line[0] == '#')
|
if (line[0] == '#')
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
colon = strchr (line, ':');
|
colon = strchr (line, ':');
|
||||||
if (colon == NULL)
|
if (colon == NULL)
|
||||||
continue;
|
continue;
|
||||||
*(colon++) = '\000';
|
*(colon++) = '\0';
|
||||||
colon[strlen (colon) -1] = '\000';
|
colon[strlen (colon) -1] = '\0';
|
||||||
_xdg_glob_hash_append_glob (glob_hash, colon, line);
|
colon2 = strchr (colon, ':');
|
||||||
|
if (colon2)
|
||||||
|
{
|
||||||
|
*(colon2++) = '\000';
|
||||||
|
weight = atoi (line);
|
||||||
|
mimetype = colon;
|
||||||
|
glob = colon2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
weight = 50;
|
||||||
|
mimetype = line;
|
||||||
|
glob = colon;
|
||||||
|
}
|
||||||
|
_xdg_glob_hash_append_glob (glob_hash, glob, mimetype, weight);
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose (glob_file);
|
fclose (glob_file);
|
||||||
|
@ -41,13 +41,13 @@ typedef enum
|
|||||||
|
|
||||||
|
|
||||||
#ifdef XDG_PREFIX
|
#ifdef XDG_PREFIX
|
||||||
#define _xdg_mime_glob_read_from_file XDG_ENTRY(glob_read_from_file)
|
#define _xdg_mime_glob_read_from_file XDG_RESERVED_ENTRY(glob_read_from_file)
|
||||||
#define _xdg_glob_hash_new XDG_ENTRY(hash_new)
|
#define _xdg_glob_hash_new XDG_RESERVED_ENTRY(hash_new)
|
||||||
#define _xdg_glob_hash_free XDG_ENTRY(hash_free)
|
#define _xdg_glob_hash_free XDG_RESERVED_ENTRY(hash_free)
|
||||||
#define _xdg_glob_hash_lookup_file_name XDG_ENTRY(hash_lookup_file_name)
|
#define _xdg_glob_hash_lookup_file_name XDG_RESERVED_ENTRY(hash_lookup_file_name)
|
||||||
#define _xdg_glob_hash_append_glob XDG_ENTRY(hash_append_glob)
|
#define _xdg_glob_hash_append_glob XDG_RESERVED_ENTRY(hash_append_glob)
|
||||||
#define _xdg_glob_determine_type XDG_ENTRY(determine_type)
|
#define _xdg_glob_determine_type XDG_RESERVED_ENTRY(determine_type)
|
||||||
#define _xdg_glob_hash_dump XDG_ENTRY(hash_dump)
|
#define _xdg_glob_hash_dump XDG_RESERVED_ENTRY(hash_dump)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void _xdg_mime_glob_read_from_file (XdgGlobHash *glob_hash,
|
void _xdg_mime_glob_read_from_file (XdgGlobHash *glob_hash,
|
||||||
@ -60,7 +60,8 @@ int _xdg_glob_hash_lookup_file_name (XdgGlobHash *glob_hash,
|
|||||||
int n_mime_types);
|
int n_mime_types);
|
||||||
void _xdg_glob_hash_append_glob (XdgGlobHash *glob_hash,
|
void _xdg_glob_hash_append_glob (XdgGlobHash *glob_hash,
|
||||||
const char *glob,
|
const char *glob,
|
||||||
const char *mime_type);
|
const char *mime_type,
|
||||||
|
int weight);
|
||||||
XdgGlobType _xdg_glob_determine_type (const char *glob);
|
XdgGlobType _xdg_glob_determine_type (const char *glob);
|
||||||
void _xdg_glob_hash_dump (XdgGlobHash *glob_hash);
|
void _xdg_glob_hash_dump (XdgGlobHash *glob_hash);
|
||||||
|
|
||||||
|
183
gio/xdgmime/xdgmimeicon.c
Normal file
183
gio/xdgmime/xdgmimeicon.c
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
/* -*- mode: C; c-file-style: "gnu" -*- */
|
||||||
|
/* xdgmimeicon.c: Private file. Datastructure for storing the aliases.
|
||||||
|
*
|
||||||
|
* More info can be found at http://www.freedesktop.org/standards/
|
||||||
|
*
|
||||||
|
* Copyright (C) 2008 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Academic Free License version 2.0
|
||||||
|
* Or under the following terms:
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "xdgmimeicon.h"
|
||||||
|
#include "xdgmimeint.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <fnmatch.h>
|
||||||
|
|
||||||
|
#ifndef FALSE
|
||||||
|
#define FALSE (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef TRUE
|
||||||
|
#define TRUE (!FALSE)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct XdgIcon XdgIcon;
|
||||||
|
|
||||||
|
struct XdgIcon
|
||||||
|
{
|
||||||
|
char *mime_type;
|
||||||
|
char *icon_name;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct XdgIconList
|
||||||
|
{
|
||||||
|
struct XdgIcon *icons;
|
||||||
|
int n_icons;
|
||||||
|
};
|
||||||
|
|
||||||
|
XdgIconList *
|
||||||
|
_xdg_mime_icon_list_new (void)
|
||||||
|
{
|
||||||
|
XdgIconList *list;
|
||||||
|
|
||||||
|
list = malloc (sizeof (XdgIconList));
|
||||||
|
|
||||||
|
list->icons = NULL;
|
||||||
|
list->n_icons = 0;
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_xdg_mime_icon_list_free (XdgIconList *list)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (list->icons)
|
||||||
|
{
|
||||||
|
for (i = 0; i < list->n_icons; i++)
|
||||||
|
{
|
||||||
|
free (list->icons[i].mime_type);
|
||||||
|
free (list->icons[i].icon_name);
|
||||||
|
}
|
||||||
|
free (list->icons);
|
||||||
|
}
|
||||||
|
free (list);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
icon_entry_cmp (const void *v1, const void *v2)
|
||||||
|
{
|
||||||
|
return strcmp (((XdgIcon *)v1)->mime_type, ((XdgIcon *)v2)->mime_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
_xdg_mime_icon_list_lookup (XdgIconList *list,
|
||||||
|
const char *mime_type)
|
||||||
|
{
|
||||||
|
XdgIcon *entry;
|
||||||
|
XdgIcon key;
|
||||||
|
|
||||||
|
if (list->n_icons > 0)
|
||||||
|
{
|
||||||
|
key.mime_type = (char *)mime_type;
|
||||||
|
key.icon_name = NULL;
|
||||||
|
|
||||||
|
entry = bsearch (&key, list->icons, list->n_icons,
|
||||||
|
sizeof (XdgIcon), icon_entry_cmp);
|
||||||
|
if (entry)
|
||||||
|
return entry->icon_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_xdg_mime_icon_read_from_file (XdgIconList *list,
|
||||||
|
const char *file_name)
|
||||||
|
{
|
||||||
|
FILE *file;
|
||||||
|
char line[255];
|
||||||
|
int alloc;
|
||||||
|
|
||||||
|
file = fopen (file_name, "r");
|
||||||
|
|
||||||
|
if (file == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* FIXME: Not UTF-8 safe. Doesn't work if lines are greater than 255 chars.
|
||||||
|
* Blah */
|
||||||
|
alloc = list->n_icons + 16;
|
||||||
|
list->icons = realloc (list->icons, alloc * sizeof (XdgIcon));
|
||||||
|
while (fgets (line, 255, file) != NULL)
|
||||||
|
{
|
||||||
|
char *sep;
|
||||||
|
if (line[0] == '#')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
sep = strchr (line, ':');
|
||||||
|
if (sep == NULL)
|
||||||
|
continue;
|
||||||
|
*(sep++) = '\000';
|
||||||
|
sep[strlen (sep) -1] = '\000';
|
||||||
|
if (list->n_icons == alloc)
|
||||||
|
{
|
||||||
|
alloc <<= 1;
|
||||||
|
list->icons = realloc (list->icons,
|
||||||
|
alloc * sizeof (XdgIcon));
|
||||||
|
}
|
||||||
|
list->icons[list->n_icons].mime_type = strdup (line);
|
||||||
|
list->icons[list->n_icons].icon_name = strdup (sep);
|
||||||
|
list->n_icons++;
|
||||||
|
}
|
||||||
|
list->icons = realloc (list->icons,
|
||||||
|
list->n_icons * sizeof (XdgIcon));
|
||||||
|
|
||||||
|
fclose (file);
|
||||||
|
|
||||||
|
if (list->n_icons > 1)
|
||||||
|
qsort (list->icons, list->n_icons,
|
||||||
|
sizeof (XdgIcon), icon_entry_cmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
_xdg_mime_icon_list_dump (XdgIconList *list)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (list->icons)
|
||||||
|
{
|
||||||
|
for (i = 0; i < list->n_icons; i++)
|
||||||
|
{
|
||||||
|
printf ("%s %s\n",
|
||||||
|
list->icons[i].mime_type,
|
||||||
|
list->icons[i].icon_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
50
gio/xdgmime/xdgmimeicon.h
Normal file
50
gio/xdgmime/xdgmimeicon.h
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/* -*- mode: C; c-file-style: "gnu" -*- */
|
||||||
|
/* xdgmimeicon.h: Private file. Datastructure for storing the aliases.
|
||||||
|
*
|
||||||
|
* More info can be found at http://www.freedesktop.org/standards/
|
||||||
|
*
|
||||||
|
* Copyright (C) 2008 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Academic Free License version 2.0
|
||||||
|
* Or under the following terms:
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __XDG_MIME_ICON_H__
|
||||||
|
#define __XDG_MIME_ICON_H__
|
||||||
|
|
||||||
|
#include "xdgmime.h"
|
||||||
|
|
||||||
|
typedef struct XdgIconList XdgIconList;
|
||||||
|
|
||||||
|
#ifdef XDG_PREFIX
|
||||||
|
#define _xdg_mime_icon_read_from_file XDG_ENTRY(icon_read_from_file)
|
||||||
|
#define _xdg_mime_icon_list_new XDG_ENTRY(icon_list_new)
|
||||||
|
#define _xdg_mime_icon_list_free XDG_ENTRY(icon_list_free)
|
||||||
|
#define _xdg_mime_icon_list_lookup XDG_ENTRY(icon_list_lookup)
|
||||||
|
#define _xdg_mime_icon_list_dump XDG_ENTRY(icon_list_dump)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void _xdg_mime_icon_read_from_file (XdgIconList *list,
|
||||||
|
const char *file_name);
|
||||||
|
XdgIconList *_xdg_mime_icon_list_new (void);
|
||||||
|
void _xdg_mime_icon_list_free (XdgIconList *list);
|
||||||
|
const char *_xdg_mime_icon_list_lookup (XdgIconList *list,
|
||||||
|
const char *mime);
|
||||||
|
void _xdg_mime_icon_list_dump (XdgIconList *list);
|
||||||
|
|
||||||
|
#endif /* __XDG_MIME_ICON_H__ */
|
@ -152,3 +152,40 @@ _xdg_get_base_name (const char *file_name)
|
|||||||
else
|
else
|
||||||
return base_name + 1;
|
return base_name + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xdg_unichar_t *
|
||||||
|
_xdg_convert_to_ucs4 (const char *source, int *len)
|
||||||
|
{
|
||||||
|
xdg_unichar_t *out;
|
||||||
|
int i;
|
||||||
|
const char *p;
|
||||||
|
|
||||||
|
out = malloc (sizeof (xdg_unichar_t) * (strlen (source) + 1));
|
||||||
|
|
||||||
|
p = source;
|
||||||
|
i = 0;
|
||||||
|
while (*p)
|
||||||
|
{
|
||||||
|
out[i++] = _xdg_utf8_to_ucs4 (p);
|
||||||
|
p = _xdg_utf8_next_char (p);
|
||||||
|
}
|
||||||
|
out[i] = 0;
|
||||||
|
*len = i;
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_xdg_reverse_ucs4 (xdg_unichar_t *source, int len)
|
||||||
|
{
|
||||||
|
xdg_unichar_t c;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < len - i - 1; i++)
|
||||||
|
{
|
||||||
|
c = source[i];
|
||||||
|
source[i] = source[len - i - 1];
|
||||||
|
source[len - i - 1] = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -46,11 +46,13 @@ typedef unsigned short xdg_uint16_t;
|
|||||||
typedef unsigned int xdg_uint32_t;
|
typedef unsigned int xdg_uint32_t;
|
||||||
|
|
||||||
#ifdef XDG_PREFIX
|
#ifdef XDG_PREFIX
|
||||||
#define _xdg_utf8_skip XDG_ENTRY(utf8_skip)
|
#define _xdg_utf8_skip XDG_RESERVED_ENTRY(utf8_skip)
|
||||||
#define _xdg_utf8_to_ucs4 XDG_ENTRY(utf8_to_ucs4)
|
#define _xdg_utf8_to_ucs4 XDG_RESERVED_ENTRY(utf8_to_ucs4)
|
||||||
#define _xdg_ucs4_to_lower XDG_ENTRY(ucs4_to_lower)
|
#define _xdg_ucs4_to_lower XDG_RESERVED_ENTRY(ucs4_to_lower)
|
||||||
#define _xdg_utf8_validate XDG_ENTRY(utf8_validate)
|
#define _xdg_utf8_validate XDG_RESERVED_ENTRY(utf8_validate)
|
||||||
#define _xdg_get_base_name XDG_ENTRY(get_ase_name)
|
#define _xdg_get_base_name XDG_RESERVED_ENTRY(get_base_name)
|
||||||
|
#define _xdg_convert_to_ucs4 XDG_RESERVED_ENTRY(convert_to_ucs4)
|
||||||
|
#define _xdg_reverse_ucs4 XDG_RESERVED_ENTRY(reverse_ucs4)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define SWAP_BE16_TO_LE16(val) (xdg_uint16_t)(((xdg_uint16_t)(val) << 8)|((xdg_uint16_t)(val) >> 8))
|
#define SWAP_BE16_TO_LE16(val) (xdg_uint16_t)(((xdg_uint16_t)(val) << 8)|((xdg_uint16_t)(val) >> 8))
|
||||||
@ -68,6 +70,8 @@ extern const char *const _xdg_utf8_skip;
|
|||||||
xdg_unichar_t _xdg_utf8_to_ucs4 (const char *source);
|
xdg_unichar_t _xdg_utf8_to_ucs4 (const char *source);
|
||||||
xdg_unichar_t _xdg_ucs4_to_lower (xdg_unichar_t source);
|
xdg_unichar_t _xdg_ucs4_to_lower (xdg_unichar_t source);
|
||||||
int _xdg_utf8_validate (const char *source);
|
int _xdg_utf8_validate (const char *source);
|
||||||
|
xdg_unichar_t *_xdg_convert_to_ucs4 (const char *source, int *len);
|
||||||
|
void _xdg_reverse_ucs4 (xdg_unichar_t *source, int len);
|
||||||
const char *_xdg_get_base_name (const char *file_name);
|
const char *_xdg_get_base_name (const char *file_name);
|
||||||
|
|
||||||
#endif /* __XDG_MIME_INT_H__ */
|
#endif /* __XDG_MIME_INT_H__ */
|
||||||
|
@ -33,12 +33,12 @@
|
|||||||
typedef struct XdgMimeMagic XdgMimeMagic;
|
typedef struct XdgMimeMagic XdgMimeMagic;
|
||||||
|
|
||||||
#ifdef XDG_PREFIX
|
#ifdef XDG_PREFIX
|
||||||
#define _xdg_mime_glob_read_from_file XDG_ENTRY(glob_read_from_file)
|
#define _xdg_mime_glob_read_from_file XDG_RESERVED_ENTRY(glob_read_from_file)
|
||||||
#define _xdg_mime_magic_new XDG_ENTRY(magic_new)
|
#define _xdg_mime_magic_new XDG_RESERVED_ENTRY(magic_new)
|
||||||
#define _xdg_mime_magic_read_from_file XDG_ENTRY(magic_read_from_file)
|
#define _xdg_mime_magic_read_from_file XDG_RESERVED_ENTRY(magic_read_from_file)
|
||||||
#define _xdg_mime_magic_free XDG_ENTRY(magic_free)
|
#define _xdg_mime_magic_free XDG_RESERVED_ENTRY(magic_free)
|
||||||
#define _xdg_mime_magic_get_buffer_extents XDG_ENTRY(magic_get_buffer_extents)
|
#define _xdg_mime_magic_get_buffer_extents XDG_RESERVED_ENTRY(magic_get_buffer_extents)
|
||||||
#define _xdg_mime_magic_lookup_data XDG_ENTRY(magic_lookup_data)
|
#define _xdg_mime_magic_lookup_data XDG_RESERVED_ENTRY(magic_lookup_data)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -33,11 +33,11 @@
|
|||||||
typedef struct XdgParentList XdgParentList;
|
typedef struct XdgParentList XdgParentList;
|
||||||
|
|
||||||
#ifdef XDG_PREFIX
|
#ifdef XDG_PREFIX
|
||||||
#define _xdg_mime_parent_read_from_file XDG_ENTRY(parent_read_from_file)
|
#define _xdg_mime_parent_read_from_file XDG_RESERVED_ENTRY(parent_read_from_file)
|
||||||
#define _xdg_mime_parent_list_new XDG_ENTRY(parent_list_new)
|
#define _xdg_mime_parent_list_new XDG_RESERVED_ENTRY(parent_list_new)
|
||||||
#define _xdg_mime_parent_list_free XDG_ENTRY(parent_list_free)
|
#define _xdg_mime_parent_list_free XDG_RESERVED_ENTRY(parent_list_free)
|
||||||
#define _xdg_mime_parent_list_lookup XDG_ENTRY(parent_list_lookup)
|
#define _xdg_mime_parent_list_lookup XDG_RESERVED_ENTRY(parent_list_lookup)
|
||||||
#define _xdg_mime_parent_list_dump XDG_ENTRY(parent_list_dump)
|
#define _xdg_mime_parent_list_dump XDG_RESERVED_ENTRY(parent_list_dump)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void _xdg_mime_parent_read_from_file (XdgParentList *list,
|
void _xdg_mime_parent_read_from_file (XdgParentList *list,
|
||||||
|
Loading…
Reference in New Issue
Block a user