mirror of
https://gitlab.freedesktop.org/pipewire/wireplumber.git
synced 2026-04-26 11:30:43 +02:00
lib: introduce WpConfiguration
The purpose of this change is to have a generic API that allows modules to read configuration data from files under a specific directory. Since we can have many types of configuration files, this new class maps file extensions with generic parsers defined in the modules, giving modules full freedom to parse any kind of data.
This commit is contained in:
parent
9a9d773b06
commit
77ec4c548c
4 changed files with 279 additions and 0 deletions
225
lib/wp/configuration.c
Normal file
225
lib/wp/configuration.c
Normal file
|
|
@ -0,0 +1,225 @@
|
|||
/* 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_core_find_object (core, (GEqualFunc) WP_IS_CONFIGURATION, NULL);
|
||||
if (!self) {
|
||||
self = g_object_new (WP_TYPE_CONFIGURATION, NULL);
|
||||
wp_core_register_object (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);
|
||||
if (!wp_config_parser_add_file (parser, location))
|
||||
g_warning ("Failed to parse file '%s'", location);
|
||||
}
|
||||
}
|
||||
|
||||
/* Close the directory */
|
||||
g_dir_close (conf_dir);
|
||||
}
|
||||
}
|
||||
51
lib/wp/configuration.h
Normal file
51
lib/wp/configuration.h
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
/* WirePlumber
|
||||
*
|
||||
* Copyright © 2019 Collabora Ltd.
|
||||
* @author Julian Bouzas <julian.bouzas@collabora.com>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#ifndef __WIREPLUMBER_CONFIGURATION_H__
|
||||
#define __WIREPLUMBER_CONFIGURATION_H__
|
||||
|
||||
#include "core.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define WP_TYPE_CONFIG_PARSER (wp_config_parser_get_type ())
|
||||
G_DECLARE_INTERFACE (WpConfigParser, wp_config_parser, WP,
|
||||
CONFIG_PARSER, GObject)
|
||||
|
||||
struct _WpConfigParserInterface
|
||||
{
|
||||
GTypeInterface parent;
|
||||
|
||||
gboolean (*add_file) (WpConfigParser *parser, const gchar *name);
|
||||
gconstpointer (*get_matched_data) (WpConfigParser *parser, gpointer data);
|
||||
void (*reset) (WpConfigParser *parser);
|
||||
};
|
||||
|
||||
gboolean wp_config_parser_add_file (WpConfigParser *self, const char *location);
|
||||
gconstpointer wp_config_parser_get_matched_data (WpConfigParser *self,
|
||||
gpointer data);
|
||||
void wp_config_parser_reset (WpConfigParser *self);
|
||||
|
||||
#define WP_TYPE_CONFIGURATION (wp_configuration_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (WpConfiguration, wp_configuration, WP, CONFIGURATION,
|
||||
GObject)
|
||||
|
||||
WpConfiguration * wp_configuration_get_instance (WpCore *core);
|
||||
void wp_configuration_add_path (WpConfiguration *self, const char *path);
|
||||
void wp_configuration_remove_path (WpConfiguration *self, const char *path);
|
||||
gboolean wp_configuration_add_extension (WpConfiguration *self,
|
||||
const gchar * extension, GType parser_type);
|
||||
gboolean wp_configuration_remove_extension (WpConfiguration *self,
|
||||
const gchar * extension);
|
||||
WpConfigParser *wp_configuration_get_parser (WpConfiguration *self,
|
||||
const char *extension);
|
||||
void wp_configuration_reload (WpConfiguration *self, const char *extension);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
wp_lib_sources = [
|
||||
'configuration.c',
|
||||
'core.c',
|
||||
'endpoint.c',
|
||||
'error.c',
|
||||
|
|
@ -19,6 +20,7 @@ wp_lib_sources = [
|
|||
]
|
||||
|
||||
wp_lib_headers = [
|
||||
'configuration.h',
|
||||
'core.h',
|
||||
'endpoint.h',
|
||||
'error.h',
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include "configuration.h"
|
||||
#include "core.h"
|
||||
#include "endpoint.h"
|
||||
#include "error.h"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue