From e55efa35e3b1a0b810f7605028406b3c6b442679 Mon Sep 17 00:00:00 2001 From: Friedrich Beckmann Date: Wed, 11 Oct 2017 15:59:16 +0200 Subject: [PATCH] OSX: Use xdgmime system to guess content type from data Closes: Bug #788401 The problem is described here: https://bugzilla.gnome.org/show_bug.cgi?id=788401 This patch introduces the use of the xdgmime system to guess the content type from data. So you can guess for example the type public.svg-image from the file content of a svg file. This patch only applies to MacOS. A test for the regression is also included. --- gio/Makefile.am | 5 +---- gio/gosxcontenttype.c | 18 +++++++++++++++++- gio/tests/contenttype.c | 30 +++++++++++++++++++++++++++--- 3 files changed, 45 insertions(+), 8 deletions(-) diff --git a/gio/Makefile.am b/gio/Makefile.am index dbc8cbb1b..1ffe0cc6f 100644 --- a/gio/Makefile.am +++ b/gio/Makefile.am @@ -3,10 +3,8 @@ include $(top_srcdir)/glib.mk SUBDIRS = gdbus-2.0/codegen if OS_UNIX -if !OS_COCOA SUBDIRS += xdgmime endif -endif if OS_WIN32_AND_DLL_COMPILATION if MS_LIB_AVAILABLE @@ -262,10 +260,9 @@ SUBDIRS += fam endif if OS_UNIX -if !OS_COCOA platform_libadd += xdgmime/libxdgmime.la platform_deps += xdgmime/libxdgmime.la - +if !OS_COCOA appinfo_headers += gdesktopappinfo.h endif diff --git a/gio/gosxcontenttype.c b/gio/gosxcontenttype.c index 485f5bfb6..89245d1f1 100644 --- a/gio/gosxcontenttype.c +++ b/gio/gosxcontenttype.c @@ -25,6 +25,12 @@ #include +#define XDG_PREFIX _gio_xdg +#include "xdgmime/xdgmime.h" + +/* We lock this mutex whenever we modify global state in this module. */ +G_LOCK_DEFINE_STATIC (gio_xdgmime); + /*< internal > * create_cfstring_from_cstr: @@ -429,7 +435,17 @@ g_content_type_guess (const gchar *filename, if (data && (!filename || !uti || CFStringCompare (uti, CFSTR ("public.data"), 0) == kCFCompareEqualTo)) { - if (looks_like_text (data, data_size)) + const char *sniffed_mimetype; + G_LOCK (gio_xdgmime); + sniffed_mimetype = xdg_mime_get_mime_type_for_data (data, data_size, NULL); + G_UNLOCK (gio_xdgmime); + if (sniffed_mimetype != XDG_MIME_TYPE_UNKNOWN) + { + gchar *uti_str = g_content_type_from_mime_type (sniffed_mimetype); + uti = create_cfstring_from_cstr (uti_str); + g_free (uti_str); + } + if (!uti && looks_like_text (data, data_size)) { if (g_str_has_prefix ((const gchar*)data, "#!/")) uti = CFStringCreateCopy (NULL, CFSTR ("public.script")); diff --git a/gio/tests/contenttype.c b/gio/tests/contenttype.c index 1acbd776f..3589b124a 100644 --- a/gio/tests/contenttype.c +++ b/gio/tests/contenttype.c @@ -56,6 +56,8 @@ test_guess (void) g_free (res); g_free (expected); + /* Sadly OSX just doesn't have as large and robust of a mime type database as Linux */ +#ifndef __APPLE__ res = g_content_type_guess ("foo", data, sizeof (data) - 1, &uncertain); expected = g_content_type_from_mime_type ("text/plain"); g_assert_content_type_equals (expected, res); @@ -63,8 +65,6 @@ test_guess (void) g_free (res); g_free (expected); -/* Sadly OSX just doesn't have as large and robust of a mime type database as Linux */ -#ifndef __APPLE__ res = g_content_type_guess ("foo.desktop", data, sizeof (data) - 1, &uncertain); expected = g_content_type_from_mime_type ("application/x-desktop"); g_assert_content_type_equals (expected, res); @@ -110,6 +110,7 @@ test_guess (void) g_assert (!uncertain); g_free (res); g_free (expected); +#endif res = g_content_type_guess (NULL, (guchar *)"%!PS-Adobe-2.0 EPSF-1.2", 23, &uncertain); expected = g_content_type_from_mime_type ("image/x-eps"); @@ -117,7 +118,6 @@ test_guess (void) g_assert (!uncertain); g_free (res); g_free (expected); -#endif } static void @@ -338,6 +338,29 @@ test_type_is_a_special_case (void) g_assert_true (res); } +static void +test_guess_svg_from_data (void) +{ + const gchar svgfilecontent[] = "\n\ + \n\ +\n"; + + gboolean uncertain = TRUE; + gchar *res = g_content_type_guess (NULL, (guchar *)svgfilecontent, + sizeof (svgfilecontent) - 1, &uncertain); +#ifdef __APPLE__ + g_assert_cmpstr (res, ==, "public.svg-image"); +#elif defined(G_OS_WIN32) + g_test_skip ("svg type detection from content is not implemented on WIN32"); +#else + g_assert_cmpstr (res, ==, "image/svg+xml"); +#endif + g_assert_false (uncertain); + g_free (res); +} + int main (int argc, char *argv[]) { @@ -346,6 +369,7 @@ main (int argc, char *argv[]) g_test_bug_base ("http://bugzilla.gnome.org/"); g_test_add_func ("/contenttype/guess", test_guess); + g_test_add_func ("/contenttype/guess_svg_from_data", test_guess_svg_from_data); g_test_add_func ("/contenttype/unknown", test_unknown); g_test_add_func ("/contenttype/subtype", test_subtype); g_test_add_func ("/contenttype/list", test_list);