mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-04 10:16:17 +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>
|
||||
|
||||
* Makefile.am: don't define G_DISABLE_SINGLE_INCLUDES, it's in
|
||||
@ -49,6 +55,13 @@
|
||||
|
||||
* 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>
|
||||
|
||||
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", "text/plain", 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
|
||||
@ -126,6 +178,8 @@ main (int argc, char *argv[])
|
||||
test_glob_type ();
|
||||
test_aliasing ();
|
||||
test_subclassing ();
|
||||
test_matches ();
|
||||
test_icons ();
|
||||
|
||||
for (i = 1; i < argc; i++)
|
||||
{
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "xdgmimeglob.h"
|
||||
#include "xdgmimemagic.h"
|
||||
#include "xdgmimealias.h"
|
||||
#include "xdgmimeicon.h"
|
||||
#include "xdgmimeparent.h"
|
||||
#include "xdgmimecache.h"
|
||||
#include <stdio.h>
|
||||
@ -56,6 +57,8 @@ static XdgAliasList *alias_list = NULL;
|
||||
static XdgParentList *parent_list = NULL;
|
||||
static XdgDirTimeList *dir_time_list = NULL;
|
||||
static XdgCallbackList *callback_list = NULL;
|
||||
static XdgIconList *icon_list = NULL;
|
||||
static XdgIconList *generic_icon_list = NULL;
|
||||
|
||||
XdgMimeCache **_caches = NULL;
|
||||
static int n_caches = 0;
|
||||
@ -155,6 +158,16 @@ xdg_mime_init_from_directory (const char *directory)
|
||||
}
|
||||
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);
|
||||
strcpy (file_name, directory); strcat (file_name, "/mime/globs");
|
||||
if (stat (file_name, &st) == 0)
|
||||
@ -166,6 +179,7 @@ xdg_mime_init_from_directory (const char *directory)
|
||||
{
|
||||
free (file_name);
|
||||
}
|
||||
}
|
||||
|
||||
file_name = malloc (strlen (directory) + strlen ("/mime/magic") + 1);
|
||||
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);
|
||||
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 */
|
||||
}
|
||||
|
||||
@ -423,6 +447,8 @@ xdg_mime_init (void)
|
||||
global_magic = _xdg_mime_magic_new ();
|
||||
alias_list = _xdg_mime_alias_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,
|
||||
NULL);
|
||||
@ -796,10 +822,18 @@ xdg_mime_get_mime_parents (const char *mime)
|
||||
void
|
||||
xdg_mime_dump (void)
|
||||
{
|
||||
xdg_mime_init();
|
||||
|
||||
printf ("*** ALIASES ***\n\n");
|
||||
_xdg_mime_alias_list_dump (alias_list);
|
||||
printf ("\n*** PARENTS ***\n\n");
|
||||
_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_ENTRY2(prefix,func) _XDG_ENTRY3(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
|
||||
|
||||
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_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_p)
|
||||
#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_p)
|
||||
#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_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_shutdown XDG_ENTRY(shutdown)
|
||||
#define xdg_mime_dump XDG_ENTRY(dump)
|
||||
#define xdg_mime_register_reload_callback XDG_ENTRY(register_reload_callback)
|
||||
#define xdg_mime_remove_callback XDG_ENTRY(remove_callback)
|
||||
#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
|
||||
|
||||
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);
|
||||
char ** xdg_mime_list_mime_parents (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);
|
||||
void xdg_mime_shutdown (void);
|
||||
void xdg_mime_dump (void);
|
||||
|
@ -33,11 +33,11 @@
|
||||
typedef struct XdgAliasList XdgAliasList;
|
||||
|
||||
#ifdef XDG_PREFIX
|
||||
#define _xdg_mime_alias_read_from_file XDG_ENTRY(alias_read_from_file)
|
||||
#define _xdg_mime_alias_list_new XDG_ENTRY(alias_list_new)
|
||||
#define _xdg_mime_alias_list_free XDG_ENTRY(alias_list_free)
|
||||
#define _xdg_mime_alias_list_lookup XDG_ENTRY(alias_list_lookup)
|
||||
#define _xdg_mime_alias_list_dump XDG_ENTRY(alias_list_dump)
|
||||
#define _xdg_mime_alias_read_from_file XDG_RESERVED_ENTRY(alias_read_from_file)
|
||||
#define _xdg_mime_alias_list_new XDG_RESERVED_ENTRY(alias_list_new)
|
||||
#define _xdg_mime_alias_list_free XDG_RESERVED_ENTRY(alias_list_free)
|
||||
#define _xdg_mime_alias_list_lookup XDG_RESERVED_ENTRY(alias_list_lookup)
|
||||
#define _xdg_mime_alias_list_dump XDG_RESERVED_ENTRY(alias_list_dump)
|
||||
#endif
|
||||
|
||||
void _xdg_mime_alias_read_from_file (XdgAliasList *list,
|
||||
|
@ -41,6 +41,8 @@
|
||||
|
||||
#ifdef HAVE_MMAP
|
||||
#include <sys/mman.h>
|
||||
#else
|
||||
#warning Building xdgmime without MMAP support. Binary "mime.info" cache files will not be used.
|
||||
#endif
|
||||
|
||||
#include <sys/stat.h>
|
||||
@ -70,7 +72,7 @@
|
||||
#endif
|
||||
|
||||
#define MAJOR_VERSION 1
|
||||
#define MINOR_VERSION 0
|
||||
#define MINOR_VERSION 1
|
||||
|
||||
struct _XdgMimeCache
|
||||
{
|
||||
@ -344,6 +346,11 @@ cache_alias_lookup (const char *alias)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
const char *mime;
|
||||
int weight;
|
||||
} MimeWeight;
|
||||
|
||||
static int
|
||||
cache_glob_lookup_literal (const char *file_name,
|
||||
const char *mime_types[],
|
||||
@ -365,7 +372,7 @@ cache_glob_lookup_literal (const char *file_name,
|
||||
{
|
||||
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;
|
||||
cmp = strcmp (ptr, file_name);
|
||||
|
||||
@ -375,7 +382,7 @@ cache_glob_lookup_literal (const char *file_name,
|
||||
max = mid - 1;
|
||||
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);
|
||||
|
||||
return 1;
|
||||
@ -388,7 +395,7 @@ cache_glob_lookup_literal (const char *file_name,
|
||||
|
||||
static int
|
||||
cache_glob_lookup_fnmatch (const char *file_name,
|
||||
const char *mime_types[],
|
||||
MimeWeight mime_types[],
|
||||
int n_mime_types)
|
||||
{
|
||||
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++)
|
||||
{
|
||||
xdg_uint32_t offset = GET_UINT32 (cache->buffer, list_offset + 4 + 8 * j);
|
||||
xdg_uint32_t mimetype_offset = GET_UINT32 (cache->buffer, list_offset + 4 + 8 * j + 4);
|
||||
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 + 12 * j + 4);
|
||||
int weight = GET_UINT32 (cache->buffer, list_offset + 4 + 12 * j + 8);
|
||||
ptr = cache->buffer + offset;
|
||||
mime_type = cache->buffer + mimetype_offset;
|
||||
|
||||
/* FIXME: Not UTF-8 safe */
|
||||
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)
|
||||
@ -427,9 +439,10 @@ static int
|
||||
cache_glob_node_lookup_suffix (XdgMimeCache *cache,
|
||||
xdg_uint32_t n_entries,
|
||||
xdg_uint32_t offset,
|
||||
const char *suffix,
|
||||
xdg_unichar_t *file_name,
|
||||
int len,
|
||||
int ignore_case,
|
||||
const char *mime_types[],
|
||||
MimeWeight mime_types[],
|
||||
int n_mime_types)
|
||||
{
|
||||
xdg_unichar_t character;
|
||||
@ -437,72 +450,71 @@ cache_glob_node_lookup_suffix (XdgMimeCache *cache,
|
||||
xdg_uint32_t mimetype_offset;
|
||||
xdg_uint32_t n_children;
|
||||
xdg_uint32_t child_offset;
|
||||
int weight;
|
||||
|
||||
int min, max, mid, n, i;
|
||||
|
||||
character = _xdg_utf8_to_ucs4 (suffix);
|
||||
character = file_name[len - 1];
|
||||
if (ignore_case)
|
||||
character = _xdg_ucs4_to_lower (character);
|
||||
|
||||
assert (character != 0);
|
||||
|
||||
min = 0;
|
||||
max = n_entries - 1;
|
||||
while (max >= min)
|
||||
{
|
||||
mid = (min + max) / 2;
|
||||
|
||||
match_char = GET_UINT32 (cache->buffer, offset + 16 * mid);
|
||||
|
||||
match_char = GET_UINT32 (cache->buffer, offset + 12 * mid);
|
||||
if (match_char < character)
|
||||
min = mid + 1;
|
||||
else if (match_char > character)
|
||||
max = mid - 1;
|
||||
else
|
||||
{
|
||||
suffix = _xdg_utf8_next_char (suffix);
|
||||
if (*suffix == '\0')
|
||||
{
|
||||
mimetype_offset = GET_UINT32 (cache->buffer, offset + 16 * mid + 4);
|
||||
len--;
|
||||
n = 0;
|
||||
if (mimetype_offset)
|
||||
mime_types[n++] = cache->buffer + mimetype_offset;
|
||||
n_children = GET_UINT32 (cache->buffer, offset + 12 * mid + 4);
|
||||
child_offset = GET_UINT32 (cache->buffer, offset + 12 * mid + 8);
|
||||
|
||||
n_children = GET_UINT32 (cache->buffer, offset + 16 * mid + 8);
|
||||
child_offset = GET_UINT32 (cache->buffer, offset + 16 * mid + 12);
|
||||
i = 0;
|
||||
while (n < n_mime_types && i < n_children)
|
||||
if (len > 0)
|
||||
{
|
||||
match_char = GET_UINT32 (cache->buffer, child_offset + 16 * i);
|
||||
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 = cache_glob_node_lookup_suffix (cache,
|
||||
n_children, child_offset,
|
||||
suffix, ignore_case,
|
||||
file_name, len,
|
||||
ignore_case,
|
||||
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;
|
||||
}
|
||||
|
||||
static int
|
||||
cache_glob_lookup_suffix (const char *suffix,
|
||||
cache_glob_lookup_suffix (xdg_unichar_t *file_name,
|
||||
int len,
|
||||
int ignore_case,
|
||||
const char *mime_types[],
|
||||
MimeWeight mime_types[],
|
||||
int n_mime_types)
|
||||
{
|
||||
int i, n;
|
||||
@ -517,7 +529,8 @@ cache_glob_lookup_suffix (const char *suffix,
|
||||
|
||||
n = cache_glob_node_lookup_suffix (cache,
|
||||
n_entries, offset,
|
||||
suffix, ignore_case,
|
||||
file_name, len,
|
||||
ignore_case,
|
||||
mime_types,
|
||||
n_mime_types);
|
||||
if (n > 0)
|
||||
@ -527,41 +540,12 @@ cache_glob_lookup_suffix (const char *suffix,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
find_stopchars (char *stopchars)
|
||||
static int compare_mime_weight (const void *a, const void *b)
|
||||
{
|
||||
int i, j, k, l;
|
||||
const MimeWeight *aa = (const MimeWeight *)a;
|
||||
const MimeWeight *bb = (const MimeWeight *)b;
|
||||
|
||||
k = 0;
|
||||
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';
|
||||
return aa->weight - bb->weight;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -569,36 +553,40 @@ cache_glob_lookup_file_name (const char *file_name,
|
||||
const char *mime_types[],
|
||||
int n_mime_types)
|
||||
{
|
||||
const char *ptr;
|
||||
char stopchars[128];
|
||||
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 */
|
||||
n = cache_glob_lookup_literal (file_name, mime_types, n_mime_types);
|
||||
if (n > 0)
|
||||
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 */
|
||||
ptr = strpbrk (file_name, stopchars);
|
||||
while (ptr)
|
||||
{
|
||||
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);
|
||||
}
|
||||
if (n == 0)
|
||||
n = cache_glob_lookup_suffix (ucs4, len, TRUE, mimes, n_mimes);
|
||||
free(ucs4);
|
||||
|
||||
/* 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
|
||||
@ -677,7 +665,7 @@ _xdg_mime_cache_get_mime_type_for_file (const char *file_name,
|
||||
struct stat *statbuf)
|
||||
{
|
||||
const char *mime_type;
|
||||
const char *mime_types[2];
|
||||
const char *mime_types[10];
|
||||
FILE *file;
|
||||
unsigned char *data;
|
||||
int max_extent;
|
||||
@ -693,7 +681,7 @@ _xdg_mime_cache_get_mime_type_for_file (const char *file_name,
|
||||
return NULL;
|
||||
|
||||
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)
|
||||
return mime_types[0];
|
||||
@ -918,3 +906,107 @@ _xdg_mime_cache_list_mime_parents (const char *mime)
|
||||
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;
|
||||
|
||||
#ifdef XDG_PREFIX
|
||||
#define _xdg_mime_cache_new_from_file XDG_ENTRY(cache_new_from_file)
|
||||
#define _xdg_mime_cache_ref XDG_ENTRY(cache_ref)
|
||||
#define _xdg_mime_cache_unref XDG_ENTRY(cache_unref)
|
||||
#define _xdg_mime_cache_get_max_buffer_extents XDG_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_file XDG_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_types_from_file_name XDG_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_mime_type_subclass XDG_ENTRY(cache_mime_type_subclass)
|
||||
#define _xdg_mime_cache_unalias_mime_type XDG_ENTRY(cache_unalias_mime_type)
|
||||
|
||||
#define _xdg_mime_cache_new_from_file XDG_RESERVED_ENTRY(cache_new_from_file)
|
||||
#define _xdg_mime_cache_ref XDG_RESERVED_ENTRY(cache_ref)
|
||||
#define _xdg_mime_cache_unref XDG_RESERVED_ENTRY(cache_unref)
|
||||
#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_RESERVED_ENTRY(cache_get_mime_type_for_data)
|
||||
#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_RESERVED_ENTRY(cache_get_mime_type_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_RESERVED_ENTRY(cache_list_mime_parents)
|
||||
#define _xdg_mime_cache_mime_type_subclass XDG_RESERVED_ENTRY(cache_mime_type_subclass)
|
||||
#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
|
||||
|
||||
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);
|
||||
const char *_xdg_mime_cache_unalias_mime_type (const char *mime);
|
||||
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__ */
|
||||
|
@ -52,6 +52,7 @@ struct XdgGlobHashNode
|
||||
{
|
||||
xdg_unichar_t character;
|
||||
const char *mime_type;
|
||||
int weight;
|
||||
XdgGlobHashNode *next;
|
||||
XdgGlobHashNode *child;
|
||||
};
|
||||
@ -59,6 +60,7 @@ struct XdgGlobList
|
||||
{
|
||||
const char *data;
|
||||
const char *mime_type;
|
||||
int weight;
|
||||
XdgGlobList *next;
|
||||
};
|
||||
|
||||
@ -107,7 +109,8 @@ _xdg_glob_list_free (XdgGlobList *glob_list)
|
||||
static XdgGlobList *
|
||||
_xdg_glob_list_append (XdgGlobList *glob_list,
|
||||
void *data,
|
||||
const char *mime_type)
|
||||
const char *mime_type,
|
||||
int weight)
|
||||
{
|
||||
XdgGlobList *new_element;
|
||||
XdgGlobList *tmp_element;
|
||||
@ -115,6 +118,7 @@ _xdg_glob_list_append (XdgGlobList *glob_list,
|
||||
new_element = _xdg_glob_list_new ();
|
||||
new_element->data = data;
|
||||
new_element->mime_type = mime_type;
|
||||
new_element->weight = weight;
|
||||
if (glob_list == NULL)
|
||||
return new_element;
|
||||
|
||||
@ -127,23 +131,6 @@ _xdg_glob_list_append (XdgGlobList *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
|
||||
*/
|
||||
|
||||
@ -167,7 +154,7 @@ _xdg_glob_hash_node_dump (XdgGlobHashNode *glob_hash_node,
|
||||
|
||||
printf ("%c", (char)glob_hash_node->character);
|
||||
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
|
||||
printf ("\n");
|
||||
if (glob_hash_node->child)
|
||||
@ -177,14 +164,15 @@ _xdg_glob_hash_node_dump (XdgGlobHashNode *glob_hash_node,
|
||||
}
|
||||
|
||||
static XdgGlobHashNode *
|
||||
_xdg_glob_hash_insert_text (XdgGlobHashNode *glob_hash_node,
|
||||
const char *text,
|
||||
const char *mime_type)
|
||||
_xdg_glob_hash_insert_ucs4 (XdgGlobHashNode *glob_hash_node,
|
||||
xdg_unichar_t *text,
|
||||
const char *mime_type,
|
||||
int weight)
|
||||
{
|
||||
XdgGlobHashNode *node;
|
||||
xdg_unichar_t character;
|
||||
|
||||
character = _xdg_utf8_to_ucs4 (text);
|
||||
character = text[0];
|
||||
|
||||
if ((glob_hash_node == NULL) ||
|
||||
(character < glob_hash_node->character))
|
||||
@ -238,8 +226,8 @@ _xdg_glob_hash_insert_text (XdgGlobHashNode *glob_hash_node,
|
||||
}
|
||||
}
|
||||
|
||||
text = _xdg_utf8_next_char (text);
|
||||
if (*text == '\000')
|
||||
text++;
|
||||
if (*text == 0)
|
||||
{
|
||||
if (node->mime_type)
|
||||
{
|
||||
@ -249,7 +237,7 @@ _xdg_glob_hash_insert_text (XdgGlobHashNode *glob_hash_node,
|
||||
int found_node = FALSE;
|
||||
|
||||
child = node->child;
|
||||
while (child && child->character == '\0')
|
||||
while (child && child->character == 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)
|
||||
{
|
||||
child = _xdg_glob_hash_node_new ();
|
||||
child->character = '\000';
|
||||
child->character = 0;
|
||||
child->mime_type = strdup (mime_type);
|
||||
child->weight = weight;
|
||||
child->child = NULL;
|
||||
child->next = node->child;
|
||||
node->child = child;
|
||||
@ -273,20 +262,45 @@ _xdg_glob_hash_insert_text (XdgGlobHashNode *glob_hash_node,
|
||||
else
|
||||
{
|
||||
node->mime_type = strdup (mime_type);
|
||||
node->weight = weight;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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
|
||||
_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,
|
||||
const char *mime_types[],
|
||||
MimeWeight mime_types[],
|
||||
int n_mime_types)
|
||||
{
|
||||
int n;
|
||||
@ -296,7 +310,7 @@ _xdg_glob_hash_node_lookup_file_name (XdgGlobHashNode *glob_hash_node,
|
||||
if (glob_hash_node == NULL)
|
||||
return 0;
|
||||
|
||||
character = _xdg_utf8_to_ucs4 (file_name);
|
||||
character = file_name[len - 1];
|
||||
if (ignore_case)
|
||||
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)
|
||||
{
|
||||
file_name = _xdg_utf8_next_char (file_name);
|
||||
if (*file_name == '\000')
|
||||
{
|
||||
len--;
|
||||
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)
|
||||
mime_types[n++] = node->mime_type;
|
||||
{
|
||||
mime_types[n].mime = node->mime_type;
|
||||
mime_types[n].weight = node->weight;
|
||||
n++;
|
||||
}
|
||||
node = node->child;
|
||||
while (n < n_mime_types && node && node->character == 0)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
n = _xdg_glob_hash_node_lookup_file_name (node->child,
|
||||
file_name,
|
||||
ignore_case,
|
||||
mime_types,
|
||||
n_mime_types);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
}
|
||||
@ -333,6 +356,14 @@ _xdg_glob_hash_node_lookup_file_name (XdgGlobHashNode *glob_hash_node,
|
||||
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
|
||||
_xdg_glob_hash_lookup_file_name (XdgGlobHash *glob_hash,
|
||||
const char *file_name,
|
||||
@ -340,15 +371,18 @@ _xdg_glob_hash_lookup_file_name (XdgGlobHash *glob_hash,
|
||||
int n_mime_types)
|
||||
{
|
||||
XdgGlobList *list;
|
||||
const char *ptr;
|
||||
char stopchars[128];
|
||||
int i, n;
|
||||
XdgGlobHashNode *node;
|
||||
MimeWeight mimes[10];
|
||||
int n_mimes = 10;
|
||||
xdg_unichar_t *ucs4;
|
||||
int len;
|
||||
|
||||
/* First, check the literals */
|
||||
|
||||
assert (file_name != NULL && n_mime_types > 0);
|
||||
|
||||
n = 0;
|
||||
|
||||
for (list = glob_hash->literal_list; list; list = list->next)
|
||||
{
|
||||
if (strcmp ((const char *)list->data, file_name) == 0)
|
||||
@ -358,37 +392,35 @@ _xdg_glob_hash_lookup_file_name (XdgGlobHash *glob_hash,
|
||||
}
|
||||
}
|
||||
|
||||
i = 0;
|
||||
for (node = glob_hash->simple_node; node; node = node->next)
|
||||
{
|
||||
if (node->character < 128)
|
||||
stopchars[i++] = (char)node->character;
|
||||
}
|
||||
stopchars[i] = '\0';
|
||||
|
||||
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);
|
||||
}
|
||||
ucs4 = _xdg_convert_to_ucs4 (file_name, &len);
|
||||
n = _xdg_glob_hash_node_lookup_file_name (glob_hash->simple_node, ucs4, len, FALSE,
|
||||
mimes, n_mimes);
|
||||
if (n == 0)
|
||||
n = _xdg_glob_hash_node_lookup_file_name (glob_hash->simple_node, ucs4, len, TRUE,
|
||||
mimes, n_mimes);
|
||||
free(ucs4);
|
||||
|
||||
/* FIXME: Not UTF-8 safe */
|
||||
n = 0;
|
||||
if (n == 0)
|
||||
{
|
||||
for (list = glob_hash->full_list; list && n < n_mime_types; list = list->next)
|
||||
{
|
||||
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;
|
||||
}
|
||||
@ -442,7 +474,7 @@ _xdg_glob_determine_type (const char *glob)
|
||||
|
||||
ptr = glob;
|
||||
|
||||
while (*ptr != '\000')
|
||||
while (*ptr != '\0')
|
||||
{
|
||||
if (*ptr == '*' && first_char)
|
||||
maybe_in_simple_glob = TRUE;
|
||||
@ -462,7 +494,8 @@ _xdg_glob_determine_type (const char *glob)
|
||||
void
|
||||
_xdg_glob_hash_append_glob (XdgGlobHash *glob_hash,
|
||||
const char *glob,
|
||||
const char *mime_type)
|
||||
const char *mime_type,
|
||||
int weight)
|
||||
{
|
||||
XdgGlobType type;
|
||||
|
||||
@ -474,13 +507,13 @@ _xdg_glob_hash_append_glob (XdgGlobHash *glob_hash,
|
||||
switch (type)
|
||||
{
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -490,27 +523,34 @@ _xdg_glob_hash_dump (XdgGlobHash *glob_hash)
|
||||
{
|
||||
XdgGlobList *list;
|
||||
printf ("LITERAL STRINGS\n");
|
||||
if (glob_hash->literal_list == NULL)
|
||||
if (!glob_hash || glob_hash->literal_list == NULL)
|
||||
{
|
||||
printf (" None\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
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");
|
||||
if (!glob_hash || glob_hash->simple_node == NULL)
|
||||
{
|
||||
printf (" None\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
_xdg_glob_hash_node_dump (glob_hash->simple_node, 4);
|
||||
}
|
||||
|
||||
printf ("\nFULL GLOBS\n");
|
||||
if (glob_hash->full_list == NULL)
|
||||
if (!glob_hash || glob_hash->full_list == NULL)
|
||||
{
|
||||
printf (" None\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
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 */
|
||||
while (fgets (line, 255, glob_file) != NULL)
|
||||
{
|
||||
char *colon;
|
||||
char *colon, *colon2;
|
||||
char *mimetype, *glob;
|
||||
int weight;
|
||||
|
||||
if (line[0] == '#')
|
||||
continue;
|
||||
|
||||
colon = strchr (line, ':');
|
||||
if (colon == NULL)
|
||||
continue;
|
||||
*(colon++) = '\000';
|
||||
colon[strlen (colon) -1] = '\000';
|
||||
_xdg_glob_hash_append_glob (glob_hash, colon, line);
|
||||
*(colon++) = '\0';
|
||||
colon[strlen (colon) -1] = '\0';
|
||||
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);
|
||||
|
@ -41,13 +41,13 @@ typedef enum
|
||||
|
||||
|
||||
#ifdef XDG_PREFIX
|
||||
#define _xdg_mime_glob_read_from_file XDG_ENTRY(glob_read_from_file)
|
||||
#define _xdg_glob_hash_new XDG_ENTRY(hash_new)
|
||||
#define _xdg_glob_hash_free XDG_ENTRY(hash_free)
|
||||
#define _xdg_glob_hash_lookup_file_name XDG_ENTRY(hash_lookup_file_name)
|
||||
#define _xdg_glob_hash_append_glob XDG_ENTRY(hash_append_glob)
|
||||
#define _xdg_glob_determine_type XDG_ENTRY(determine_type)
|
||||
#define _xdg_glob_hash_dump XDG_ENTRY(hash_dump)
|
||||
#define _xdg_mime_glob_read_from_file XDG_RESERVED_ENTRY(glob_read_from_file)
|
||||
#define _xdg_glob_hash_new XDG_RESERVED_ENTRY(hash_new)
|
||||
#define _xdg_glob_hash_free XDG_RESERVED_ENTRY(hash_free)
|
||||
#define _xdg_glob_hash_lookup_file_name XDG_RESERVED_ENTRY(hash_lookup_file_name)
|
||||
#define _xdg_glob_hash_append_glob XDG_RESERVED_ENTRY(hash_append_glob)
|
||||
#define _xdg_glob_determine_type XDG_RESERVED_ENTRY(determine_type)
|
||||
#define _xdg_glob_hash_dump XDG_RESERVED_ENTRY(hash_dump)
|
||||
#endif
|
||||
|
||||
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);
|
||||
void _xdg_glob_hash_append_glob (XdgGlobHash *glob_hash,
|
||||
const char *glob,
|
||||
const char *mime_type);
|
||||
const char *mime_type,
|
||||
int weight);
|
||||
XdgGlobType _xdg_glob_determine_type (const char *glob);
|
||||
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
|
||||
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;
|
||||
|
||||
#ifdef XDG_PREFIX
|
||||
#define _xdg_utf8_skip XDG_ENTRY(utf8_skip)
|
||||
#define _xdg_utf8_to_ucs4 XDG_ENTRY(utf8_to_ucs4)
|
||||
#define _xdg_ucs4_to_lower XDG_ENTRY(ucs4_to_lower)
|
||||
#define _xdg_utf8_validate XDG_ENTRY(utf8_validate)
|
||||
#define _xdg_get_base_name XDG_ENTRY(get_ase_name)
|
||||
#define _xdg_utf8_skip XDG_RESERVED_ENTRY(utf8_skip)
|
||||
#define _xdg_utf8_to_ucs4 XDG_RESERVED_ENTRY(utf8_to_ucs4)
|
||||
#define _xdg_ucs4_to_lower XDG_RESERVED_ENTRY(ucs4_to_lower)
|
||||
#define _xdg_utf8_validate XDG_RESERVED_ENTRY(utf8_validate)
|
||||
#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
|
||||
|
||||
#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_ucs4_to_lower (xdg_unichar_t 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);
|
||||
|
||||
#endif /* __XDG_MIME_INT_H__ */
|
||||
|
@ -33,12 +33,12 @@
|
||||
typedef struct XdgMimeMagic XdgMimeMagic;
|
||||
|
||||
#ifdef XDG_PREFIX
|
||||
#define _xdg_mime_glob_read_from_file XDG_ENTRY(glob_read_from_file)
|
||||
#define _xdg_mime_magic_new XDG_ENTRY(magic_new)
|
||||
#define _xdg_mime_magic_read_from_file XDG_ENTRY(magic_read_from_file)
|
||||
#define _xdg_mime_magic_free XDG_ENTRY(magic_free)
|
||||
#define _xdg_mime_magic_get_buffer_extents XDG_ENTRY(magic_get_buffer_extents)
|
||||
#define _xdg_mime_magic_lookup_data XDG_ENTRY(magic_lookup_data)
|
||||
#define _xdg_mime_glob_read_from_file XDG_RESERVED_ENTRY(glob_read_from_file)
|
||||
#define _xdg_mime_magic_new XDG_RESERVED_ENTRY(magic_new)
|
||||
#define _xdg_mime_magic_read_from_file XDG_RESERVED_ENTRY(magic_read_from_file)
|
||||
#define _xdg_mime_magic_free XDG_RESERVED_ENTRY(magic_free)
|
||||
#define _xdg_mime_magic_get_buffer_extents XDG_RESERVED_ENTRY(magic_get_buffer_extents)
|
||||
#define _xdg_mime_magic_lookup_data XDG_RESERVED_ENTRY(magic_lookup_data)
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -33,11 +33,11 @@
|
||||
typedef struct XdgParentList XdgParentList;
|
||||
|
||||
#ifdef XDG_PREFIX
|
||||
#define _xdg_mime_parent_read_from_file XDG_ENTRY(parent_read_from_file)
|
||||
#define _xdg_mime_parent_list_new XDG_ENTRY(parent_list_new)
|
||||
#define _xdg_mime_parent_list_free XDG_ENTRY(parent_list_free)
|
||||
#define _xdg_mime_parent_list_lookup XDG_ENTRY(parent_list_lookup)
|
||||
#define _xdg_mime_parent_list_dump XDG_ENTRY(parent_list_dump)
|
||||
#define _xdg_mime_parent_read_from_file XDG_RESERVED_ENTRY(parent_read_from_file)
|
||||
#define _xdg_mime_parent_list_new XDG_RESERVED_ENTRY(parent_list_new)
|
||||
#define _xdg_mime_parent_list_free XDG_RESERVED_ENTRY(parent_list_free)
|
||||
#define _xdg_mime_parent_list_lookup XDG_RESERVED_ENTRY(parent_list_lookup)
|
||||
#define _xdg_mime_parent_list_dump XDG_RESERVED_ENTRY(parent_list_dump)
|
||||
#endif
|
||||
|
||||
void _xdg_mime_parent_read_from_file (XdgParentList *list,
|
||||
|
Loading…
Reference in New Issue
Block a user