From eff98aad312ac546d733c8d4342db7e545ba664c Mon Sep 17 00:00:00 2001 From: Gergely Polonkai Date: Fri, 10 Nov 2017 11:29:45 +0100 Subject: [PATCH] Port MatrixFilter to C --- src/matrix-c-compacts.c | 297 +++++++++++++++++++++++++++++++++++++++ src/matrix-c-compacts.h | 18 +++ src/matrix-compacts.vala | 65 --------- vapi/c-api.vapi | 10 ++ 4 files changed, 325 insertions(+), 65 deletions(-) diff --git a/src/matrix-c-compacts.c b/src/matrix-c-compacts.c index 9ab95b0..e86dc6b 100644 --- a/src/matrix-c-compacts.c +++ b/src/matrix-c-compacts.c @@ -18,7 +18,9 @@ #include #include "matrix-c-compacts.h" +#include "matrix-enumtypes.h" #include "matrix-types.h" +#include "utils.h" static JsonNode * matrix_json_compact_get_json_node_impl(MatrixJsonCompact *matrix_json_compact, GError **error); @@ -1004,3 +1006,298 @@ matrix_room_filter_init(MatrixRoomFilter *matrix_room_filter) priv->_state = NULL; priv->_timeline = NULL; } + +typedef struct { + gchar **_event_fields; + guint _event_fields_len; + MatrixEventFormat _event_format; + MatrixFilterRules *_presence_filter; + MatrixRoomFilter*_room_filter; +} MatrixFilterPrivate; + +/** + * MatrixFilter: + * + * Class to hold a message filter, eg. to be used with matrix_api_sync(). + */ +G_DEFINE_TYPE_WITH_PRIVATE(MatrixFilter, matrix_filter, MATRIX_TYPE_JSON_COMPACT); + +static JsonNode * +matrix_filter_get_json_node(MatrixJsonCompact *matrix_json_compact, GError **error) +{ + MatrixFilterPrivate *priv; + JsonBuilder *builder; + JsonNode *node; + GError *inner_error = NULL; + + g_return_val_if_fail(matrix_json_compact != NULL, NULL); + + priv = matrix_filter_get_instance_private(MATRIX_FILTER(matrix_json_compact)); + + builder = json_builder_new(); + + json_builder_begin_object(builder); + + json_builder_set_member_name(builder, "event_fields"); + json_builder_begin_array(builder); + + for (guint i = 0; i < priv->_event_fields_len; i++) { + json_builder_add_string_value(builder, priv->_event_fields[i]); + } + + json_builder_end_array(builder); + + json_builder_set_member_name(builder, "event_format"); + json_builder_add_string_value(builder, _matrix_g_enum_to_string(MATRIX_TYPE_EVENT_FORMAT, priv->_event_format, TRUE)); + + json_builder_set_member_name(builder, "presence"); + node = matrix_json_compact_get_json_node(MATRIX_JSON_COMPACT(priv->_presence_filter), &inner_error); + + if (inner_error != NULL) { + g_propagate_error(error, inner_error); + g_object_unref(builder); + + return NULL; + } + json_builder_add_value(builder, node); + + json_builder_set_member_name(builder, "room"); + node = matrix_json_compact_get_json_node(MATRIX_JSON_COMPACT(priv->_room_filter), &inner_error); + + if (inner_error != NULL) { + g_propagate_error(error, inner_error); + g_object_unref(builder); + + return NULL; + } + + json_builder_add_value(builder, node); + + json_builder_end_object(builder); + + node = json_builder_get_root(builder); + + g_object_unref(builder); + + return node; +} + +MatrixFilter * +matrix_filter_construct(GType object_type) +{ + return (MatrixFilter *)matrix_json_compact_construct(object_type); +} + +/** + * matrix_filter_new: + * + * Create a new #MatrixFilter object. + * + * Returns: (transfer full): a new #MatrixFilter object + */ +MatrixFilter * +matrix_filter_new(void) +{ + return matrix_filter_construct(MATRIX_TYPE_FILTER); +} + +/** + * matrix_filter_get_event_fields: + * @filter: a #MatrixFilter object + * @n_event_fields: (nullable): placeholder for the length of the result, or %NULL to ignore + * + * Get the fields to be included in the filtered events. + * + * The returned value is owned by @filter and should not be freed. + * + * Returns: (transfer none): the list of fields to include + */ +gchar ** +matrix_filter_get_event_fields(MatrixFilter *matrix_filter, int *n_event_fields) +{ + MatrixFilterPrivate *priv; + + g_return_val_if_fail(matrix_filter != NULL, NULL); + + priv = matrix_filter_get_instance_private(matrix_filter); + + if (n_event_fields != NULL) { + *n_event_fields = priv->_event_fields_len; + } + + return priv->_event_fields; +} + +/** + * matrix_filter_set_event_fields: + * @filter: a #MatrixFilter object + * @event_fields: (transfer none) (nullable): a list of event field names + * @n_event_fields: the number of elements in @event_fields + * + * Set the event fields to be included in the filtered events. + */ +void +matrix_filter_set_event_fields(MatrixFilter *matrix_filter, gchar **event_fields, int n_event_fields) +{ + MatrixFilterPrivate *priv; + + g_return_if_fail(matrix_filter != NULL); + + priv = matrix_filter_get_instance_private(matrix_filter); + + free_str_array(priv->_event_fields, priv->_event_fields_len); + priv->_event_fields = copy_str_array(event_fields, n_event_fields); + priv->_event_fields_len = n_event_fields; +} + +/** + * matrix_filter_get_event_format: + * @filter: a #MatrixFilter object + * + * Get the format that will be used to represent the filtered events. + * + * Returns: a #MatrixEventFormat value + */ +MatrixEventFormat +matrix_filter_get_event_format(MatrixFilter *matrix_filter) +{ + MatrixFilterPrivate *priv; + + g_return_val_if_fail(matrix_filter != NULL, 0); + + priv = matrix_filter_get_instance_private(matrix_filter); + + return priv->_event_format; +} + +/** + * matrix_filter_set_event_format: + * @filter: a #MatrixFilter object + * @event_format: the event format to use + * + * Set the desired event format for the filtered events (eg. for used with matrix_api_sync()) + */ +void +matrix_filter_set_event_format(MatrixFilter *matrix_filter, MatrixEventFormat event_format) +{ + MatrixFilterPrivate *priv; + + g_return_if_fail(matrix_filter != NULL); + + priv = matrix_filter_get_instance_private(matrix_filter); + + priv->_event_format = event_format; +} + +/** + * matrix_filter_get_presence_filter: + * @filter: a #MatrixFilter object + * + * Get the filtering ruleset for presence events. + * + * The returned value is owned by @filter and should not be freed. + * + * Returns: (transfer none) (nullable): a #MatrixFilterRules object + */ +MatrixFilterRules * +matrix_filter_get_presence_filter(MatrixFilter *matrix_filter) +{ + MatrixFilterPrivate *priv; + + g_return_val_if_fail(matrix_filter != NULL, NULL); + + priv = matrix_filter_get_instance_private(matrix_filter); + + return priv->_presence_filter; +} + +/** + * matrix_filter_set_presence_filter: + * @filter: a #MatrixFilter object + * @presence_filter: (transfer none): a #MatrixFilterRules object to be applied to presence events + * + * Set a filtering ruleset for presence events. + */ +void +matrix_filter_set_presence_filter(MatrixFilter *matrix_filter, MatrixFilterRules *presence_filter) +{ + MatrixFilterPrivate *priv; + + g_return_if_fail(matrix_filter != NULL); + + priv = matrix_filter_get_instance_private(matrix_filter); + + matrix_json_compact_unref(MATRIX_JSON_COMPACT(priv->_presence_filter)); + priv->_presence_filter = (MatrixFilterRules *)matrix_json_compact_ref(MATRIX_JSON_COMPACT(presence_filter)); +} + +/** + * matrix_filter_get_room_filter: + * @filter: a #MatrixFilter object + * + * Get the filtering ruleset to be applied to room events. + * + * The returned value is owned by @filter and should not be freed. + * + * Returns: (transfer none) (nullable): a #MatrixRoomFilter object + */ +MatrixRoomFilter * +matrix_filter_get_room_filter(MatrixFilter *matrix_filter) +{ + MatrixFilterPrivate *priv; + + g_return_val_if_fail(matrix_filter != NULL, NULL); + + priv = matrix_filter_get_instance_private(matrix_filter); + + return priv->_room_filter; +} + +/** + * matrix_filter_set_room_filter: + * @filter: a #MatrixFilter object + * @room_filter: a #MatrixRoomFilter to be applied to room events + * + * Set the filtering ruleset for room events. + */ +void +matrix_filter_set_room_filter(MatrixFilter *matrix_filter, MatrixRoomFilter *room_filter) +{ + MatrixFilterPrivate *priv; + + g_return_if_fail(matrix_filter != NULL); + + priv = matrix_filter_get_instance_private(matrix_filter); + + matrix_json_compact_unref(MATRIX_JSON_COMPACT(priv->_room_filter)); + priv->_room_filter = (MatrixRoomFilter *)matrix_json_compact_ref(MATRIX_JSON_COMPACT(room_filter)); +} + +static void +matrix_filter_finalize(MatrixJsonCompact *matrix_json_compact) +{ + MatrixFilterPrivate *priv = matrix_filter_get_instance_private(MATRIX_FILTER(matrix_json_compact)); + + priv->_event_fields = (free_str_array(priv->_event_fields, priv->_event_fields_len), NULL); + matrix_json_compact_unref(MATRIX_JSON_COMPACT(priv->_presence_filter)); + matrix_json_compact_unref(MATRIX_JSON_COMPACT(priv->_room_filter)); + + MATRIX_JSON_COMPACT_CLASS(matrix_filter_parent_class)->finalize(matrix_json_compact); +} + +static void +matrix_filter_class_init(MatrixFilterClass *klass) +{ + ((MatrixJsonCompactClass *)klass)->finalize = matrix_filter_finalize; + ((MatrixJsonCompactClass *)klass)->get_json_node = matrix_filter_get_json_node; +} + +static void +matrix_filter_init(MatrixFilter *matrix_filter) +{ + MatrixFilterPrivate *priv = matrix_filter_get_instance_private(matrix_filter); + + priv->_event_format = MATRIX_EVENT_FORMAT_CLIENT; + priv->_presence_filter = NULL; + priv->_room_filter = NULL; +} diff --git a/src/matrix-c-compacts.h b/src/matrix-c-compacts.h index 69043db..941b727 100644 --- a/src/matrix-c-compacts.h +++ b/src/matrix-c-compacts.h @@ -100,6 +100,24 @@ void matrix_room_filter_set_state(MatrixRoomFilter *room_filter, MatrixFilterRul MatrixFilterRules *matrix_room_filter_get_timeline(MatrixRoomFilter *room_filter); void matrix_room_filter_set_timeline(MatrixRoomFilter *room_filter, MatrixFilterRules *timeline_rules); +# define MATRIX_TYPE_FILTER matrix_filter_get_type() +G_DECLARE_DERIVABLE_TYPE(MatrixFilter, matrix_filter, MATRIX, FILTER, MatrixJsonCompact); + +struct _MatrixFilterClass { + MatrixJsonCompactClass parent_class; +}; + +MatrixFilter *matrix_filter_new(void); +MatrixFilter *matrix_filter_construct(GType object_type); +gchar **matrix_filter_get_event_fields(MatrixFilter *filter, int *n_event_fields); +void matrix_filter_set_event_fields(MatrixFilter *filter, gchar **event_fields, int n_event_fields); +MatrixEventFormat matrix_filter_get_event_format(MatrixFilter *filter); +void matrix_filter_set_event_format(MatrixFilter *filter, MatrixEventFormat event_format); +MatrixFilterRules *matrix_filter_get_presence_filter(MatrixFilter *filter); +void matrix_filter_set_presence_filter(MatrixFilter *filter, MatrixFilterRules *presence_filter); +MatrixRoomFilter *matrix_filter_get_room_filter(MatrixFilter *filter); +void matrix_filter_set_room_filter(MatrixFilter *filter, MatrixRoomFilter *room_filter); + G_END_DECLS #endif /* __MATRIX_GLIB_SDK_COMPACTS_H__ */ diff --git a/src/matrix-compacts.vala b/src/matrix-compacts.vala index da16b17..fd30e4f 100644 --- a/src/matrix-compacts.vala +++ b/src/matrix-compacts.vala @@ -17,71 +17,6 @@ */ namespace Matrix { - - /** - * Class to hold a filter. - */ - public class Filter : JsonCompact { - /** - * The event fields to include in the filtered events. - */ - public string[] event_fields { get; set; } - - /** - * The desired event format for the filtered events (e.g. for - * matrix_api_sync()) - */ - public EventFormat event_format { - get; set; - default = Matrix.EventFormat.CLIENT; - } - - /** - * A filtering ruleset for presence events. - */ - public FilterRules? presence_filter { get; set; default = null; } - - /** - * A filtering ruleset for room events. - */ - public RoomFilter? room_filter { get; set; default = null; } - - /** - * Get the filter as a JSON node. - */ - public override Json.Node? - get_json_node() - throws Matrix.Error - { - var builder = new Json.Builder(); - - builder.begin_object(); - - builder.set_member_name("event_fields"); - builder.begin_array(); - - foreach (var entry in event_fields) { - builder.add_string_value(entry); - } - - builder.end_array(); - - builder.set_member_name("event_format"); - builder.add_string_value( - _g_enum_value_to_nick(typeof(EventFormat), event_format)); - - builder.set_member_name("presence"); - builder.add_value(presence_filter.get_json_node()); - - builder.set_member_name("room"); - builder.add_value(room_filter.get_json_node()); - - builder.end_object(); - - return builder.get_root(); - } - } - /** * Class to hold 3rd party credential related data. */ diff --git a/vapi/c-api.vapi b/vapi/c-api.vapi index e6a289e..cbd2cd1 100644 --- a/vapi/c-api.vapi +++ b/vapi/c-api.vapi @@ -320,6 +320,16 @@ namespace Matrix { throws Matrix.Error; } + [CCode (cheader_filename = "matrix-c-compacts.h")] + public class Filter : JsonCompact { + public string[] event_fields { get; set; } + public EventFormat event_format { get; set; default = Matrix.EventFormat.CLIENT; } + public FilterRules? presence_filter { get; set; default = null; } + public RoomFilter? room_filter { get; set; default = null; } + public override Json.Node? get_json_node() + throws Matrix.Error; + } + /* Utilities */ [CCode (cheader_filename = "utils.h", cname = "_matrix_g_enum_to_string")] public string? _g_enum_value_to_nick(GLib.Type enum_type, int value, bool convert_dashes = true);