diff --git a/src/Makefile.am b/src/Makefile.am
index f2fdecc..d58ac06 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -113,6 +113,7 @@ bin_PROGRAMS = test-api-client test-client
INST_H_SRC_FILES = \
matrix-types.h \
+ matrix-c-compacts.h \
utils.h \
matrix-profile.h \
$(NULL)
@@ -134,6 +135,7 @@ libmatrix_glib_0_0_la_SOURCES = \
matrix-event-types.c \
matrix-version.c \
matrix-types.c \
+ matrix-c-compacts.c \
matrix-profile.c \
utils.c \
matrix-enumtypes.c \
diff --git a/src/matrix-c-compacts.c b/src/matrix-c-compacts.c
new file mode 100644
index 0000000..401e77c
--- /dev/null
+++ b/src/matrix-c-compacts.c
@@ -0,0 +1,293 @@
+/*
+ * This file is part of matrix-glib-sdk
+ *
+ * matrix-glib-sdk is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * matrix-glib-sdk is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with matrix-glib-sdk. If not, see
+ * .
+ */
+
+#include
+#include "matrix-c-compacts.h"
+#include "matrix-types.h"
+
+static JsonNode * matrix_json_compact_get_json_node_impl(MatrixJsonCompact *matrix_json_compact,
+ GError **error);
+
+/**
+ * MatrixJsonCompactClass:
+ * @finalize: instance finalization function. Should chain up to the @finalize method of the
+ * parent class
+ * @get_json_node: instance method to get the JSON node described by the instance
+ *
+ * Class structure for #MatrixJsonCompact.
+ */
+static void
+matrix_json_compact_class_init(MatrixJsonCompactClass *klass)
+{
+ ((MatrixJsonCompactClass *)klass)->get_json_node = matrix_json_compact_get_json_node_impl;
+}
+
+/**
+ * matrix_json_compact_construct:
+ * @object_type: the #GType to construct
+ *
+ * Returns: (transfer full): a new instance of @object_type
+ */
+MatrixJsonCompact *
+matrix_json_compact_construct(GType object_type)
+{
+ MatrixJsonCompact *ret = (MatrixJsonCompact *)g_type_create_instance(object_type);
+
+ ret->refcount = 1;
+
+ return ret;
+}
+
+static void
+matrix_json_compact_init(MatrixJsonCompact *matrix_json_compact)
+{}
+
+/**
+ * matrix_json_compact_ref:
+ * @json_compact: a #MatrixJsonCompact object
+ *
+ * Increment reference count on @json_compact.
+ *
+ * Returns: (transfer full): @json_compact
+ */
+MatrixJsonCompact *
+matrix_json_compact_ref(MatrixJsonCompact *matrix_json_compact)
+{
+ g_return_val_if_fail(matrix_json_compact != NULL, NULL);
+
+ ++(matrix_json_compact->refcount);
+
+ return matrix_json_compact;
+}
+
+static void
+matrix_json_compact_free(MatrixJsonCompact *matrix_json_compact)
+{
+ g_return_if_fail(matrix_json_compact != NULL);
+
+ g_free(matrix_json_compact);
+}
+
+/**
+ * matrix_json_compact_unref:
+ * @json_compact: (transfer full): a #MatrixJsonCompact object
+ *
+ * Decrement reference count on @json_compact.
+ *
+ * If reference count reaches 0, the object is disposed.
+ */
+void
+matrix_json_compact_unref(MatrixJsonCompact *matrix_json_compact)
+{
+ g_return_if_fail(matrix_json_compact != NULL);
+
+ if (--(matrix_json_compact->refcount) == 0) {
+ matrix_json_compact_free(matrix_json_compact);
+ }
+}
+
+static JsonNode *
+matrix_json_compact_get_json_node_impl(MatrixJsonCompact *matrix_json_compact, GError **error)
+{
+ g_critical("Type `%s' does not implement abstract method `matrix_json_compact_get_json_node'",
+ g_type_name(G_TYPE_FROM_INSTANCE(matrix_json_compact)));
+
+ return NULL;
+}
+
+/**
+ * matrix_json_compact_get_json_node:
+ * @json_compact: a #MatrixJsonCompact object
+ * @error: a #GError, or %NULL to ignore errors
+ *
+ * Export the contents of @json_compact as a #JsonNode object.
+ *
+ * Subclasses must implement this method.
+ *
+ * Returns: (transfer full): a #JsonNode
+ */
+JsonNode *
+matrix_json_compact_get_json_node(MatrixJsonCompact *matrix_json_compact, GError **error)
+{
+ g_return_val_if_fail(matrix_json_compact != NULL, NULL);
+
+ return MATRIX_JSON_COMPACT_GET_CLASS(matrix_json_compact)->get_json_node(matrix_json_compact,
+ error);
+}
+
+/**
+ * matrix_json_compact_get_json_data:
+ * @json_compact: a #MatrixJsonCompact object
+ * @datalen: (nullable): a place to hold the length of the result, or %NULL to ignore
+ * @error: (nullable): a #GError, or %NULL to ignore errors
+ *
+ * Export the contents of the @json_compact as a stringified JSON object. If @datalen is
+ * not %NULL, the length of the resulting string is stored there.
+ *
+ * This function calls matrix_json_compact_get_json_node() internally. If any error happens
+ * during the export, it is stored in @error.
+ *
+ * The returned string is owned by the caller and must be freed.
+ *
+ * Returns: (transfer full): a stringified JSON object
+ */
+gchar *
+matrix_json_compact_get_json_data(MatrixJsonCompact *matrix_json_compact,
+ gsize *datalen,
+ GError **error)
+{
+ gchar* result = NULL;
+ JsonGenerator* generator = NULL;
+ JsonNode* node = NULL;
+ gsize result_len;
+ GError * inner_error = NULL;
+
+ g_return_val_if_fail(matrix_json_compact != NULL, NULL);
+
+ node = matrix_json_compact_get_json_node(matrix_json_compact, &inner_error);
+
+ if (inner_error != NULL) {
+ g_object_unref(generator);
+ g_propagate_error (error, inner_error);
+
+ return NULL;
+ }
+
+ generator = json_generator_new ();
+ json_generator_set_root (generator, node);
+ result = json_generator_to_data (generator, &result_len);
+ json_node_free(node);
+ g_object_unref(generator);
+
+ if (datalen) {
+ *datalen = result_len;
+ }
+
+ return result;
+}
+
+static void
+matrix_value_json_compact_init(GValue *value)
+{
+ value->data[0].v_pointer = NULL;
+}
+
+static void
+matrix_value_json_compact_free_value(GValue *value)
+{
+ matrix_json_compact_unref(value->data[0].v_pointer);
+}
+
+static void
+matrix_value_json_compact_copy_value(const GValue *src_value, GValue *dest_value)
+{
+ dest_value->data[0].v_pointer = matrix_json_compact_ref(src_value->data[0].v_pointer);
+}
+
+static gpointer
+matrix_value_json_compact_peek_pointer(const GValue *value)
+{
+ return value->data[0].v_pointer;
+}
+
+static gchar *
+matrix_value_json_compact_collect_value(GValue *value, guint n_collect_values, GTypeCValue *collect_values, guint collect_flags)
+{
+ if (collect_values[0].v_pointer) {
+ MatrixJsonCompact *object = collect_values[0].v_pointer;
+
+ if (object->parent_instance.g_class == NULL) {
+ return g_strconcat("invalid unclassed object pointer for value type `", G_VALUE_TYPE_NAME(value), "'", NULL);
+ } else if (!g_value_type_compatible(G_TYPE_FROM_INSTANCE(object), G_VALUE_TYPE(value))) {
+ return g_strconcat("invalid object type `", g_type_name(G_TYPE_FROM_INSTANCE (object)), "' for value type `", G_VALUE_TYPE_NAME(value), "'", NULL);
+ }
+
+ value->data[0].v_pointer = matrix_json_compact_ref(object);
+ } else {
+ value->data[0].v_pointer = NULL;
+ }
+
+ return NULL;
+}
+
+static gchar *
+matrix_value_json_compact_lcopy_value(const GValue *value, guint n_collect_values, GTypeCValue *collect_values, guint collect_flags)
+{
+ MatrixJsonCompact **object_p = collect_values[0].v_pointer;
+
+ if (!object_p) {
+ return g_strdup_printf("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME(value));
+ }
+
+ if (!value->data[0].v_pointer) {
+ *object_p = NULL;
+ } else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) {
+ *object_p = value->data[0].v_pointer;
+ } else {
+ *object_p = matrix_json_compact_ref (value->data[0].v_pointer);
+ }
+
+ return NULL;
+}
+
+/**
+ * MatrixJsonCompact:
+ *
+ * Abstract parent for classes that can be saved to JSON but don’t need full #GObject
+ * functionality.
+ */
+GType
+matrix_json_compact_get_type(void)
+{
+ static volatile gsize matrix_json_compact_type_id__volatile = 0;
+
+ if (g_once_init_enter(&matrix_json_compact_type_id__volatile)) {
+ static const GTypeValueTable g_define_type_value_table = {
+ matrix_value_json_compact_init,
+ matrix_value_json_compact_free_value,
+ matrix_value_json_compact_copy_value,
+ matrix_value_json_compact_peek_pointer, "p",
+ matrix_value_json_compact_collect_value, "p",
+ matrix_value_json_compact_lcopy_value
+ };
+ static const GTypeInfo g_define_type_info = {
+ sizeof(MatrixJsonCompactClass),
+ (GBaseInitFunc)NULL,
+ (GBaseFinalizeFunc)NULL,
+ (GClassInitFunc)matrix_json_compact_class_init,
+ (GClassFinalizeFunc)NULL,
+ NULL,
+ sizeof(MatrixJsonCompact),
+ 0,
+ (GInstanceInitFunc)matrix_json_compact_init,
+ &g_define_type_value_table
+ };
+ static const GTypeFundamentalInfo g_define_type_fundamental_info = {
+ (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE)
+ };
+ GType matrix_json_compact_type_id;
+ matrix_json_compact_type_id = g_type_register_fundamental(g_type_fundamental_next(),
+ "MatrixJsonCompact",
+ &g_define_type_info,
+ &g_define_type_fundamental_info,
+ G_TYPE_FLAG_ABSTRACT);
+ g_once_init_leave(&matrix_json_compact_type_id__volatile, matrix_json_compact_type_id);
+ }
+
+ return matrix_json_compact_type_id__volatile;
+}
diff --git a/src/matrix-c-compacts.h b/src/matrix-c-compacts.h
new file mode 100644
index 0000000..a5b99d6
--- /dev/null
+++ b/src/matrix-c-compacts.h
@@ -0,0 +1,61 @@
+/*
+ * This file is part of matrix-glib-sdk
+ *
+ * matrix-glib-sdk is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * matrix-glib-sdk is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with matrix-glib-sdk. If not, see
+ * .
+ */
+
+#ifndef __MATRIX_GLIB_SDK_COMPACTS_H__
+# define __MATRIX_GLIB_SDK_COMPACTS_H__
+
+# include
+# include
+
+G_BEGIN_DECLS
+
+# define MATRIX_TYPE_JSON_COMPACT matrix_json_compact_get_type()
+# define MATRIX_JSON_COMPACT(o) (G_TYPE_CHECK_INSTANCE_CAST((o), MATRIX_TYPE_JSON_COMPACT, MatrixJsonCompact))
+# define MATRIX_JSON_COMPACT_CLASS(c) (G_TYPE_CHECK_CLASS_CAST((c), MATRIX_TYPE_JSON_COMPACT, MatrixJsonCompactClass))
+# define MATRIX_IS_JSON_COMPACT(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), MATRIX_TYPE_JSON_COMPACT))
+# define MATRIX_IS_JSON_COMPACT_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE((c), MATRIX_TYPE_JSON_COMPACT))
+# define MATRIX_JSON_COMPACT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), MATRIX_TYPE_JSON_COMPACT, MatrixJsonCompactClass))
+
+typedef struct _MatrixJsonCompactClass MatrixJsonCompactClass;
+typedef struct _MatrixJsonCompact MatrixJsonCompact;
+void matrix_json_compact_unref(MatrixJsonCompact *json_compact);
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(MatrixJsonCompact, matrix_json_compact_unref)
+
+struct _MatrixJsonCompact {
+ GTypeInstance parent_instance;
+
+ /* < private > */
+ volatile int refcount;
+};
+
+struct _MatrixJsonCompactClass {
+ GTypeClass parent_class;
+
+ void (*finalize)(MatrixJsonCompact *json_compact);
+ JsonNode *(*get_json_node)(MatrixJsonCompact *json_compact, GError **error);
+};
+
+GType matrix_json_compact_get_type(void) G_GNUC_CONST;
+MatrixJsonCompact *matrix_json_compact_construct(GType object_type);
+MatrixJsonCompact *matrix_json_compact_ref(MatrixJsonCompact *json_compact);
+JsonNode *matrix_json_compact_get_json_node(MatrixJsonCompact *json_compact, GError **error);
+gchar *matrix_json_compact_get_json_data(MatrixJsonCompact *json_compact, gsize *datalen, GError **error);
+
+G_END_DECLS
+
+#endif /* __MATRIX_GLIB_SDK_COMPACTS_H__ */
diff --git a/src/matrix-compacts.vala b/src/matrix-compacts.vala
index 058a2a2..e045669 100644
--- a/src/matrix-compacts.vala
+++ b/src/matrix-compacts.vala
@@ -17,25 +17,6 @@
*/
namespace Matrix {
- /**
- * Abstract parent class for classes that can be saved to JSON.
- */
- public abstract class JsonCompact {
- public abstract Json.Node?
- get_json_node()
- throws Matrix.Error;
-
- public string
- get_json_data(out size_t datalen)
- throws Matrix.Error
- {
- var generator = new Json.Generator();
-
- generator.set_root(get_json_node());
-
- return generator.to_data(out datalen);
- }
- }
/**
* Class to hold a filter.
diff --git a/vapi/c-api.vapi b/vapi/c-api.vapi
index 1d16f98..5db0d42 100644
--- a/vapi/c-api.vapi
+++ b/vapi/c-api.vapi
@@ -284,6 +284,18 @@ namespace Matrix {
throws Matrix.Error;
}
+ /* Compact classes */
+ [CCode (cheader_filename = "matrix-c-compacts.h")]
+ public abstract class JsonCompact {
+ public JsonCompact();
+
+ public abstract Json.Node? get_json_node()
+ throws Matrix.Error;
+
+ public string get_json_data(out size_t datalen)
+ 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);