#include "config.h" #include #include "ssb-packet-stream.h" #define DEFAULT_SHS_CAP_KEY "\xd4\xa1\xcb\x88\xa6\x6f\x02\xf8\xdb\x63\x5c\xe2\x64\x41\xcc\x5d" \ "\xac\x1b\x08\x42\x0c\xea\xac\x23\x08\x39\xb7\x55\x84\x5a\x9f\xfb" static void ssb_packet_stream_initable_interface_init(GInitableIface *iface); static GInitableIface *ssb_packet_stream_parent_initable_iface; typedef struct { GIOStream *base_io_stream; GInputStream *input_stream; GOutputStream *output_stream; } SsbPacketStreamPrivate; G_DEFINE_TYPE_WITH_CODE(SsbPacketStream, ssb_packet_stream, G_TYPE_IO_STREAM, G_IMPLEMENT_INTERFACE(G_TYPE_INITABLE, ssb_packet_stream_initable_interface_init) G_ADD_PRIVATE(SsbPacketStream)); enum { PROP_0, PROP_BASE_IO_STREAM, PROP_COUNT }; static GParamSpec *properties[PROP_COUNT]; static GInputStream * ssb_packet_stream_get_input_stream(GIOStream *iostream) { SsbPacketStreamPrivate *priv = ssb_packet_stream_get_instance_private( SSB_PACKET_STREAM(iostream)); return priv->input_stream; } static GOutputStream * ssb_packet_stream_get_output_stream(GIOStream *iostream) { SsbPacketStreamPrivate *priv = ssb_packet_stream_get_instance_private( SSB_PACKET_STREAM(iostream)); return priv->output_stream; } static gboolean ssb_packet_stream_close_fn(GIOStream *iostream, GCancellable *cancellable, GError **error) { // TODO: How to do this? return TRUE; } static void close_thread(GTask *task, gpointer object, gpointer task_data, GCancellable *cancellable) { GIOStream *iostream = object; GError *err = NULL; if (!ssb_packet_stream_close(st)) } static void ssb_packet_stream_close_async(GIOStream *iostream, GIOPriority io_priority, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { GTask *task = g_task_new(stream, cancellable, callback, user_data); g_task_set_source_tag(task, ssb_packet_stream_close_async); g_task_set_priority(task, io_priority); g_task_run_in_thread(task, close_thread); g_object_unref(task); } static gboolean ssb_packet_stream_close_finish(GIOStream *stream, GAsyncResult *result, GError **error) { g_return_val_if_fail(g_task_is_valid(result, stream), FALSE); return g_task_propagate_boolean(G_TASK(result), error); } static void ssb_packet_stream_get_property(GObject *gobject, guint prop_id, GValue *value, GParamSpec *pspec) { SsbPacketStreamPrivate *priv = ssb_packet_stream_get_instance_private( SSB_PACKET_STREAM(gobject)); switch (prop_id) { case PROP_BASE_IO_STREAM: g_value_set_object(value, priv->base_io_stream); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec); } } static void ssb_packet_stream_set_property(GObject *gobject, guint prop_id, const GValue *value, GParamSpec *pspec) { SsbPacketStreamPrivate *priv = ssb_packet_stream_get_instance_private( SSB_PACKET_STREAM(gobject)); switch (prop_id) { case PROP_BASE_IO_STREAM: g_clear_object(&(priv->base_io_stream)); priv->base_io_stream = g_value_dup_object(value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec); } } static void ssb_packet_stream_finalize(GObject *gobject) { SsbPacketStreamPrivate *priv = ssb_packet_stream_get_instance_private( SSB_PACKET_STREAM(gobject)); g_clear_object(&(priv->base_io_stream)); } static void ssb_packet_stream_init(SsbPacketStream *stream) { SsbPacketStreamPrivate *priv = ssb_packet_stream_get_instance_private(stream); priv->base_io_stream = NULL; } static void ssb_packet_stream_class_init(SsbPacketStreamClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS(klass); GIOStreamClass *iostream_class = G_IO_STREAM_CLASS(klass); gobject_class->get_property = ssb_packet_stream_get_property; gobject_class->set_property = ssb_packet_stream_set_property; gobject_class->finalize = ssb_packet_stream_finalize; iostream_class->get_input_stream = ssb_packet_stream_get_input_stream; iostream_class->get_output_stream = ssb_packet_stream_get_output_stream; iostream_class->close_fn = ssb_packet_stream_close_fn; iostream_class->close_async = ssb_packet_stream_close_async; iostream_class->close_finish = ssb_packet_stream_close_finish; properties[PROP_BASE_IO_STREAM] = g_param_spec_object( "base-io-stream", P_("Base IOStream"), P_("The GIOStream that the connection wraps"), G_TYPE_IO_STREAM, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); g_object_class_install_properties(gobject_class, PROP_COUNT, properties); } static gboolean ssb_packet_stream_initable_init(GInitable *initable, GCancellable *cancellable, GError **error) { if (!ssb_packet_stream_parent_initable_iface->init(initable, cancellable, error)) { return FALSE; } return TRUE; } static void ssb_packet_stream_initable_interface_init(GInitableIface *iface) { ssb_packet_stream_parent_initable_iface = g_type_interface_peek_parent(iface); iface->init = ssb_packet_stream_initable_init; } GIOStream * ssb_packet_stream_new(GIOStream *base_io_stream, GError **error) { GObject *conn; conn = g_initable_new(SSB_TYPE_PACKET_STREAM, NULL, error, "base-io-stream", base_io_stream, NULL); return G_IO_STREAM(conn); }