Files
wireplumber/lib/wp/configuration.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);
}
}