Files
wireplumber/modules/module-config-endpoint/parser-streams.c
2019-12-16 13:36:56 -05:00

224 lines
5.2 KiB
C

/* 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;
}