231 lines
5.8 KiB
C
231 lines
5.8 KiB
C
/* WirePlumber
|
|
*
|
|
* Copyright © 2019 Collabora Ltd.
|
|
* @author Julian Bouzas <julian.bouzas@collabora.com>
|
|
*
|
|
* SPDX-License-Identifier: MIT
|
|
*/
|
|
|
|
#include "configuration.h"
|
|
#include "private.h"
|
|
|
|
struct _WpConfiguration
|
|
{
|
|
GObject parent;
|
|
|
|
GPtrArray *paths;
|
|
GHashTable *parsers;
|
|
};
|
|
|
|
G_DEFINE_INTERFACE (WpConfigParser, wp_config_parser, G_TYPE_OBJECT)
|
|
|
|
static void
|
|
wp_config_parser_default_init (WpConfigParserInterface *klass)
|
|
{
|
|
}
|
|
|
|
gboolean
|
|
wp_config_parser_add_file (WpConfigParser *self, const char *location)
|
|
{
|
|
g_return_val_if_fail (WP_IS_CONFIG_PARSER (self), FALSE);
|
|
g_return_val_if_fail (WP_CONFIG_PARSER_GET_IFACE (self)->add_file, FALSE);
|
|
|
|
return WP_CONFIG_PARSER_GET_IFACE (self)->add_file (self, location);
|
|
}
|
|
|
|
gconstpointer
|
|
wp_config_parser_get_matched_data (WpConfigParser *self, gpointer data)
|
|
{
|
|
g_return_val_if_fail (WP_IS_CONFIG_PARSER (self), NULL);
|
|
g_return_val_if_fail (WP_CONFIG_PARSER_GET_IFACE (self)->get_matched_data, NULL);
|
|
|
|
return WP_CONFIG_PARSER_GET_IFACE (self)->get_matched_data (self, data);
|
|
}
|
|
|
|
void
|
|
wp_config_parser_reset (WpConfigParser *self)
|
|
{
|
|
g_return_if_fail (WP_IS_CONFIG_PARSER (self));
|
|
g_return_if_fail (WP_CONFIG_PARSER_GET_IFACE (self)->reset);
|
|
|
|
WP_CONFIG_PARSER_GET_IFACE (self)->reset (self);
|
|
}
|
|
|
|
G_DEFINE_TYPE (WpConfiguration, wp_configuration, G_TYPE_OBJECT)
|
|
|
|
static void
|
|
wp_configuration_finalize (GObject * obj)
|
|
{
|
|
WpConfiguration * self = WP_CONFIGURATION (obj);
|
|
|
|
g_clear_pointer (&self->paths, g_ptr_array_unref);
|
|
g_clear_pointer (&self->parsers, g_hash_table_unref);
|
|
|
|
G_OBJECT_CLASS (wp_configuration_parent_class)->finalize (obj);
|
|
}
|
|
|
|
static void
|
|
wp_configuration_init (WpConfiguration * self)
|
|
{
|
|
self->paths = g_ptr_array_new_with_free_func (g_free);
|
|
self->parsers = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
|
|
g_object_unref);
|
|
}
|
|
|
|
static void
|
|
wp_configuration_class_init (WpConfigurationClass * klass)
|
|
{
|
|
GObjectClass *object_class = (GObjectClass *) klass;
|
|
|
|
object_class->finalize = wp_configuration_finalize;
|
|
}
|
|
|
|
WpConfiguration *
|
|
wp_configuration_get_instance (WpCore *core)
|
|
{
|
|
WpConfiguration *self;
|
|
|
|
g_return_val_if_fail (WP_IS_CORE (core), NULL);
|
|
|
|
self = wp_registry_find_object (wp_core_get_registry (core),
|
|
(GEqualFunc) WP_IS_CONFIGURATION, NULL);
|
|
if (!self) {
|
|
self = g_object_new (WP_TYPE_CONFIGURATION, NULL);
|
|
wp_registry_register_object (wp_core_get_registry (core),
|
|
g_object_ref (self));
|
|
}
|
|
|
|
return self;
|
|
}
|
|
|
|
void
|
|
wp_configuration_add_path (WpConfiguration *self, const char *path)
|
|
{
|
|
guint i;
|
|
|
|
g_return_if_fail (self);
|
|
g_return_if_fail (WP_IS_CONFIGURATION (self));
|
|
|
|
/* Make sure the path is not already added */
|
|
for (i = 0; i < self->paths->len; i++) {
|
|
const char *p = g_ptr_array_index(self->paths, i);
|
|
if (g_strcmp0(p, path) == 0)
|
|
return;
|
|
}
|
|
|
|
g_ptr_array_add (self->paths, g_strdup (path));
|
|
}
|
|
|
|
void
|
|
wp_configuration_remove_path (WpConfiguration *self, const char *path)
|
|
{
|
|
guint i;
|
|
|
|
g_return_if_fail (self);
|
|
g_return_if_fail (WP_IS_CONFIGURATION (self));
|
|
|
|
/* Find the path index */
|
|
for (i = 0; i < self->paths->len; i++) {
|
|
const char *p = g_ptr_array_index(self->paths, i);
|
|
if (g_strcmp0(p, path) == 0)
|
|
break;
|
|
}
|
|
|
|
/* Only remove the path if the index is valid */
|
|
if (i < self->paths->len)
|
|
g_ptr_array_remove_index (self->paths, i);
|
|
}
|
|
|
|
gboolean
|
|
wp_configuration_add_extension (WpConfiguration *self, const gchar * extension,
|
|
GType parser_type)
|
|
{
|
|
g_return_val_if_fail (self, FALSE);
|
|
g_return_val_if_fail (WP_IS_CONFIGURATION (self), FALSE);
|
|
|
|
/* create the parser */
|
|
g_autoptr (WpConfigParser) parser = g_object_new (parser_type, FALSE);
|
|
g_return_val_if_fail (WP_IS_CONFIG_PARSER (parser), FALSE);
|
|
|
|
return g_hash_table_insert (self->parsers, g_strdup (extension),
|
|
g_steal_pointer (&parser));
|
|
|
|
}
|
|
|
|
gboolean
|
|
wp_configuration_remove_extension (WpConfiguration *self,
|
|
const gchar * extension)
|
|
{
|
|
g_return_val_if_fail (self, FALSE);
|
|
g_return_val_if_fail (WP_IS_CONFIGURATION (self), FALSE);
|
|
|
|
return g_hash_table_remove (self->parsers, extension);
|
|
}
|
|
|
|
WpConfigParser *
|
|
wp_configuration_get_parser (WpConfiguration *self, const char *extension)
|
|
{
|
|
WpConfigParser *parser = NULL;
|
|
|
|
g_return_val_if_fail (self, NULL);
|
|
g_return_val_if_fail (WP_IS_CONFIGURATION (self), NULL);
|
|
|
|
parser = g_hash_table_lookup (self->parsers, extension);
|
|
return parser ? g_object_ref (parser) : NULL;
|
|
}
|
|
|
|
void
|
|
wp_configuration_reload (WpConfiguration *self, const char *extension)
|
|
{
|
|
guint i;
|
|
const char *path = NULL;
|
|
GDir* conf_dir = NULL;
|
|
GError* error = NULL;
|
|
const gchar *file_name = NULL;
|
|
g_autofree gchar *ext = NULL;
|
|
g_autofree gchar *location = NULL;
|
|
|
|
g_return_if_fail (self);
|
|
g_return_if_fail (WP_IS_CONFIGURATION (self));
|
|
|
|
/* Get the parser for the extension */
|
|
WpConfigParser *parser = g_hash_table_lookup (self->parsers, extension);
|
|
if (!parser) {
|
|
g_warning ("Could not find parser for extension '%s'", extension);
|
|
return;
|
|
}
|
|
|
|
/* Reset the parser */
|
|
wp_config_parser_reset (parser);
|
|
|
|
/* Load extension files in all paths */
|
|
for (i = 0; i < self->paths->len; i++) {
|
|
/* Get the path */
|
|
path = g_ptr_array_index(self->paths, i);
|
|
|
|
/* Open the directory */
|
|
conf_dir = g_dir_open (path, 0, &error);
|
|
if (!conf_dir) {
|
|
g_warning ("Could not open configuration path '%s'", path);
|
|
continue;
|
|
}
|
|
|
|
/* Parse each configuration file matching the extension */
|
|
ext = g_strdup_printf (".%s", extension);
|
|
while ((file_name = g_dir_read_name (conf_dir))) {
|
|
/* Only parse files that have the proper extension */
|
|
if (g_str_has_suffix (file_name, ext)) {
|
|
location = g_build_filename (path, file_name, NULL);
|
|
|
|
g_debug ("loading config file: %s", location);
|
|
|
|
if (!wp_config_parser_add_file (parser, location))
|
|
g_warning ("Failed to parse file '%s'", location);
|
|
}
|
|
}
|
|
|
|
/* Close the directory */
|
|
g_dir_close (conf_dir);
|
|
}
|
|
}
|