Port MatrixPusher to C

This commit is contained in:
Gergely Polonkai 2017-11-10 13:32:28 +01:00
parent f5df3831a3
commit d3db60e50d
4 changed files with 497 additions and 128 deletions

View File

@ -16,6 +16,7 @@
* <http://www.gnu.org/licenses/>.
*/
#include <string.h>
#include <gobject/gvaluecollector.h>
#include "matrix-c-compacts.h"
#include "matrix-enumtypes.h"
@ -1529,3 +1530,456 @@ matrix_3pid_credential_init(Matrix3PidCredential* matrix_3pid_credential)
priv->_session_id = NULL;
priv->_client_secret = NULL;
}
typedef struct {
gchar *_device_display_name;
gchar *_app_display_name;
gchar *_app_id;
gboolean _append;
gchar *_kind;
gchar *_lang;
gchar *_profile_tag;
gchar *_pushkey;
JsonNode *_data;
} MatrixPusherPrivate;
/**
* MatrixPusher:
*
* Class to hold pusher related data.
*/
G_DEFINE_TYPE_WITH_PRIVATE(MatrixPusher, matrix_pusher, MATRIX_TYPE_JSON_COMPACT);
static JsonNode *
matrix_pusher_get_json_node(MatrixJsonCompact *matrix_json_compact, GError **error)
{
MatrixPusherPrivate *priv;
JsonBuilder *builder;
JsonNode *result;
g_return_val_if_fail(matrix_json_compact != NULL, NULL);
priv = matrix_pusher_get_instance_private(MATRIX_PUSHER(matrix_json_compact));
if ((priv->_device_display_name == NULL)
|| (priv->_app_display_name == NULL)
|| (priv->_app_id == NULL)
|| (priv->_data == NULL)
|| (priv->_kind == NULL)
|| (priv->_lang == NULL)
|| (priv->_profile_tag == NULL)
|| (priv->_pushkey == NULL)) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_INCOMPLETE, "Pusher data incomplete");
return NULL;
}
builder = json_builder_new();
json_builder_begin_object(builder);
json_builder_set_member_name(builder, "device_display_name");
json_builder_add_string_value(builder, priv->_device_display_name);
json_builder_set_member_name(builder, "app_display_name");
json_builder_add_string_value(builder, priv->_app_display_name);
json_builder_set_member_name(builder, "app_id");
json_builder_add_string_value(builder, priv->_app_id);
json_builder_set_member_name(builder, "append");
json_builder_add_boolean_value(builder, priv->_append);
json_builder_set_member_name(builder, "kind");
json_builder_add_string_value(builder, priv->_kind);
json_builder_set_member_name(builder, "lang");
json_builder_add_string_value(builder, priv->_lang);
json_builder_set_member_name(builder, "profile_tag");
json_builder_add_string_value(builder, priv->_profile_tag);
json_builder_set_member_name(builder, "pushkey");
json_builder_add_string_value(builder, priv->_pushkey);
json_builder_set_member_name(builder, "data");
json_builder_add_value(builder, priv->_data);
json_builder_end_object(builder);
result = json_builder_get_root(builder);
g_object_unref(builder);
return result;
}
MatrixPusher *
matrix_pusher_construct(GType object_type)
{
return (MatrixPusher *)matrix_json_compact_construct(object_type);
}
/**
* matrix_pusher_new:
*
* Create a new #MatrixPusher object
*
* Returns: (transfer full): a new #MatrixPusher object
*/
MatrixPusher *
matrix_pusher_new(void)
{
return matrix_pusher_construct(MATRIX_TYPE_PUSHER);
}
/*
* STR_GETTER:
* @NAME: the property the generated function is a getter for
*
* Generate a function to get a string property from a #MatrixPusher object.
*/
# define STR_GETTER(NAME) \
const gchar * \
matrix_pusher_get_ ## NAME (MatrixPusher *matrix_pusher) \
{ \
MatrixPusherPrivate *priv; \
\
g_return_val_if_fail(matrix_pusher != NULL, NULL); \
\
priv = matrix_pusher_get_instance_private(matrix_pusher); \
\
return priv->_ ## NAME ; \
}
/*
* STR_SETTER:
* @NAME: the property the generated function is a setter for
*
* Generate a function to set a string property of a #MatrixPusher object
*/
# define STR_SETTER(NAME) \
void \
matrix_pusher_set_ ## NAME (MatrixPusher * matrix_pusher, const gchar *NAME) \
{ \
MatrixPusherPrivate *priv; \
\
g_return_if_fail(matrix_pusher != NULL); \
\
priv = matrix_pusher_get_instance_private(matrix_pusher); \
\
g_free(priv->_ ## NAME); \
priv->_ ## NAME = g_strdup(NAME); \
}
/**
* matrix_pusher_get_device_display_name:
* @pusher: a #MatrixPusher object
*
* Get the device display name of @pusher.
*
* The returned value is owned by @pusher, and should not be freed.
*
* Returns: (transfer none): the device display name
*/
STR_GETTER(device_display_name);
/**
* matrix_pusher_set_device_display_name:
* @pusher: a #MatrixPusher object
* @device_display_name: (transfer none): a device display name
*
* Set the device display name in @pusher
*/
STR_SETTER(device_display_name);
/**
* matrix_pusher_get_app_display_name:
* @pusher: a #MatrixPusher object
*
* Get the app display name of @pusher.
*
* The returned value is owned by @pusher, and should not be freed.
*
* Returns: (transfer none): the app display name
*/
STR_GETTER(app_display_name);
/**
* matrix_pusher_set_app_display_name:
* @pusher: a #MatrixPusher object
* @app_display_name: (transfer none): an app display name
*
* Set the app display name in @pusher
*/
STR_SETTER(app_display_name);
/**
* matrix_pusher_get_app_id:
* @pusher: a #MatrixPusher object
*
* Get the application ID of @pusher.
*
* The returned value is owned by @pusher, and should not be freed.
*
* Returns: (transfer none): the application ID
*/
STR_GETTER(app_id);
/**
* matrix_pusher_set_app_id:
* @pusher: a #MatrixPusher object
* @app_id: (transfer none): an application ID
*
* Set the application ID in @pusher
*/
STR_SETTER(app_id);
/**
* matrix_pusher_get_append:
* @pusher: a #MatrixPusher object
*
* If this function returns %TRUE, this pusher will tell the homeserver to add another pusher
* with the given push key instead of replacing the old one.
*
* Returns: %TRUE or %FALSE
*/
gboolean
matrix_pusher_get_append(MatrixPusher *matrix_pusher)
{
MatrixPusherPrivate *priv;
g_return_val_if_fail(matrix_pusher != NULL, FALSE);
priv = matrix_pusher_get_instance_private(matrix_pusher);
return priv->_append;
}
/**
* matrix_pusher_set_append:
* @pusher: a #MatrixPusher object
* @append: a boolean value indicating if existing pushers should be overwritten
*
* If @append is #TRUE, the homeserver should add another pusher with the given push key and
* app ID in addition to any others with different user IDs. Otherwise, the homeserver must
* remove any other pushers with the same App ID and pushkey for different users.
*/
void
matrix_pusher_set_append(MatrixPusher *matrix_pusher, gboolean append)
{
MatrixPusherPrivate *priv;
g_return_if_fail(matrix_pusher != NULL);
priv = matrix_pusher_get_instance_private(matrix_pusher);
priv->_append = append;
}
/**
* matrix_pusher_get_kind:
* @pusher: a #MatrixPusher object
*
* Get the type of @pusher. For available types, see matrix_pusher_set_kind().
*/
STR_GETTER(kind);
/**
* matrix_pusher_set_kind:
* @pusher: a #MatrixPusher object
* @kind: the kind of @pusher
*
* Set the type of the pusher. For example, `"http"` makes a pusher that sends HTTP pokes.
*
* If set to %NULL, the pusher will be deleted.
*/
STR_SETTER(kind);
/**
* matrix_pusher_get_lang:
* @pusher: a #MatrixPusher object
*
* Get the preferred language of the notifications sent by this pusher.
*
* The returned value is owned by @pusher, and should not be freed.
*
* Returns: (transfer none): the preferred language
*/
STR_GETTER(lang);
/**
* matrix_pusher_set_lang:
* @pusher: a #MatrixPusher object
* @lang: (transfer none): a language code
*
* The preferred language for receiving notifications. @lang should be an ISO code like
* `"en"` `"en-US"`.
*/
STR_SETTER(lang);
/**
* matrix_pusher_get_profile_tag:
* @pusher: a #MatrixPusher object
*
* Get the profile tag of @pusher. For details, see matrix_pusher_set_profile_tag().
*
* The returned value is owned by @pusher, and should not be freed.
*
* Returns: (transfer none): the profile tag
*/
STR_GETTER(profile_tag);
/**
* matrix_pusher_set_profile_tag:
* @pusher: a #MatrixPusher object
* @profile_tag: (transfer none) (nullable): a profile tag
*
* A profile tag is a string that determines what set of device rules will be matched when
* evaluating push rules for this pusher. It is an arbitrary string. Multiple devices may
* use the same profile tag. It is advised that when an apps data is copied or restored to a
* different device, this value remain the same. Client apps should offer ways to change the
* profile tag, optionally copying rules from the old profile tag. Maximum length is 32 bytes.
* If the profile tag is longer than this, it will be truncated.
*/
void
matrix_pusher_set_profile_tag(MatrixPusher *matrix_pusher, const gchar *profile_tag)
{
MatrixPusherPrivate *priv;
g_return_if_fail(matrix_pusher != NULL);
if ((profile_tag != NULL) && (strlen(profile_tag) > 32)) {
g_warning("profile_key cant be longer than 32 bytes. Truncating.");
}
priv = matrix_pusher_get_instance_private(matrix_pusher);
g_free(priv->_profile_tag);
priv->_profile_tag = g_strndup(profile_tag, 32);
}
/**
* matrix_pusher_get_pushkey:
* @pusher: a #MatrixPusher object
*
* Get the push key of @pusher. For details, see matrix_pusher_set_pushkey().
*
* The returned value is owned by @pusher, and should not be freed.
*/
STR_GETTER(pushkey);
/**
* matrix_pusher_set_pushkey:
* @pusher: a #MatrixPusher object
* @pushkey: (transfer none) (nullable): a push key
*
* A push key is a unique identifier for a pusher. The value you should use for this is the
* routing or destination address information for the notification, for example, the APNS token
* for APNS or the Registration ID for GCM. If your notification client has no such concept,
* use any unique identifier. Maximum length is 512 bytes. If @pushkey is longer than this,
* it will be truncated
*/
void
matrix_pusher_set_pushkey(MatrixPusher *matrix_pusher, const gchar *pushkey)
{
MatrixPusherPrivate *priv;
g_return_if_fail(matrix_pusher != NULL);
priv = matrix_pusher_get_instance_private(matrix_pusher);
g_free(priv->_pushkey);
priv->_pushkey = g_strndup(pushkey, 512);
}
/**
* matrix_pusher_get_data:
* @pusher: a #MatrixPusher object
*
* Get the associated data for @pusher. For details, see matrix_pusher_set_data().
*
* The returned value is owned by @pusher, and should not be freed.
*
* Returns: (transfer none): the data associated with @pusher
*/
JsonNode *
matrix_pusher_get_data(MatrixPusher *matrix_pusher)
{
MatrixPusherPrivate *priv;
g_return_val_if_fail(matrix_pusher != NULL, FALSE);
priv = matrix_pusher_get_instance_private(matrix_pusher);
return priv->_data;
}
/**
* matrix_pusher_set_data:
* @pusher: a #MatrixPusher object
* @data: (transfer none): a JSON node holding extra data for @pusher
*
* Set a dictionary of information for the pusher implementation itself.
*
* For example, if kind (set by matrix_pusher_set_kind()) is `"http"`, this should contain an
* `"url"` member, which is the URL to use to send notifications to. The function gets a
* reference on @data, but doesnt copy the object in it.
*/
void
matrix_pusher_set_data(MatrixPusher *matrix_pusher, JsonNode *data)
{
MatrixPusherPrivate *priv;
g_return_if_fail(matrix_pusher != NULL);
priv = matrix_pusher_get_instance_private(matrix_pusher);
if (priv->_data != NULL) {
json_node_unref(priv->_data);
}
priv->_data = json_node_ref(data);
}
static void
matrix_pusher_finalize(MatrixJsonCompact *matrix_json_compact)
{
MatrixPusherPrivate *priv = matrix_pusher_get_instance_private(MATRIX_PUSHER(matrix_json_compact));
g_free(priv->_device_display_name);
g_free(priv->_app_display_name);
g_free(priv->_app_id);
g_free(priv->_kind);
g_free(priv->_lang);
g_free(priv->_profile_tag);
g_free(priv->_pushkey);
if (priv->_data) {
json_node_unref(priv->_data);
}
MATRIX_JSON_COMPACT_CLASS(matrix_pusher_parent_class)->finalize(matrix_json_compact);
}
static void
matrix_pusher_class_init(MatrixPusherClass *klass)
{
((MatrixJsonCompactClass *)klass)->finalize = matrix_pusher_finalize;
((MatrixJsonCompactClass *)klass)->get_json_node = matrix_pusher_get_json_node;
}
static void
matrix_pusher_init(MatrixPusher *matrix_pusher)
{
MatrixPusherPrivate *priv = matrix_pusher_get_instance_private(matrix_pusher);
priv->_device_display_name = NULL;
priv->_app_display_name = NULL;
priv->_app_id = NULL;
priv->_append = TRUE;
priv->_kind = NULL;
priv->_lang = NULL;
priv->_profile_tag = NULL;
priv->_pushkey = NULL;
priv->_data = NULL;
}

View File

@ -134,6 +134,34 @@ void matrix_3pid_credential_set_session_id(Matrix3PidCredential *credential, con
const gchar *matrix_3pid_credential_get_client_secret(Matrix3PidCredential *credential);
void matrix_3pid_credential_set_client_secret(Matrix3PidCredential *credential, const gchar *client_secret);
# define MATRIX_TYPE_PUSHER matrix_pusher_get_type()
G_DECLARE_DERIVABLE_TYPE(MatrixPusher, matrix_pusher, MATRIX, PUSHER, MatrixJsonCompact);
struct _MatrixPusherClass {
MatrixJsonCompactClass parent_class;
};
MatrixPusher *matrix_pusher_new(void);
MatrixPusher *matrix_pusher_construct(GType object_type);
const gchar *matrix_pusher_get_device_display_name(MatrixPusher *pusher);
void matrix_pusher_set_device_display_name(MatrixPusher *pusher, const gchar *device_display_name);
const gchar *matrix_pusher_get_app_display_name(MatrixPusher *pusher);
void matrix_pusher_set_app_display_name(MatrixPusher *pusher, const gchar *app_display_name);
const gchar *matrix_pusher_get_app_id(MatrixPusher *pusher);
void matrix_pusher_set_app_id(MatrixPusher *pusher, const gchar *app_id);
gboolean matrix_pusher_get_append(MatrixPusher *pusher);
void matrix_pusher_set_append(MatrixPusher *pusher, gboolean append);
const gchar *matrix_pusher_get_kind(MatrixPusher *pusher);
void matrix_pusher_set_kind(MatrixPusher *pusher, const gchar *kind);
const gchar *matrix_pusher_get_lang(MatrixPusher *pusher);
void matrix_pusher_set_lang(MatrixPusher *pusher, const gchar *lang);
const gchar *matrix_pusher_get_profile_tag(MatrixPusher *pusher);
void matrix_pusher_set_profile_tag(MatrixPusher *pusher, const gchar *profile_tag);
const gchar *matrix_pusher_get_pushkey(MatrixPusher *pusher);
void matrix_pusher_set_pushkey(MatrixPusher *pusher, const gchar *pushkey);
JsonNode *matrix_pusher_get_data(MatrixPusher *pusher);
void matrix_pusher_set_data(MatrixPusher *pusher, JsonNode *data);
G_END_DECLS
#endif /* __MATRIX_GLIB_SDK_COMPACTS_H__ */

View File

@ -17,134 +17,6 @@
*/
namespace Matrix {
/**
* Class to hold pusher related data.
*/
public class Pusher : JsonCompact {
/**
* A device display name.
*/
public string? device_display_name { get; set; default = null; }
/**
* An application display name.
*/
public string? app_display_name { get; set; default = null; }
/**
* An application ID.
*/
public string? app_id { get; set; default = null; }
/**
* If {{{true}}}, the homeserver should add another pusher
* with the given push key and app ID in addition to any
* others with different user IDs. Otherwise, the homeserver
* must remove any other pushers with the same App ID and
* pushkey for different users.
*/
public bool append { get; set; default = true; }
/**
* The kind of the pusher. {{{http}}} makes a pusher that
* sends HTTP pokes. {{{null}}} deletes the pusher.
*/
public string? kind { get; set; default = null; }
/**
* The preferred language for receiving notifications,
* e.g. {{{en}}} or {{{en-US}}}.
*/
public string? lang { get; set; default = null; }
/**
* A string that determines what set of device rules will be
* matched when evaluating push rules for this pusher. It is
* an arbitrary string. Multiple devices may use the same
* profile tag. It is advised that when an app's data is
* copied or restored to a different device, this value remain
* the same. Client apps should offer ways to change the
* profile tag, optionally copying rules from the old profile
* tag. Maximum length is 32 bytes. If the profile tag is
* longer than this, it will be truncated
*/
public string? profile_tag { get; set; default = null; }
/**
* A unique identifier for this pusher. The value you should
* use for this is the routing or destination address
* information for the notification, for example, the APNS
* token for APNS or the Registration ID for GCM. If your
* notification client has no such concept, use any unique
* identifier. Maximum length is 512 bytes. If pushkey is
* longer than this, it will be truncated
*/
public string? pushkey { get; set; default = null; }
/**
* a dictionary of information for the pusher implementation
* itself. For example, if kind is {{{http}}}, this should
* contain an {{{url}}} member, which is the URL to use to
* send notifications to. This function creates a deep copy of
* the data, so it can be freed after this call.
*/
public Json.Node? data { get; set; default = null; }
/**
* Get the pusher data as a JSON node.
*/
public override Json.Node?
get_json_node()
throws Matrix.Error
{
if ((device_display_name == null)
|| (app_display_name == null)
|| (app_id == null)
|| (data == null)
|| (kind == null)
|| (lang == null)
|| (profile_tag == null)
|| (pushkey == null)) {
throw new Matrix.Error.INCOMPLETE("Pusher data incomplete");
}
var builder = new Json.Builder();
builder.begin_object();
builder.set_member_name("device_display_name");
builder.add_string_value(device_display_name);
builder.set_member_name("app_display_name");
builder.add_string_value(app_display_name);
builder.set_member_name("app_id");
builder.add_string_value(app_id);
builder.set_member_name("append");
builder.add_boolean_value(append);
builder.set_member_name("kind");
builder.add_string_value(kind);
builder.set_member_name("lang");
builder.add_string_value(lang);
builder.set_member_name("profile_tag");
builder.add_string_value(profile_tag);
builder.set_member_name("pushkey");
builder.add_string_value(pushkey);
builder.set_member_name("data");
builder.add_value(data);
builder.end_object();
return builder.get_root();
}
}
public class EventContext : JsonCompact {
public int before_limit { get; set; default = -1; }
public int after_limit { get; set; default = -1; }

View File

@ -340,6 +340,21 @@ namespace Matrix {
throws Matrix.Error;
}
[CCode (cheader_filename = "matrix-c-compacts.h")]
public class Pusher : JsonCompact {
public string? device_display_name { get; set; default = null; }
public string? app_display_name { get; set; default = null; }
public string? app_id { get; set; default = null; }
public bool append { get; set; default = true; }
public string? kind { get; set; default = null; }
public string? lang { get; set; default = null; }
public string? profile_tag { get; set; default = null; }
public string? pushkey { get; set; default = null; }
public Json.Node? data { 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);