1 /* GIO - GLib Input, Output and Streaming Library
3 * Copyright © 2010 Red Hat, Inc.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General
16 * Public License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18 * Boston, MA 02111-1307, USA.
22 #include "gtlsoutputstream-gnutls.h"
24 static void g_tls_output_stream_gnutls_pollable_iface_init (GPollableOutputStreamInterface *iface);
26 G_DEFINE_TYPE_WITH_CODE (GTlsOutputStreamGnutls, g_tls_output_stream_gnutls, G_TYPE_OUTPUT_STREAM,
27 G_IMPLEMENT_INTERFACE (G_TYPE_POLLABLE_OUTPUT_STREAM, g_tls_output_stream_gnutls_pollable_iface_init)
30 struct _GTlsOutputStreamGnutlsPrivate
32 GTlsConnectionGnutls *conn;
34 /* pending operation metadata */
35 GCancellable *cancellable;
41 g_tls_output_stream_gnutls_finalize (GObject *object)
43 GTlsOutputStreamGnutls *stream = G_TLS_OUTPUT_STREAM_GNUTLS (object);
45 if (stream->priv->conn)
46 g_object_unref (stream->priv->conn);
48 G_OBJECT_CLASS (g_tls_output_stream_gnutls_parent_class)->finalize (object);
52 g_tls_output_stream_gnutls_write (GOutputStream *stream,
55 GCancellable *cancellable,
58 GTlsOutputStreamGnutls *tls_stream = G_TLS_OUTPUT_STREAM_GNUTLS (stream);
60 return g_tls_connection_gnutls_write (tls_stream->priv->conn,
66 g_tls_output_stream_gnutls_write_ready (GIOStreamAdapter *adapter,
69 GTlsOutputStreamGnutls *tls_stream;
70 GSimpleAsyncResult *simple = user_data;
74 tls_stream = G_TLS_OUTPUT_STREAM_GNUTLS (g_async_result_get_source_object (G_ASYNC_RESULT (simple)));
75 g_object_unref (tls_stream);
77 nwrote = g_tls_connection_gnutls_write (tls_stream->priv->conn,
78 tls_stream->priv->buffer,
79 tls_stream->priv->count, FALSE,
80 tls_stream->priv->cancellable,
83 g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK))
91 g_simple_async_result_set_from_error (simple, error);
95 g_simple_async_result_set_op_res_gssize (simple, nwrote);
96 g_simple_async_result_complete (simple);
97 g_object_unref (simple);
103 g_tls_output_stream_gnutls_write_async (GOutputStream *stream,
107 GCancellable *cancellable,
108 GAsyncReadyCallback callback,
111 GTlsOutputStreamGnutls *tls_stream = G_TLS_OUTPUT_STREAM_GNUTLS (stream);
112 GSimpleAsyncResult *simple;
114 GError *error = NULL;
117 simple = g_simple_async_result_new (G_OBJECT (stream), callback, user_data,
118 g_tls_output_stream_gnutls_write_async);
119 nwrote = g_tls_connection_gnutls_write (tls_stream->priv->conn,
120 buffer, count, FALSE,
121 cancellable, &error);
124 !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK))
128 g_simple_async_result_set_from_error (simple, error);
129 g_error_free (error);
132 g_simple_async_result_set_op_res_gssize (simple, nwrote);
133 g_simple_async_result_complete_in_idle (simple);
134 g_object_unref (simple);
138 tls_stream->priv->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
139 tls_stream->priv->buffer = buffer;
140 tls_stream->priv->count = count;
142 source = g_tls_connection_gnutls_create_source (tls_stream->priv->conn,
144 tls_stream->priv->cancellable);
145 g_source_set_callback (source,
146 (GSourceFunc) g_tls_output_stream_gnutls_write_ready,
148 g_source_attach (source, g_main_context_get_thread_default ());
149 g_source_unref (source);
153 g_tls_output_stream_gnutls_write_finish (GOutputStream *stream,
154 GAsyncResult *result,
157 g_return_val_if_fail (G_IS_TLS_OUTPUT_STREAM_GNUTLS (stream), -1);
158 g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (stream), g_tls_output_stream_gnutls_write_async), -1);
160 return g_simple_async_result_get_op_res_gssize (G_SIMPLE_ASYNC_RESULT (result));
164 g_tls_output_stream_gnutls_pollable_is_writable (GPollableOutputStream *pollable)
166 GTlsOutputStreamGnutls *tls_stream = G_TLS_OUTPUT_STREAM_GNUTLS (pollable);
168 return g_tls_connection_gnutls_check (tls_stream->priv->conn, G_IO_OUT);
172 g_tls_output_stream_gnutls_pollable_create_source (GPollableOutputStream *pollable,
173 GCancellable *cancellable)
175 GTlsOutputStreamGnutls *tls_stream = G_TLS_OUTPUT_STREAM_GNUTLS (pollable);
177 return g_tls_connection_gnutls_create_source (tls_stream->priv->conn,
183 g_tls_output_stream_gnutls_pollable_write_nonblocking (GPollableOutputStream *pollable,
188 GTlsOutputStreamGnutls *tls_stream = G_TLS_OUTPUT_STREAM_GNUTLS (pollable);
190 return g_tls_connection_gnutls_write (tls_stream->priv->conn,
196 g_tls_output_stream_gnutls_class_init (GTlsOutputStreamGnutlsClass *klass)
198 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
199 GOutputStreamClass *output_stream_class = G_OUTPUT_STREAM_CLASS (klass);
201 g_type_class_add_private (klass, sizeof (GTlsOutputStreamGnutlsPrivate));
203 gobject_class->finalize = g_tls_output_stream_gnutls_finalize;
205 output_stream_class->write_fn = g_tls_output_stream_gnutls_write;
206 output_stream_class->write_async = g_tls_output_stream_gnutls_write_async;
207 output_stream_class->write_finish = g_tls_output_stream_gnutls_write_finish;
211 g_tls_output_stream_gnutls_pollable_iface_init (GPollableOutputStreamInterface *iface)
213 iface->is_writable = g_tls_output_stream_gnutls_pollable_is_writable;
214 iface->create_source = g_tls_output_stream_gnutls_pollable_create_source;
215 iface->write_nonblocking = g_tls_output_stream_gnutls_pollable_write_nonblocking;
219 g_tls_output_stream_gnutls_init (GTlsOutputStreamGnutls *stream)
221 stream->priv = G_TYPE_INSTANCE_GET_PRIVATE (stream, G_TYPE_TLS_OUTPUT_STREAM_GNUTLS, GTlsOutputStreamGnutlsPrivate);
225 g_tls_output_stream_gnutls_new (GTlsConnectionGnutls *conn)
227 GTlsOutputStreamGnutls *tls_stream;
229 tls_stream = g_object_new (G_TYPE_TLS_OUTPUT_STREAM_GNUTLS, NULL);
230 tls_stream->priv->conn = g_object_ref (conn);
231 return G_OUTPUT_STREAM (tls_stream);