mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-24 14:36:13 +01:00
gcontenttype: Add g_content_type_{get,set}_mime_dirs() API
This allows the list of directories which contain MIME data to be set, separately from the list of directories returned by g_get_user_data_home() and g_get_system_data_dirs(). While the latter are overridden for a unit test, we don’t have access to the system MIME registry, which can sometimes be useful for tests which need to know about standard MIME associations from shared-mime-info. Allow g_content_type_set_mime_dirs() to be used from unit tests to allow them to use the system MIME registry again, or to allow them to be pointed to another custom registry. Signed-off-by: Philip Withnall <withnall@endlessm.com>
This commit is contained in:
parent
df2f13f89b
commit
b06fa34bb1
@ -55,6 +55,8 @@
|
|||||||
#define XDG_PREFIX _gio_xdg
|
#define XDG_PREFIX _gio_xdg
|
||||||
#include "xdgmime/xdgmime.h"
|
#include "xdgmime/xdgmime.h"
|
||||||
|
|
||||||
|
static void tree_magic_schedule_reload (void);
|
||||||
|
|
||||||
/* We lock this mutex whenever we modify global state in this module. */
|
/* We lock this mutex whenever we modify global state in this module. */
|
||||||
G_LOCK_DEFINE_STATIC (gio_xdgmime);
|
G_LOCK_DEFINE_STATIC (gio_xdgmime);
|
||||||
|
|
||||||
@ -111,6 +113,106 @@ _g_unix_content_type_get_parents (const gchar *type)
|
|||||||
return (gchar **)g_ptr_array_free (array, FALSE);
|
return (gchar **)g_ptr_array_free (array, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
G_LOCK_DEFINE_STATIC (global_mime_dirs);
|
||||||
|
static gchar **global_mime_dirs = NULL;
|
||||||
|
|
||||||
|
static void
|
||||||
|
_g_content_type_set_mime_dirs_locked (const char * const *dirs)
|
||||||
|
{
|
||||||
|
g_clear_pointer (&global_mime_dirs, g_strfreev);
|
||||||
|
|
||||||
|
if (dirs != NULL)
|
||||||
|
{
|
||||||
|
global_mime_dirs = g_strdupv ((gchar **) dirs);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GPtrArray *mime_dirs = g_ptr_array_new_with_free_func (g_free);
|
||||||
|
const gchar * const *system_dirs = g_get_system_data_dirs ();
|
||||||
|
|
||||||
|
g_ptr_array_add (mime_dirs, g_build_filename (g_get_user_data_dir (), "mime", NULL));
|
||||||
|
for (; *system_dirs != NULL; system_dirs++)
|
||||||
|
g_ptr_array_add (mime_dirs, g_build_filename (*system_dirs, "mime", NULL));
|
||||||
|
g_ptr_array_add (mime_dirs, NULL); /* NULL terminator */
|
||||||
|
|
||||||
|
global_mime_dirs = (gchar **) g_ptr_array_free (mime_dirs, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
xdg_mime_set_dirs ((const gchar * const *) global_mime_dirs);
|
||||||
|
tree_magic_schedule_reload ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* g_content_type_set_mime_dirs:
|
||||||
|
* @dirs: (array zero-terminated=1) (nullable): %NULL-terminated list of
|
||||||
|
* directories to load MIME data from, including any `mime/` subdirectory,
|
||||||
|
* and with the first directory to try listed first
|
||||||
|
*
|
||||||
|
* Set the list of directories used by GIO to load the MIME database.
|
||||||
|
* If @dirs is %NULL, the directories used are the default:
|
||||||
|
*
|
||||||
|
* - the `mime` subdirectory of the directory in `$XDG_DATA_HOME`
|
||||||
|
* - the `mime` subdirectory of every directory in `$XDG_DATA_DIRS`
|
||||||
|
*
|
||||||
|
* This function is intended to be used when writing tests that depend on
|
||||||
|
* information stored in the MIME database, in order to control the data.
|
||||||
|
*
|
||||||
|
* Typically, in case your tests use %G_TEST_OPTION_ISOLATE_DIRS, but they
|
||||||
|
* depend on the system’s MIME database, you should call this function
|
||||||
|
* with @dirs set to %NULL before calling g_test_init(), for instance:
|
||||||
|
*
|
||||||
|
* |[<!-- language="C" -->
|
||||||
|
* // Load MIME data from the system
|
||||||
|
* g_content_type_set_mime_dirs (NULL);
|
||||||
|
* // Isolate the environment
|
||||||
|
* g_test_init (&argc, &argv, G_TEST_OPTION_ISOLATE_DIRS, NULL);
|
||||||
|
*
|
||||||
|
* …
|
||||||
|
*
|
||||||
|
* return g_test_run ();
|
||||||
|
* ]|
|
||||||
|
*
|
||||||
|
* Since: 2.60
|
||||||
|
*/
|
||||||
|
/*< private >*/
|
||||||
|
void
|
||||||
|
g_content_type_set_mime_dirs (const gchar * const *dirs)
|
||||||
|
{
|
||||||
|
G_LOCK (global_mime_dirs);
|
||||||
|
_g_content_type_set_mime_dirs_locked (dirs);
|
||||||
|
G_UNLOCK (global_mime_dirs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* g_content_type_get_mime_dirs:
|
||||||
|
*
|
||||||
|
* Get the list of directories which MIME data is loaded from. See
|
||||||
|
* g_content_type_set_mime_dirs() for details.
|
||||||
|
*
|
||||||
|
* Returns: (transfer none) (array zero-terminated=1): %NULL-terminated list of
|
||||||
|
* directories to load MIME data from, including any `mime/` subdirectory,
|
||||||
|
* and with the first directory to try listed first
|
||||||
|
* Since: 2.60
|
||||||
|
*/
|
||||||
|
/*< private >*/
|
||||||
|
const gchar * const *
|
||||||
|
g_content_type_get_mime_dirs (void)
|
||||||
|
{
|
||||||
|
const gchar * const *mime_dirs;
|
||||||
|
|
||||||
|
G_LOCK (global_mime_dirs);
|
||||||
|
|
||||||
|
if (global_mime_dirs == NULL)
|
||||||
|
_g_content_type_set_mime_dirs_locked (NULL);
|
||||||
|
|
||||||
|
mime_dirs = (const gchar * const *) global_mime_dirs;
|
||||||
|
|
||||||
|
G_UNLOCK (global_mime_dirs);
|
||||||
|
|
||||||
|
g_assert (mime_dirs != NULL);
|
||||||
|
return mime_dirs;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* g_content_type_equals:
|
* g_content_type_equals:
|
||||||
* @type1: a content type string
|
* @type1: a content type string
|
||||||
@ -306,7 +408,7 @@ load_comment_for_mime_helper (const char *dir,
|
|||||||
mime_info_text
|
mime_info_text
|
||||||
};
|
};
|
||||||
|
|
||||||
filename = g_build_filename (dir, "mime", basename, NULL);
|
filename = g_build_filename (dir, basename, NULL);
|
||||||
|
|
||||||
res = g_file_get_contents (filename, &data, &len, NULL);
|
res = g_file_get_contents (filename, &data, &len, NULL);
|
||||||
g_free (filename);
|
g_free (filename);
|
||||||
@ -328,22 +430,14 @@ load_comment_for_mime_helper (const char *dir,
|
|||||||
static char *
|
static char *
|
||||||
load_comment_for_mime (const char *mimetype)
|
load_comment_for_mime (const char *mimetype)
|
||||||
{
|
{
|
||||||
const char * const* dirs;
|
const char * const *dirs;
|
||||||
char *basename;
|
char *basename;
|
||||||
char *comment;
|
char *comment;
|
||||||
int i;
|
gsize i;
|
||||||
|
|
||||||
basename = g_strdup_printf ("%s.xml", mimetype);
|
basename = g_strdup_printf ("%s.xml", mimetype);
|
||||||
|
|
||||||
comment = load_comment_for_mime_helper (g_get_user_data_dir (), basename);
|
dirs = g_content_type_get_mime_dirs ();
|
||||||
if (comment)
|
|
||||||
{
|
|
||||||
g_free (basename);
|
|
||||||
return comment;
|
|
||||||
}
|
|
||||||
|
|
||||||
dirs = g_get_system_data_dirs ();
|
|
||||||
|
|
||||||
for (i = 0; dirs[i] != NULL; i++)
|
for (i = 0; dirs[i] != NULL; i++)
|
||||||
{
|
{
|
||||||
comment = load_comment_for_mime_helper (dirs[i], basename);
|
comment = load_comment_for_mime_helper (dirs[i], basename);
|
||||||
@ -780,10 +874,10 @@ enumerate_mimetypes_dir (const char *dir,
|
|||||||
{
|
{
|
||||||
DIR *d;
|
DIR *d;
|
||||||
struct dirent *ent;
|
struct dirent *ent;
|
||||||
char *mimedir;
|
const char *mimedir;
|
||||||
char *name;
|
char *name;
|
||||||
|
|
||||||
mimedir = g_build_filename (dir, "mime", NULL);
|
mimedir = dir;
|
||||||
|
|
||||||
d = opendir (mimedir);
|
d = opendir (mimedir);
|
||||||
if (d)
|
if (d)
|
||||||
@ -800,8 +894,6 @@ enumerate_mimetypes_dir (const char *dir,
|
|||||||
}
|
}
|
||||||
closedir (d);
|
closedir (d);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free (mimedir);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -817,18 +909,16 @@ enumerate_mimetypes_dir (const char *dir,
|
|||||||
GList *
|
GList *
|
||||||
g_content_types_get_registered (void)
|
g_content_types_get_registered (void)
|
||||||
{
|
{
|
||||||
const char * const* dirs;
|
const char * const *dirs;
|
||||||
GHashTable *mimetypes;
|
GHashTable *mimetypes;
|
||||||
GHashTableIter iter;
|
GHashTableIter iter;
|
||||||
gpointer key;
|
gpointer key;
|
||||||
int i;
|
gsize i;
|
||||||
GList *l;
|
GList *l;
|
||||||
|
|
||||||
mimetypes = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
mimetypes = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
||||||
|
|
||||||
enumerate_mimetypes_dir (g_get_user_data_dir (), mimetypes);
|
dirs = g_content_type_get_mime_dirs ();
|
||||||
dirs = g_get_system_data_dirs ();
|
|
||||||
|
|
||||||
for (i = 0; dirs[i] != NULL; i++)
|
for (i = 0; dirs[i] != NULL; i++)
|
||||||
enumerate_mimetypes_dir (dirs[i], mimetypes);
|
enumerate_mimetypes_dir (dirs[i], mimetypes);
|
||||||
|
|
||||||
@ -1030,7 +1120,7 @@ read_tree_magic_from_directory (const gchar *prefix)
|
|||||||
TreeMatchlet *matchlet;
|
TreeMatchlet *matchlet;
|
||||||
gint depth;
|
gint depth;
|
||||||
|
|
||||||
filename = g_build_filename (prefix, "mime", "treemagic", NULL);
|
filename = g_build_filename (prefix, "treemagic", NULL);
|
||||||
|
|
||||||
if (g_file_get_contents (filename, &text, &len, NULL))
|
if (g_file_get_contents (filename, &text, &len, NULL))
|
||||||
{
|
{
|
||||||
@ -1068,11 +1158,16 @@ read_tree_magic_from_directory (const gchar *prefix)
|
|||||||
g_free (filename);
|
g_free (filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tree_magic_schedule_reload (void)
|
||||||
|
{
|
||||||
|
need_reload = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
xdg_mime_reload (void *user_data)
|
xdg_mime_reload (void *user_data)
|
||||||
{
|
{
|
||||||
need_reload = TRUE;
|
tree_magic_schedule_reload ();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1086,9 +1181,7 @@ static void
|
|||||||
tree_magic_init (void)
|
tree_magic_init (void)
|
||||||
{
|
{
|
||||||
static gboolean initialized = FALSE;
|
static gboolean initialized = FALSE;
|
||||||
const gchar *dir;
|
gsize i;
|
||||||
const gchar * const * dirs;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (!initialized)
|
if (!initialized)
|
||||||
{
|
{
|
||||||
@ -1100,14 +1193,14 @@ tree_magic_init (void)
|
|||||||
|
|
||||||
if (need_reload)
|
if (need_reload)
|
||||||
{
|
{
|
||||||
|
const char * const *dirs;
|
||||||
|
|
||||||
need_reload = FALSE;
|
need_reload = FALSE;
|
||||||
|
|
||||||
tree_magic_shutdown ();
|
tree_magic_shutdown ();
|
||||||
|
|
||||||
dir = g_get_user_data_dir ();
|
dirs = g_content_type_get_mime_dirs ();
|
||||||
read_tree_magic_from_directory (dir);
|
for (i = 0; dirs[i] != NULL; i++)
|
||||||
dirs = g_get_system_data_dirs ();
|
|
||||||
for (i = 0; dirs[i]; i++)
|
|
||||||
read_tree_magic_from_directory (dirs[i]);
|
read_tree_magic_from_directory (dirs[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -69,6 +69,12 @@ gchar ** g_content_type_guess_for_tree (GFile *root);
|
|||||||
GLIB_AVAILABLE_IN_ALL
|
GLIB_AVAILABLE_IN_ALL
|
||||||
GList * g_content_types_get_registered (void);
|
GList * g_content_types_get_registered (void);
|
||||||
|
|
||||||
|
/*< private >*/
|
||||||
|
GLIB_AVAILABLE_IN_2_60
|
||||||
|
const gchar * const *g_content_type_get_mime_dirs (void);
|
||||||
|
GLIB_AVAILABLE_IN_2_60
|
||||||
|
void g_content_type_set_mime_dirs (const gchar * const *dirs);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __G_CONTENT_TYPE_H__ */
|
#endif /* __G_CONTENT_TYPE_H__ */
|
||||||
|
Loading…
Reference in New Issue
Block a user