modules: add config endpoint module
This commit is contained in:
223
modules/module-config-endpoint/parser-streams.c
Normal file
223
modules/module-config-endpoint/parser-streams.c
Normal file
@@ -0,0 +1,223 @@
|
||||
/* WirePlumber
|
||||
*
|
||||
* Copyright © 2019 Collabora Ltd.
|
||||
* @author Julian Bouzas <julian.bouzas@collabora.com>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include <wptoml/wptoml.h>
|
||||
|
||||
#include <pipewire/pipewire.h>
|
||||
|
||||
#include "parser-streams.h"
|
||||
|
||||
struct _WpParserStreams
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
GPtrArray *datas;
|
||||
};
|
||||
|
||||
const struct WpParserStreamsStreamData *
|
||||
wp_parser_streams_find_stream (const struct WpParserStreamsData *data,
|
||||
const char *name)
|
||||
{
|
||||
for (guint i = 0; i < data->n_streams; i++) {
|
||||
const struct WpParserStreamsStreamData *s = data->streams + i;
|
||||
if (g_strcmp0 (s->name, name) == 0)
|
||||
return s;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const struct WpParserStreamsStreamData *
|
||||
wp_parser_streams_get_lowest_stream (const struct WpParserStreamsData *data)
|
||||
{
|
||||
const struct WpParserStreamsStreamData *res = NULL;
|
||||
guint lowest = G_MAXUINT;
|
||||
for (guint i = 0; i < data->n_streams; i++) {
|
||||
const struct WpParserStreamsStreamData *s = data->streams + i;
|
||||
if (s->priority < lowest) {
|
||||
lowest = s->priority;
|
||||
res = s;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static void wp_parser_streams_config_parser_init (gpointer iface,
|
||||
gpointer iface_data);
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (WpParserStreams, wp_parser_streams,
|
||||
G_TYPE_OBJECT,
|
||||
G_IMPLEMENT_INTERFACE (WP_TYPE_CONFIG_PARSER,
|
||||
wp_parser_streams_config_parser_init))
|
||||
|
||||
static void
|
||||
wp_parser_streams_data_destroy (gpointer p)
|
||||
{
|
||||
struct WpParserStreamsData *data = p;
|
||||
|
||||
/* Clear the location */
|
||||
g_clear_pointer (&data->location, g_free);
|
||||
|
||||
/* Clear the streams */
|
||||
for (guint i = 0; i < data->n_streams; i++) {
|
||||
struct WpParserStreamsStreamData *s = data->streams + i;
|
||||
g_clear_pointer (&s->name, g_free);
|
||||
}
|
||||
data->n_streams = 0;
|
||||
|
||||
g_slice_free (struct WpParserStreamsData, data);
|
||||
}
|
||||
|
||||
static void
|
||||
streams_for_each (const WpTomlTable *table, gpointer user_data)
|
||||
{
|
||||
struct WpParserStreamsData *data = user_data;
|
||||
struct WpParserStreamsStreamData *stream = NULL;
|
||||
g_return_if_fail (data);
|
||||
|
||||
/* Make sure we don't parse more MAX_STREAMS streams */
|
||||
if (data->n_streams >= MAX_STREAMS)
|
||||
return;
|
||||
|
||||
/* Skip unparsed tables */
|
||||
if (!table)
|
||||
return;
|
||||
|
||||
/* Parse the mandatory name */
|
||||
stream = data->streams + data->n_streams;
|
||||
stream->name = wp_toml_table_get_string (table, "name");
|
||||
if (!stream->name)
|
||||
return;
|
||||
|
||||
/* Parse the optional priority */
|
||||
stream->priority = 0;
|
||||
wp_toml_table_get_uint32 (table, "priority", &stream->priority);
|
||||
|
||||
/* Increment the number of streams */
|
||||
data->n_streams++;
|
||||
}
|
||||
|
||||
|
||||
static struct WpParserStreamsData *
|
||||
wp_parser_streams_data_new (const gchar *location)
|
||||
{
|
||||
g_autoptr (WpTomlFile) file = NULL;
|
||||
g_autoptr (WpTomlTable) table = NULL;
|
||||
g_autoptr (WpTomlTableArray) streams = NULL;
|
||||
struct WpParserStreamsData *res = NULL;
|
||||
|
||||
/* File format:
|
||||
* ------------
|
||||
* [[streams]]
|
||||
* name (string)
|
||||
* priority (uint32)
|
||||
*/
|
||||
|
||||
/* Get the TOML file */
|
||||
file = wp_toml_file_new (location);
|
||||
if (!file)
|
||||
return NULL;
|
||||
|
||||
/* Get the file table */
|
||||
table = wp_toml_file_get_table (file);
|
||||
if (!table)
|
||||
return NULL;
|
||||
|
||||
/* Create the streams data */
|
||||
res = g_slice_new0 (struct WpParserStreamsData);
|
||||
|
||||
/* Set the location */
|
||||
res->location = g_strdup (location);
|
||||
|
||||
/* Parse the streams */
|
||||
res->n_streams = 0;
|
||||
streams = wp_toml_table_get_array_table (table, "streams");
|
||||
if (streams)
|
||||
wp_toml_table_array_for_each (streams, streams_for_each, res);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
wp_parser_streams_add_file (WpConfigParser *parser,
|
||||
const gchar *name)
|
||||
{
|
||||
WpParserStreams *self = WP_PARSER_STREAMS (parser);
|
||||
struct WpParserStreamsData *data;
|
||||
|
||||
/* Parse the file */
|
||||
data = wp_parser_streams_data_new (name);
|
||||
if (!data) {
|
||||
g_warning ("Failed to parse configuration file '%s'", name);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Add the data to the array */
|
||||
g_ptr_array_add(self->datas, data);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gconstpointer
|
||||
wp_parser_streams_get_matched_data (WpConfigParser *parser, gpointer data)
|
||||
{
|
||||
WpParserStreams *self = WP_PARSER_STREAMS (parser);
|
||||
const char *location = data;
|
||||
const struct WpParserStreamsData *d = NULL;
|
||||
|
||||
/* Find the first data that matches location */
|
||||
for (guint i = 0; i < self->datas->len; i++) {
|
||||
d = g_ptr_array_index(self->datas, i);
|
||||
if (g_strrstr (d->location, location))
|
||||
return d;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
wp_parser_streams_reset (WpConfigParser *parser)
|
||||
{
|
||||
WpParserStreams *self = WP_PARSER_STREAMS (parser);
|
||||
|
||||
g_ptr_array_set_size (self->datas, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
wp_parser_streams_config_parser_init (gpointer iface,
|
||||
gpointer iface_data)
|
||||
{
|
||||
WpConfigParserInterface *cp_iface = iface;
|
||||
|
||||
cp_iface->add_file = wp_parser_streams_add_file;
|
||||
cp_iface->get_matched_data = wp_parser_streams_get_matched_data;
|
||||
cp_iface->reset = wp_parser_streams_reset;
|
||||
}
|
||||
|
||||
static void
|
||||
wp_parser_streams_finalize (GObject * object)
|
||||
{
|
||||
WpParserStreams *self = WP_PARSER_STREAMS (object);
|
||||
|
||||
g_clear_pointer (&self->datas, g_ptr_array_unref);
|
||||
|
||||
G_OBJECT_CLASS (wp_parser_streams_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
wp_parser_streams_init (WpParserStreams * self)
|
||||
{
|
||||
self->datas = g_ptr_array_new_with_free_func (wp_parser_streams_data_destroy);
|
||||
}
|
||||
|
||||
static void
|
||||
wp_parser_streams_class_init (WpParserStreamsClass * klass)
|
||||
{
|
||||
GObjectClass *object_class = (GObjectClass *) klass;
|
||||
|
||||
object_class->finalize = wp_parser_streams_finalize;
|
||||
}
|
Reference in New Issue
Block a user