Sync with upstream

svn path=/trunk/; revision=6975
This commit is contained in:
Matthias Clasen 2008-06-09 16:45:19 +00:00
parent 7bbfdf3c6b
commit 2bd31c9e6c
15 changed files with 808 additions and 240 deletions

View File

@ -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

View File

@ -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++)
{

View File

@ -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);
}

View File

@ -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);

View File

@ -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,

View File

@ -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);
}
}

View File

@ -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__ */

View File

@ -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);

View 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
View 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
View 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__ */

View File

@ -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;
}
}

View File

@ -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__ */

View File

@ -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

View File

@ -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,