Synced with upstream

master
Yevgen Muntyan 2007-06-14 00:01:46 -05:00
parent ef02bf8ae3
commit 848a066ae8
15 changed files with 395 additions and 326 deletions

View File

@ -13,12 +13,20 @@ mooxdgmime_sources = \
xdgmimeparent.c \
xdgmimeparent.h
EXTRA_DIST = xdgmimeint.c
noinst_LTLIBRARIES = libxdgmime.la
libxdgmime_la_SOURCES = $(mooxdgmime_sources)
AM_CFLAGS = \
$(MOO_CFLAGS) \
$(MOO_DEBUG_CFLAGS) \
$(MOO_W_NO_SIGN_COMPARE)\
$(MOO_W_NO_UNUSED)
EXTRA_DIST = \
win32/fnmatch.h \
win32/netinet/in.h \
win32/sys/mman.h
if MOO_OS_MINGW
AM_CFLAGS += -I$(srcdir)/win32 -DHAVE_MMAP
endif

View File

@ -0,0 +1,4 @@
#ifndef FNMATCH_H
#define FNMATCH_H
#include <winsock2.h>
#endif /* FNMATCH_H */

View File

@ -0,0 +1,4 @@
#ifndef NETINET_IN_H
#define NETINET_IN_H
#include "mooutils/mooutils-misc.h"
#endif /* NETINET_IN_H */

View File

@ -0,0 +1,9 @@
#ifndef SYS_MMAN_H
#define SYS_MMAN_H
#include "mooutils/mooutils-misc.h"
#define mmap _moo_win32_mmap
#define munmap _moo_win32_munmap
#endif /* SYS_MMAN_H */

View File

@ -43,9 +43,6 @@
#include <sys/time.h>
#include <unistd.h>
#include <assert.h>
#include <errno.h>
#include <mooutils/mooutils-misc.h>
typedef struct XdgDirTimeList XdgDirTimeList;
typedef struct XdgCallbackList XdgCallbackList;
@ -79,6 +76,7 @@ struct XdgDirTimeList
char *directory_name;
int checked;
XdgDirTimeList *next;
XdgMimeCache *cache;
};
struct XdgCallbackList
@ -121,28 +119,6 @@ xdg_dir_time_list_free (XdgDirTimeList *list)
}
}
const char *
xdg_mime_intern_mime_type (const char *mime_type)
{
char *copy;
static GHashTable *hash;
if (!mime_type || mime_type == XDG_MIME_TYPE_UNKNOWN ||
!strcmp (mime_type, XDG_MIME_TYPE_UNKNOWN))
return XDG_MIME_TYPE_UNKNOWN;
if (G_UNLIKELY (!hash))
hash = g_hash_table_new (g_str_hash, g_str_equal);
if (!(copy = g_hash_table_lookup (hash, mime_type)))
{
copy = g_strdup (mime_type);
g_hash_table_insert (hash, copy, copy);
}
return copy;
}
static int
xdg_mime_init_from_directory (const char *directory)
{
@ -152,10 +128,9 @@ xdg_mime_init_from_directory (const char *directory)
assert (directory != NULL);
#ifdef XDG_MIME_USE_CACHE
file_name = g_build_filename (directory, "mime", "mime.cache", NULL);
errno = 0;
if (stat (file_name, &st) == 0)
file_name = malloc (strlen (directory) + strlen ("/mime/mime.cache") + 1);
strcpy (file_name, directory); strcat (file_name, "/mime/mime.cache");
if (XDG_MIME_STAT (file_name, &st) == 0)
{
XdgMimeCache *cache = _xdg_mime_cache_new_from_file (file_name);
@ -165,23 +140,22 @@ xdg_mime_init_from_directory (const char *directory)
list->directory_name = file_name;
list->mtime = st.st_mtime;
list->next = dir_time_list;
list->cache = cache;
dir_time_list = list;
_xdg_mime_caches = realloc (_xdg_mime_caches, sizeof (XdgMimeCache *) * (n_caches + 2));
_xdg_mime_caches[n_caches] = cache;
_xdg_mime_caches = realloc (_xdg_mime_caches, sizeof (XdgMimeCache *) * (n_caches + 2));
_xdg_mime_caches[n_caches] = cache;
_xdg_mime_caches[n_caches + 1] = NULL;
n_caches++;
return FALSE;
}
}
g_free (file_name);
#endif /* XDG_MIME_USE_CACHE */
free (file_name);
file_name = malloc (strlen (directory) + strlen ("/mime/globs") + 1);
strcpy (file_name, directory); strcat (file_name, "/mime/globs");
errno = 0;
if (stat (file_name, &st) == 0)
if (XDG_MIME_STAT (file_name, &st) == 0)
{
_xdg_mime_glob_read_from_file (global_hash, file_name);
@ -198,8 +172,7 @@ xdg_mime_init_from_directory (const char *directory)
file_name = malloc (strlen (directory) + strlen ("/mime/magic") + 1);
strcpy (file_name, directory); strcat (file_name, "/mime/magic");
errno = 0;
if (stat (file_name, &st) == 0)
if (XDG_MIME_STAT (file_name, &st) == 0)
{
_xdg_mime_magic_read_from_file (global_magic, file_name);
@ -242,6 +215,18 @@ xdg_run_command_on_dirs (XdgDirectoryFunc func,
break;
}
static XdgMimeCache *
xdg_lookup_cache_for_file (const char *file_path)
{
XdgDirTimeList *list;
for (list = dir_time_list; list; list = list->next)
if (! strcmp (list->directory_name, file_path))
return list->cache;
return NULL;
}
/* Checks file_path to make sure it has the same mtime as last time it was
* checked. If it has a different mtime, or if the file doesn't exist, it
* returns FALSE.
@ -249,20 +234,15 @@ xdg_run_command_on_dirs (XdgDirectoryFunc func,
* FIXME: This doesn't protect against permission changes.
*/
static int
xdg_check_file (const char *file_path,
int *exists)
xdg_check_file (const char *file_path)
{
struct stat st;
/* If the file exists */
errno = 0;
if (stat (file_path, &st) == 0)
if (XDG_MIME_STAT (file_path, &st) == 0)
{
XdgDirTimeList *list;
if (exists)
*exists = TRUE;
for (list = dir_time_list; list; list = list->next)
{
if (! strcmp (list->directory_name, file_path) &&
@ -276,12 +256,9 @@ xdg_check_file (const char *file_path,
return (list->checked != XDG_CHECKED_VALID);
}
}
return TRUE;
}
if (exists)
*exists = FALSE;
return FALSE;
}
@ -289,30 +266,33 @@ static int
xdg_check_dir (const char *directory,
int *invalid_dir_list)
{
int invalid, exists;
int invalid, has_cache;
char *file_name;
assert (directory != NULL);
#ifdef XDG_MIME_USE_CACHE
/* Check the mime.cache file */
file_name = malloc (strlen (directory) + strlen ("/mime/mime.cache") + 1);
strcpy (file_name, directory); strcat (file_name, "/mime/mime.cache");
invalid = xdg_check_file (file_name, &exists);
invalid = xdg_check_file (file_name);
has_cache = xdg_lookup_cache_for_file (file_name) != NULL;
free (file_name);
if (invalid)
if (has_cache)
{
*invalid_dir_list = TRUE;
return TRUE;
if (invalid)
{
*invalid_dir_list = TRUE;
return TRUE;
}
return FALSE;
}
else if (exists)
return FALSE;
#endif /* XDG_MIME_USE_CACHE */
/* Check the globs file */
file_name = malloc (strlen (directory) + strlen ("/mime/globs") + 1);
strcpy (file_name, directory); strcat (file_name, "/mime/globs");
invalid = xdg_check_file (file_name, NULL);
invalid = xdg_check_file (file_name);
free (file_name);
if (invalid)
{
@ -323,7 +303,7 @@ xdg_check_dir (const char *directory,
/* Check the magic file */
file_name = malloc (strlen (directory) + strlen ("/mime/magic") + 1);
strcpy (file_name, directory); strcat (file_name, "/mime/magic");
invalid = xdg_check_file (file_name, NULL);
invalid = xdg_check_file (file_name);
free (file_name);
if (invalid)
{
@ -431,10 +411,8 @@ xdg_mime_get_mime_type_for_file (const char *file_name,
struct stat *statbuf)
{
const char *mime_type;
/* currently, only a few globs occur twice, and none
* more often, so 5 seems plenty.
*/
const char *mime_types[5];
/* Used to detect whether multiple MIME types match file_name */
const char *mime_types[2];
FILE *file;
unsigned char *data;
int max_extent;
@ -444,9 +422,9 @@ xdg_mime_get_mime_type_for_file (const char *file_name,
int n;
if (file_name == NULL)
return NULL;
return XDG_MIME_TYPE_UNKNOWN;
if (! _xdg_utf8_validate (file_name))
return NULL;
return XDG_MIME_TYPE_UNKNOWN;
xdg_mime_init ();
@ -454,16 +432,14 @@ xdg_mime_get_mime_type_for_file (const char *file_name,
return xdg_mime_intern_mime_type (_xdg_mime_cache_get_mime_type_for_file (file_name, statbuf));
base_name = _xdg_get_base_name (file_name);
n = _xdg_glob_hash_lookup_file_name (global_hash, base_name, mime_types, 5);
n = _xdg_glob_hash_lookup_file_name (global_hash, base_name, mime_types, 2);
if (n == 1)
return xdg_mime_intern_mime_type (mime_types[0]);
if (!statbuf)
{
errno = 0;
if (stat (file_name, &buf) != 0)
if (XDG_MIME_STAT (file_name, &buf) != 0)
return XDG_MIME_TYPE_UNKNOWN;
statbuf = &buf;
@ -505,7 +481,10 @@ xdg_mime_get_mime_type_for_file (const char *file_name,
free (data);
fclose (file);
return xdg_mime_intern_mime_type (mime_type);
if (mime_type)
return xdg_mime_intern_mime_type (mime_type);
return XDG_MIME_TYPE_UNKNOWN;
}
const char *
@ -539,7 +518,8 @@ xdg_mime_is_valid_mime_type (const char *mime_type)
if (slash == mime_type || slash[1] == 0)
return FALSE;
#define IS_VALID_MIME_CHAR(c) ((c) == '.' || (c) == '+' || (c) == '-' || ('a' <= (c) && (c) <= 'z') || ('0' <= (c) && (c) <= '9'))
#define IS_VALID_MIME_CHAR(c) ((c) == '.' || (c) == '+' || (c) == '-' || \
('a' <= (c) && (c) <= 'z') || ('0' <= (c) && (c) <= '9'))
for (p = mime_type; p != slash; p++)
if (!IS_VALID_MIME_CHAR (*p))
return FALSE;
@ -589,7 +569,7 @@ xdg_mime_shutdown (void)
if (_xdg_mime_caches)
{
int i;
for (i = 0; i < n_caches; ++i)
for (i = 0; i < n_caches; i++)
_xdg_mime_cache_unref (_xdg_mime_caches[i]);
free (_xdg_mime_caches);
_xdg_mime_caches = NULL;
@ -606,20 +586,18 @@ int
xdg_mime_get_max_buffer_extents (void)
{
xdg_mime_init ();
if (_xdg_mime_caches)
return _xdg_mime_cache_get_max_buffer_extents ();
return _xdg_mime_magic_get_buffer_extents (global_magic);
}
const char *
xdg_mime_unalias_mime_type (const char *mime_type)
static const char *
_xdg_mime_unalias_mime_type (const char *mime_type)
{
const char *lookup;
xdg_mime_init ();
if (_xdg_mime_caches)
return _xdg_mime_cache_unalias_mime_type (mime_type);
@ -629,16 +607,22 @@ xdg_mime_unalias_mime_type (const char *mime_type)
return mime_type;
}
const char *
xdg_mime_unalias_mime_type (const char *mime_type)
{
xdg_mime_init ();
return _xdg_mime_unalias_mime_type (mime_type);
}
int
xdg_mime_mime_type_equal (const char *mime_a,
const char *mime_b)
_xdg_mime_mime_type_equal (const char *mime_a,
const char *mime_b)
{
const char *unalias_a, *unalias_b;
xdg_mime_init ();
unalias_a = xdg_mime_unalias_mime_type (mime_a);
unalias_b = xdg_mime_unalias_mime_type (mime_b);
unalias_a = _xdg_mime_unalias_mime_type (mime_a);
unalias_b = _xdg_mime_unalias_mime_type (mime_b);
if (strcmp (unalias_a, unalias_b) == 0)
return 1;
@ -647,8 +631,17 @@ xdg_mime_mime_type_equal (const char *mime_a,
}
int
xdg_mime_media_type_equal (const char *mime_a,
const char *mime_b)
xdg_mime_mime_type_equal (const char *mime_a,
const char *mime_b)
{
xdg_mime_init ();
return _xdg_mime_mime_type_equal (mime_a, mime_b);
}
int
_xdg_mime_media_type_equal (const char *mime_a,
const char *mime_b)
{
char *sep;
@ -662,6 +655,15 @@ xdg_mime_media_type_equal (const char *mime_a,
return 0;
}
int
xdg_mime_media_type_equal (const char *mime_a,
const char *mime_b)
{
xdg_mime_init ();
return _xdg_mime_media_type_equal (mime_a, mime_b);
}
#if 0
static int
xdg_mime_is_super_type (const char *mime)
@ -680,48 +682,55 @@ xdg_mime_is_super_type (const char *mime)
#endif
int
xdg_mime_mime_type_subclass (const char *mime,
const char *base)
_xdg_mime_mime_type_subclass (const char *mime,
const char *base)
{
const char *umime, *ubase;
const char **parents;
xdg_mime_init ();
if (_xdg_mime_caches)
return _xdg_mime_cache_mime_type_subclass (mime, base);
umime = xdg_mime_unalias_mime_type (mime);
ubase = xdg_mime_unalias_mime_type (base);
umime = _xdg_mime_unalias_mime_type (mime);
ubase = _xdg_mime_unalias_mime_type (base);
if (strcmp (umime, ubase) == 0)
return 1;
#if 0
#if 0
/* Handle supertypes */
if (xdg_mime_is_super_type (ubase) &&
xdg_mime_media_type_equal (umime, ubase))
_xdg_mime_media_type_equal (umime, ubase))
return 1;
#endif
/* Handle special cases text/plain and application/octet-stream */
if (strcmp (ubase, "text/plain") == 0 &&
if (strcmp (ubase, "text/plain") == 0 &&
strncmp (umime, "text/", 5) == 0)
return 1;
if (strcmp (ubase, "application/octet-stream") == 0)
return 1;
parents = _xdg_mime_parent_list_lookup (parent_list, umime);
for (; parents && *parents; parents++)
{
if (xdg_mime_mime_type_subclass (*parents, ubase))
if (_xdg_mime_mime_type_subclass (*parents, ubase))
return 1;
}
return 0;
}
int
xdg_mime_mime_type_subclass (const char *mime,
const char *base)
{
xdg_mime_init ();
return _xdg_mime_mime_type_subclass (mime, base);
}
char **
xdg_mime_list_mime_parents (const char *mime)
{
@ -753,7 +762,7 @@ xdg_mime_get_mime_parents (const char *mime)
xdg_mime_init ();
umime = xdg_mime_unalias_mime_type (mime);
umime = _xdg_mime_unalias_mime_type (mime);
return _xdg_mime_parent_list_lookup (parent_list, umime);
}
@ -765,6 +774,8 @@ xdg_mime_dump (void)
_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);
}
@ -818,18 +829,3 @@ xdg_mime_remove_callback (int callback_id)
}
}
}
int
_xdg_mime_buffer_is_text (unsigned char *buffer,
int len)
{
const char *end;
gunichar ch;
if (!len || g_utf8_validate ((const char*) buffer, len, &end))
return TRUE;
ch = g_utf8_get_char_validated (end, len - (end - (const char*) buffer));
return ch == -2;
}

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);
@ -47,26 +51,27 @@ typedef void (*XdgMimeDestroy) (void *user_data);
#ifdef XDG_PREFIX
#define xdg_mime_get_mime_type_for_data XDG_ENTRY(get_mime_type_for_data)
#define xdg_mime_get_mime_type_for_file XDG_ENTRY(get_mime_type_for_file)
#define xdg_mime_get_mime_type_from_file_name XDG_ENTRY(get_mime_type_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_media_type_equal XDG_ENTRY(media_type_equal)
#define xdg_mime_mime_type_subclass XDG_ENTRY(mime_type_subclass)
#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_get_max_buffer_extents XDG_ENTRY(get_max_buffer_extents)
#define xdg_mime_shutdown XDG_ENTRY(shutdown)
#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_dump XDG_ENTRY(dump)
#define xdg_mime_intern_mime_type XDG_ENTRY(intern_mime_type)
#endif
#define xdg_mime_get_mime_type_for_data XDG_ENTRY(mime_get_mime_type_for_data)
#define xdg_mime_get_mime_type_for_file XDG_ENTRY(mime_get_mime_type_for_file)
#define xdg_mime_get_mime_type_from_file_name XDG_ENTRY(mime_get_mime_type_from_file_name)
#define xdg_mime_is_valid_mime_type XDG_ENTRY(mime_is_valid_mime_type)
#define xdg_mime_mime_type_equal XDG_ENTRY(mime_mime_type_equal)
#define xdg_mime_media_type_equal XDG_ENTRY(mime_media_type_equal)
#define xdg_mime_mime_type_subclass XDG_ENTRY(mime_mime_type_subclass)
#define xdg_mime_get_mime_parents XDG_ENTRY(mime_get_mime_parents)
#define xdg_mime_list_mime_parents XDG_ENTRY(mime_list_mime_parents)
#define xdg_mime_unalias_mime_type XDG_ENTRY(mime_unalias_mime_type)
#define xdg_mime_get_max_buffer_extents XDG_ENTRY(mime_get_max_buffer_extents)
#define xdg_mime_shutdown XDG_ENTRY(mime_shutdown)
#define xdg_mime_dump XDG_ENTRY(mime_dump)
#define xdg_mime_register_reload_callback XDG_ENTRY(mime_register_reload_callback)
#define xdg_mime_remove_callback XDG_ENTRY(mime_remove_callback)
#define xdg_mime_type_unknown XDG_ENTRY(mime_type_unknown)
const char *xdg_mime_intern_mime_type (const char *mime_type);
#define _xdg_mime_mime_type_equal XDG_RESERVED_ENTRY(mime_mime_type_equal)
#define _xdg_mime_media_type_equal XDG_RESERVED_ENTRY(mime_media_type_equal)
#define _xdg_mime_mime_type_subclass XDG_RESERVED_ENTRY(mime_mime_type_subclass)
#endif
extern const char xdg_mime_type_unknown[];
#define XDG_MIME_TYPE_UNKNOWN xdg_mime_type_unknown
@ -99,6 +104,14 @@ int xdg_mime_register_reload_callback (XdgMimeCallback callback,
XdgMimeDestroy destroy);
void xdg_mime_remove_callback (int callback_id);
/* Private versions of functions that don't call xdg_mime_init () */
int _xdg_mime_mime_type_equal (const char *mime_a,
const char *mime_b);
int _xdg_mime_media_type_equal (const char *mime_a,
const char *mime_b);
int _xdg_mime_mime_type_subclass (const char *mime,
const char *base);
#ifdef __cplusplus
}
#endif /* __cplusplus */

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(mime_alias_read_from_file)
#define _xdg_mime_alias_list_new XDG_RESERVED_ENTRY(mime_alias_list_new)
#define _xdg_mime_alias_list_free XDG_RESERVED_ENTRY(mime_alias_list_free)
#define _xdg_mime_alias_list_lookup XDG_RESERVED_ENTRY(mime_alias_list_lookup)
#define _xdg_mime_alias_list_dump XDG_RESERVED_ENTRY(mime_alias_list_dump)
#endif
void _xdg_mime_alias_read_from_file (XdgAliasList *list,

View File

@ -34,23 +34,15 @@
#include <fcntl.h>
#include <unistd.h>
#include <assert.h>
#include <errno.h>
#ifdef HAVE_FNMATCH_H
#include <fnmatch.h>
#endif
#include <assert.h>
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h> /* for ntohl/ntohs */
#endif
#ifdef __WIN32__
#include <winsock2.h>
#include <mooutils/mooutils-misc.h>
#endif
#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>
@ -85,14 +77,9 @@
struct _XdgMimeCache
{
int ref_count;
char *filename;
size_t size;
char *buffer;
#ifndef HAVE_MMAP
GMappedFile *mf;
#endif
};
#define GET_UINT16(cache,offset) (ntohs(*(xdg_uint16_t*)((cache) + (offset))))
@ -114,10 +101,7 @@ _xdg_mime_cache_unref (XdgMimeCache *cache)
{
#ifdef HAVE_MMAP
munmap (cache->buffer, cache->size);
#else
g_mapped_file_free (cache->mf);
#endif
g_free (cache->filename);
free (cache);
}
}
@ -138,7 +122,7 @@ _xdg_mime_cache_new_from_file (const char *file_name)
if (fd < 0)
return NULL;
if (fstat (fd, &st) < 0 || st.st_size < 4)
if (XDG_MIME_FSTAT (fd, &st) < 0 || st.st_size < 4)
goto done;
buffer = (char *) mmap (NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
@ -159,42 +143,11 @@ _xdg_mime_cache_new_from_file (const char *file_name)
cache->ref_count = 1;
cache->buffer = buffer;
cache->size = st.st_size;
cache->filename = g_strdup (file_name);
done:
if (fd != -1)
close (fd);
#else
GMappedFile *mf;
char *buffer;
size_t length;
mf = g_mapped_file_new (file_name, FALSE, NULL);
if (!mf)
return NULL;
buffer = g_mapped_file_get_contents (mf);
length = g_mapped_file_get_length (mf);
/* Verify version */
if (length < 2 ||
GET_UINT16 (buffer, 0) != MAJOR_VERSION ||
GET_UINT16 (buffer, 2) != MINOR_VERSION)
{
g_mapped_file_free (mf);
return NULL;
}
cache = (XdgMimeCache *) malloc (sizeof (XdgMimeCache));
cache->ref_count = 1;
cache->buffer = buffer;
cache->size = length;
cache->filename = g_strdup (file_name);
cache->mf = mf;
#endif /* HAVE_MMAP */
return cache;
@ -295,8 +248,8 @@ cache_magic_compare_to_data (XdgMimeCache *cache,
for (i = 0; i < n_matchlets; i++)
{
if (cache_magic_matchlet_compare (cache, matchlet_offset + i * 32, data, len) &&
cache->buffer[mimetype_offset])
if (cache_magic_matchlet_compare (cache, matchlet_offset + i * 32,
data, len))
{
*prio = priority;
@ -385,7 +338,7 @@ cache_alias_lookup (const char *alias)
else
{
offset = GET_UINT32 (cache->buffer, list_offset + 4 + 8 * mid + 4);
return cache->buffer[offset] ? cache->buffer + offset : NULL;
return cache->buffer + offset;
}
}
}
@ -425,13 +378,9 @@ cache_glob_lookup_literal (const char *file_name,
else
{
offset = GET_UINT32 (cache->buffer, list_offset + 4 + 8 * mid + 4);
if (cache->buffer[offset])
{
mime_types[0] = cache->buffer + offset;
return 1;
}
else
return 0;
mime_types[0] = (const char *)(cache->buffer + offset);
return 1;
}
}
}
@ -465,8 +414,8 @@ cache_glob_lookup_fnmatch (const char *file_name,
mime_type = cache->buffer + mimetype_offset;
/* FIXME: Not UTF-8 safe */
if (*mime_type && fnmatch (ptr, file_name, 0) == 0)
mime_types[n++] = mime_type;
if (fnmatch (ptr, file_name, 0) == 0)
mime_types[n++] = mime_type;
}
if (n > 0)
@ -516,9 +465,9 @@ cache_glob_node_lookup_suffix (XdgMimeCache *cache,
{
mimetype_offset = GET_UINT32 (cache->buffer, offset + 16 * mid + 4);
n = 0;
if (cache->buffer[mimetype_offset])
mime_types[n++] = cache->buffer + mimetype_offset;
if (cache->buffer[mimetype_offset])
mime_types[n++] = cache->buffer + mimetype_offset;
n_children = GET_UINT32 (cache->buffer, offset + 16 * mid + 8);
child_offset = GET_UINT32 (cache->buffer, offset + 16 * mid + 12);
i = 0;
@ -529,8 +478,7 @@ cache_glob_node_lookup_suffix (XdgMimeCache *cache,
if (match_char != 0)
break;
if (cache->buffer[mimetype_offset])
mime_types[n++] = cache->buffer + mimetype_offset;
mime_types[n++] = cache->buffer + mimetype_offset;
i++;
}
@ -694,20 +642,20 @@ cache_get_mime_type_for_data (const void *data,
match = cache_magic_lookup_data (cache, data, len, &prio,
mime_types, n_mime_types);
if (prio > priority && match && *match)
if (prio > priority)
{
priority = prio;
mime_type = match;
}
}
if (priority > 0 && mime_type && *mime_type)
if (priority > 0)
return mime_type;
for (n = 0; n < n_mime_types; n++)
{
if (mime_types[n] && *mime_types[n])
return mime_types[n];
if (mime_types[n])
return mime_types[n];
}
return XDG_MIME_TYPE_UNKNOWN;
@ -735,10 +683,10 @@ _xdg_mime_cache_get_mime_type_for_file (const char *file_name,
int n;
if (file_name == NULL)
return NULL;
return XDG_MIME_TYPE_UNKNOWN;
if (! _xdg_utf8_validate (file_name))
return NULL;
return XDG_MIME_TYPE_UNKNOWN;
base_name = _xdg_get_base_name (file_name);
n = cache_glob_lookup_file_name (base_name, mime_types, 2);
@ -748,9 +696,7 @@ _xdg_mime_cache_get_mime_type_for_file (const char *file_name,
if (!statbuf)
{
errno = 0;
if (stat (file_name, &buf) != 0)
if (XDG_MIME_STAT (file_name, &buf) != 0)
return XDG_MIME_TYPE_UNKNOWN;
statbuf = &buf;
@ -912,44 +858,45 @@ char **
_xdg_mime_cache_list_mime_parents (const char *mime)
{
int i, j, p;
char *all_parents[128]; /* we'll stop at 128 */
char **result;
char *all_parents[128]; /* we'll stop at 128 */
char **result;
mime = xdg_mime_unalias_mime_type (mime);
p = 0;
p = 0;
for (i = 0; _xdg_mime_caches[i]; i++)
{
{
XdgMimeCache *cache = _xdg_mime_caches[i];
xdg_uint32_t list_offset = GET_UINT32 (cache->buffer, 8);
xdg_uint32_t n_entries = GET_UINT32 (cache->buffer, list_offset);
for (j = 0; j < n_entries; j++)
{
xdg_uint32_t list_offset = GET_UINT32 (cache->buffer, 8);
xdg_uint32_t n_entries = GET_UINT32 (cache->buffer, list_offset);
for (j = 0; j < n_entries; j++)
{
xdg_uint32_t mimetype_offset = GET_UINT32 (cache->buffer, list_offset + 4 + 8 * j);
xdg_uint32_t parents_offset = GET_UINT32 (cache->buffer, list_offset + 4 + 8 * j + 4);
if (strcmp (cache->buffer + mimetype_offset, mime) == 0)
{
if (strcmp (cache->buffer + mimetype_offset, mime) == 0)
{
int k;
xdg_uint32_t parent_mime_offset;
xdg_uint32_t n_parents = GET_UINT32 (cache->buffer, parents_offset);
xdg_uint32_t n_parents = GET_UINT32 (cache->buffer, parents_offset);
for (k = 0; k < n_parents; k++)
for (k = 0; k < n_parents && p < 127; k++)
{
parent_mime_offset = GET_UINT32 (cache->buffer, parents_offset + 4 + 4 * k);
all_parents[p++] = cache->buffer + parent_mime_offset;
}
break;
}
}
}
all_parents[p++] = 0;
result = (char **) malloc (p * sizeof (char *));
memcpy (result, all_parents, p * sizeof (char *));
return result;
}
break;
}
}
}
all_parents[p++] = 0;
result = (char **) malloc (p * sizeof (char *));
memcpy (result, all_parents, p * sizeof (char *));
return result;
}

View File

@ -29,25 +29,23 @@
#include "xdgmime.h"
#define XDG_MIME_USE_CACHE 1
typedef struct _XdgMimeCache XdgMimeCache;
#ifdef XDG_PREFIX
#define _xdg_mime_caches XDG_ENTRY(caches)
#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_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_is_valid_mime_type XDG_ENTRY(cache_is_valid_mime_type)
#define _xdg_mime_cache_mime_type_equal XDG_ENTRY(cache_mime_type_equal)
#define _xdg_mime_cache_media_type_equal XDG_ENTRY(cache_media_type_equal)
#define _xdg_mime_cache_mime_type_subclass XDG_ENTRY(cache_mime_type_subclass)
#define _xdg_mime_cache_list_mime_parents XDG_ENTRY(cache_list_mime_parents)
#define _xdg_mime_cache_unalias_mime_type XDG_ENTRY(cache_unalias_mime_type)
#define _xdg_mime_cache_get_max_buffer_extents XDG_ENTRY(cache_get_max_buffer_extents)
#define _xdg_mime_cache_new_from_file XDG_RESERVED_ENTRY(mime_cache_new_from_file)
#define _xdg_mime_cache_ref XDG_RESERVED_ENTRY(mime_cache_ref)
#define _xdg_mime_cache_unref XDG_RESERVED_ENTRY(mime_cache_unref)
#define _xdg_mime_cache_get_mime_type_for_data XDG_RESERVED_ENTRY(mime_cache_get_mime_type_for_data)
#define _xdg_mime_cache_get_mime_type_for_file XDG_RESERVED_ENTRY(mime_cache_get_mime_type_for_file)
#define _xdg_mime_cache_get_mime_type_from_file_name XDG_RESERVED_ENTRY(mime_cache_get_mime_type_from_file_name)
#define _xdg_mime_cache_is_valid_mime_type XDG_RESERVED_ENTRY(mime_cache_is_valid_mime_type)
#define _xdg_mime_cache_mime_type_equal XDG_RESERVED_ENTRY(mime_cache_mime_type_equal)
#define _xdg_mime_cache_media_type_equal XDG_RESERVED_ENTRY(mime_cache_media_type_equal)
#define _xdg_mime_cache_mime_type_subclass XDG_RESERVED_ENTRY(mime_cache_mime_type_subclass)
#define _xdg_mime_cache_list_mime_parents XDG_RESERVED_ENTRY(mime_cache_list_mime_parents)
#define _xdg_mime_cache_unalias_mime_type XDG_RESERVED_ENTRY(mime_cache_unalias_mime_type)
#define _xdg_mime_cache_get_max_buffer_extents XDG_RESERVED_ENTRY(mime_cache_get_max_buffer_extents)
#define _xdg_mime_caches XDG_RESERVED_ENTRY(mime_caches)
#endif
extern XdgMimeCache **_xdg_mime_caches;

View File

@ -29,19 +29,13 @@
#include <config.h>
#endif
#define _GNU_SOURCE
#include "xdgmimeglob.h"
#include "xdgmimeint.h"
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
#ifdef HAVE_FNMATCH_H
#include <fnmatch.h>
#endif
#ifdef __WIN32__
#include <mooutils/mooutils-misc.h>
#endif
#ifndef FALSE
#define FALSE (0)
@ -314,13 +308,16 @@ _xdg_glob_hash_node_lookup_file_name (XdgGlobHashNode *glob_hash_node,
if (*file_name == '\000')
{
n = 0;
if (node->mime_type)
mime_types[n++] = node->mime_type;
if (node->mime_type != NULL)
mime_types[n++] = node->mime_type;
node = node->child;
while (n < n_mime_types && node && node->character == 0)
{
if (node->mime_type)
if (node->mime_type != NULL)
mime_types[n++] = node->mime_type;
node = node->next;
}
}

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(mime_glob_read_from_file)
#define _xdg_glob_hash_new XDG_RESERVED_ENTRY(glob_hash_new)
#define _xdg_glob_hash_free XDG_RESERVED_ENTRY(glob_hash_free)
#define _xdg_glob_hash_lookup_file_name XDG_RESERVED_ENTRY(glob_hash_lookup_file_name)
#define _xdg_glob_hash_append_glob XDG_RESERVED_ENTRY(glob_hash_append_glob)
#define _xdg_glob_determine_type XDG_RESERVED_ENTRY(glob_determine_type)
#define _xdg_glob_hash_dump XDG_RESERVED_ENTRY(glob_hash_dump)
#endif
void _xdg_mime_glob_read_from_file (XdgGlobHash *glob_hash,

View File

@ -29,8 +29,7 @@
#define __XDG_MIME_INT_H__
#include "xdgmime.h"
#include <glib.h>
#include <string.h>
#ifndef FALSE
#define FALSE (0)
@ -40,29 +39,83 @@
#define TRUE (!FALSE)
#endif
typedef gunichar xdg_unichar_t;
typedef guint8 xdg_uchar8_t;
typedef guint16 xdg_uint16_t;
typedef guint32 xdg_uint32_t;
/* FIXME: Needs to be configure check */
typedef unsigned int xdg_unichar_t;
typedef unsigned char xdg_uchar8_t;
typedef unsigned short xdg_uint16_t;
typedef unsigned int xdg_uint32_t;
#if 0 && defined(XDG_PREFIX)
#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_base_name)
#define _xdg_utf8_skip XDG_ENTRY(utf8_skip)
#ifdef XDG_PREFIX
#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)
#endif
#define SWAP_BE16_TO_LE16 GUINT16_SWAP_LE_BE
#define SWAP_BE32_TO_LE32 GUINT32_SWAP_LE_BE
#define SWAP_BE16_TO_LE16(val) (xdg_uint16_t)(((xdg_uint16_t)(val) << 8)|((xdg_uint16_t)(val) >> 8))
#define SWAP_BE32_TO_LE32(val) (xdg_uint32_t)((((xdg_uint32_t)(val) & 0xFF000000U) >> 24) | \
(((xdg_uint32_t)(val) & 0x00FF0000U) >> 8) | \
(((xdg_uint32_t)(val) & 0x0000FF00U) << 8) | \
(((xdg_uint32_t)(val) & 0x000000FFU) << 24))
/* UTF-8 utils
*/
#define _xdg_utf8_next_char g_utf8_next_char
#define _xdg_utf8_to_ucs4 g_utf8_get_char
#define _xdg_ucs4_to_lower g_unichar_tolower
extern const char *const _xdg_utf8_skip;
#define _xdg_utf8_next_char(p) (char *)((p) + _xdg_utf8_skip[*(unsigned char *)(p)])
#define _xdg_utf8_char_size(p) (int) (_xdg_utf8_skip[*(unsigned char *)(p)])
#define _xdg_utf8_validate(s) g_utf8_validate ((s), -1, NULL)
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);
const char *_xdg_get_base_name (const char *file_name);
/* start muntyan's stuff */
#include <string.h>
#include <errno.h>
#include "mooutils/mooutils-misc.h"
/* make xdgmime use glib */
#undef malloc
#undef realloc
#undef free
#undef strdup
#undef calloc
#define malloc g_try_malloc
#define realloc g_try_realloc
#define free g_free
#define strdup g_strdup
#define calloc(nmemb,size) g_malloc0 ((nmemb)*(size))
#undef _xdg_utf8_skip
#undef _xdg_utf8_to_ucs4
#undef _xdg_ucs4_to_lower
#undef _xdg_utf8_validate
#undef _xdg_get_base_name
#undef _xdg_utf8_next_char
#undef _xdg_utf8_char_size
#undef SWAP_BE16_TO_LE16
#undef SWAP_BE32_TO_LE32
#define _xdg_utf8_to_ucs4 g_utf8_get_char
#define _xdg_ucs4_to_lower g_unichar_tolower
#define _xdg_utf8_validate(s) (g_utf8_validate(s, -1, NULL))
#define _xdg_utf8_next_char(p) g_utf8_next_char(p)
#define SWAP_BE16_TO_LE16(val) GUINT16_SWAP_LE_BE(val)
#define SWAP_BE32_TO_LE32(val) GUINT32_SWAP_LE_BE(val)
inline static const char *
xdg_mime_intern_mime_type (const char *mime_type)
{
if (!mime_type || mime_type == XDG_MIME_TYPE_UNKNOWN ||
!strcmp (mime_type, XDG_MIME_TYPE_UNKNOWN))
return XDG_MIME_TYPE_UNKNOWN;
else
return _moo_intern_string (mime_type);
}
inline static const char *
_xdg_get_base_name (const char *file_name)
@ -80,28 +133,47 @@ _xdg_get_base_name (const char *file_name)
return base_name + 1;
}
/*
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);
const char *_xdg_get_base_name (const char *file_name);
*/
inline static int
_xdg_mime_buffer_is_text (unsigned char *buffer,
int len)
{
const char *end;
gunichar ch;
#ifdef XDG_PREFIX
#define _xdg_mime_buffer_is_text XDG_ENTRY(buffer_is_text)
if (!len || g_utf8_validate ((const char*) buffer, len, &end))
return TRUE;
ch = g_utf8_get_char_validated (end, len - (end - (const char*) buffer));
return ch == -2;
}
#ifdef __WIN32__
#include <glib/gstdio.h>
inline static int
_xdg_mime_stat (const char *path,
struct stat *buf)
{
errno = 0;
return g_stat (path, buf);
}
inline static int
_xdg_mime_fstat (int fd,
struct stat *buf)
{
errno = 0;
return fstat (fd, buf);
}
#define XDG_MIME_STAT _xdg_mime_stat
#define XDG_MIME_FSTAT _xdg_mime_fstat
#else
#define XDG_MIME_STAT stat
#define XDG_MIME_FSTAT fstat
#endif
int _xdg_mime_buffer_is_text (unsigned char *buffer,
int len);
#undef malloc
#undef realloc
#undef free
#undef strdup
#undef calloc
#define malloc g_try_malloc
#define realloc g_try_realloc
#define free g_free
#define strdup g_strdup
#define calloc(nmemb,size) g_malloc0 ((nmemb)*(size))
/* end muntyan's stuff */
#endif /* __XDG_MIME_INT_H__ */

View File

@ -29,7 +29,6 @@
#include <config.h>
#endif
#define _GNU_SOURCE
#include <assert.h>
#include "xdgmimemagic.h"
#include "xdgmimeint.h"
@ -39,9 +38,6 @@
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#ifdef __WIN32__
#include <mooutils/mooutils-misc.h>
#endif
#ifndef FALSE
#define FALSE (0)
@ -51,6 +47,10 @@
#define TRUE (!FALSE)
#endif
#if !defined getc_unlocked && !defined HAVE_GETC_UNLOCKED
#define getc_unlocked(fp) getc (fp)
#endif
typedef struct XdgMimeMagicMatch XdgMimeMagicMatch;
typedef struct XdgMimeMagicMatchlet XdgMimeMagicMatchlet;
@ -476,11 +476,32 @@ _xdg_mime_magic_parse_magic_line (FILE *magic_file,
/* We clean up the matchlet, byte swapping if needed */
if (matchlet->word_size > 1)
{
#if LITTLE_ENDIAN
int i;
#endif
if (matchlet->value_length % matchlet->word_size != 0)
{
_xdg_mime_magic_matchlet_free (matchlet);
return XDG_MIME_MAGIC_ERROR;
}
/* FIXME: need to get this defined in a <config.h> style file */
#if LITTLE_ENDIAN
for (i = 0; i < matchlet->value_length; i = i + matchlet->word_size)
{
if (matchlet->word_size == 2)
*((xdg_uint16_t *) matchlet->value + i) = SWAP_BE16_TO_LE16 (*((xdg_uint16_t *) (matchlet->value + i)));
else if (matchlet->word_size == 4)
*((xdg_uint32_t *) matchlet->value + i) = SWAP_BE32_TO_LE32 (*((xdg_uint32_t *) (matchlet->value + i)));
if (matchlet->mask)
{
if (matchlet->word_size == 2)
*((xdg_uint16_t *) matchlet->mask + i) = SWAP_BE16_TO_LE16 (*((xdg_uint16_t *) (matchlet->mask + i)));
else if (matchlet->word_size == 4)
*((xdg_uint32_t *) matchlet->mask + i) = SWAP_BE32_TO_LE32 (*((xdg_uint32_t *) (matchlet->mask + i)));
}
}
#endif
}
matchlet->next = match->matchlet;
@ -654,13 +675,13 @@ _xdg_mime_magic_lookup_data (XdgMimeMagic *mime_magic,
if (_xdg_mime_magic_match_compare_to_data (match, data, len))
{
if (!had_match || match->priority > priority ||
(mime_type != NULL && xdg_mime_mime_type_subclass (match->mime_type, mime_type)))
(mime_type != NULL && _xdg_mime_mime_type_subclass (match->mime_type, mime_type)))
{
mime_type = match->mime_type;
priority = match->priority;
}
else if (had_match && match->priority == priority &&
!xdg_mime_mime_type_subclass (mime_type, match->mime_type))
!_xdg_mime_mime_type_subclass (mime_type, match->mime_type))
/* multiple unrelated patterns with the same priority matched,
* so we can't tell what type this is. */
mime_type = NULL;
@ -672,7 +693,7 @@ _xdg_mime_magic_lookup_data (XdgMimeMagic *mime_magic,
for (n = 0; n < n_mime_types; n++)
{
if (mime_types[n] &&
xdg_mime_mime_type_equal (mime_types[n], match->mime_type))
_xdg_mime_mime_type_equal (mime_types[n], match->mime_type))
mime_types[n] = NULL;
}
}

View File

@ -33,11 +33,11 @@
typedef struct XdgMimeMagic XdgMimeMagic;
#ifdef XDG_PREFIX
#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_magic_new XDG_RESERVED_ENTRY(mime_magic_new)
#define _xdg_mime_magic_read_from_file XDG_RESERVED_ENTRY(mime_magic_read_from_file)
#define _xdg_mime_magic_free XDG_RESERVED_ENTRY(mime_magic_free)
#define _xdg_mime_magic_get_buffer_extents XDG_RESERVED_ENTRY(mime_magic_get_buffer_extents)
#define _xdg_mime_magic_lookup_data XDG_RESERVED_ENTRY(mime_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(mime_parent_read_from_file)
#define _xdg_mime_parent_list_new XDG_RESERVED_ENTRY(mime_parent_list_new)
#define _xdg_mime_parent_list_free XDG_RESERVED_ENTRY(mime_parent_list_free)
#define _xdg_mime_parent_list_lookup XDG_RESERVED_ENTRY(mime_parent_list_lookup)
#define _xdg_mime_parent_list_dump XDG_RESERVED_ENTRY(mime_parent_list_dump)
#endif
void _xdg_mime_parent_read_from_file (XdgParentList *list,