[glib] OSX: Use xdgmime system to guess content type from data



commit e55efa35e3b1a0b810f7605028406b3c6b442679
Author: Friedrich Beckmann <friedrich beckmann gmx de>
Date:   Wed Oct 11 15:59:16 2017 +0200

    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 dbc8cbb..1ffe0cc 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 485f5bf..89245d1 100644
--- a/gio/gosxcontenttype.c
+++ b/gio/gosxcontenttype.c
@@ -25,6 +25,12 @@
 
 #include <CoreServices/CoreServices.h>
 
+#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 1acbd77..3589b12 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[] = "<svg  xmlns=\"http://www.w3.org/2000/svg\"\
+      xmlns:xlink=\"http://www.w3.org/1999/xlink\";>\n\
+    <rect x=\"10\" y=\"10\" height=\"100\" width=\"100\"\n\
+          style=\"stroke:#ff0000; fill: #0000ff\"/>\n\
+</svg>\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);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]