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 "gtlsinputstream-gnutls.h"
24 static void g_tls_input_stream_gnutls_pollable_iface_init (GPollableInputStreamInterface *iface);
26 G_DEFINE_TYPE_WITH_CODE (GTlsInputStreamGnutls, g_tls_input_stream_gnutls, G_TYPE_INPUT_STREAM,
27 G_IMPLEMENT_INTERFACE (G_TYPE_POLLABLE_INPUT_STREAM, g_tls_input_stream_gnutls_pollable_iface_init)
30 struct _GTlsInputStreamGnutlsPrivate
32 GTlsConnectionGnutls *conn;
34 /* pending operation metadata */
35 GCancellable *cancellable;
41 g_tls_input_stream_gnutls_finalize (GObject *object)
43 GTlsInputStreamGnutls *stream = G_TLS_INPUT_STREAM_GNUTLS (object);
45 if (stream->priv->conn)
46 g_object_unref (stream->priv->conn);
48 G_OBJECT_CLASS (g_tls_input_stream_gnutls_parent_class)->finalize (object);
52 g_tls_input_stream_gnutls_read (GInputStream *stream,
55 GCancellable *cancellable,
58 GTlsInputStreamGnutls *tls_stream = G_TLS_INPUT_STREAM_GNUTLS (stream);
60 return g_tls_connection_gnutls_read (tls_stream->priv->conn,
66 g_tls_input_stream_gnutls_read_ready (GPollableInputStream *stream,
69 GTlsInputStreamGnutls *tls_stream;
70 GSimpleAsyncResult *simple = user_data;
74 tls_stream = G_TLS_INPUT_STREAM_GNUTLS (g_async_result_get_source_object (G_ASYNC_RESULT (simple)));
75 g_object_unref (tls_stream);
77 nread = g_tls_connection_gnutls_read (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, nread);
97 if (tls_stream->priv->cancellable)
98 g_object_unref (tls_stream->priv->cancellable);
99 g_simple_async_result_complete (simple);
100 g_object_unref (simple);
106 g_tls_input_stream_gnutls_read_async (GInputStream *stream,
110 GCancellable *cancellable,
111 GAsyncReadyCallback callback,
114 GTlsInputStreamGnutls *tls_stream = G_TLS_INPUT_STREAM_GNUTLS (stream);
115 GSimpleAsyncResult *simple;
117 GError *error = NULL;
120 simple = g_simple_async_result_new (G_OBJECT (stream), callback, user_data,
121 g_tls_input_stream_gnutls_read_async);
122 nread = g_tls_connection_gnutls_read (tls_stream->priv->conn,
123 buffer, count, FALSE,
124 cancellable, &error);
127 !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK))
131 g_simple_async_result_set_from_error (simple, error);
132 g_error_free (error);
135 g_simple_async_result_set_op_res_gssize (simple, nread);
136 g_simple_async_result_complete_in_idle (simple);
137 g_object_unref (simple);
141 tls_stream->priv->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
142 tls_stream->priv->buffer = buffer;
143 tls_stream->priv->count = count;
145 source = g_tls_connection_gnutls_create_source (tls_stream->priv->conn,
147 tls_stream->priv->cancellable);
148 g_source_set_callback (source,
149 (GSourceFunc) g_tls_input_stream_gnutls_read_ready,
151 g_source_attach (source, g_main_context_get_thread_default ());
152 g_source_unref (source);
156 g_tls_input_stream_gnutls_read_finish (GInputStream *stream,
157 GAsyncResult *result,
160 g_return_val_if_fail (G_IS_TLS_INPUT_STREAM_GNUTLS (stream), -1);
161 g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (stream), g_tls_input_stream_gnutls_read_async), -1);
163 return g_simple_async_result_get_op_res_gssize (G_SIMPLE_ASYNC_RESULT (result));
167 g_tls_input_stream_gnutls_pollable_is_readable (GPollableInputStream *pollable)
169 GTlsInputStreamGnutls *tls_stream = G_TLS_INPUT_STREAM_GNUTLS (pollable);
171 return g_tls_connection_gnutls_check (tls_stream->priv->conn, G_IO_IN);
175 g_tls_input_stream_gnutls_pollable_create_source (GPollableInputStream *pollable,
176 GCancellable *cancellable)
178 GTlsInputStreamGnutls *tls_stream = G_TLS_INPUT_STREAM_GNUTLS (pollable);
180 return g_tls_connection_gnutls_create_source (tls_stream->priv->conn,
186 g_tls_input_stream_gnutls_pollable_read_nonblocking (GPollableInputStream *pollable,
191 GTlsInputStreamGnutls *tls_stream = G_TLS_INPUT_STREAM_GNUTLS (pollable);
193 return g_tls_connection_gnutls_read (tls_stream->priv->conn,
199 g_tls_input_stream_gnutls_class_init (GTlsInputStreamGnutlsClass *klass)
201 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
202 GInputStreamClass *input_stream_class = G_INPUT_STREAM_CLASS (klass);
204 g_type_class_add_private (klass, sizeof (GTlsInputStreamGnutlsPrivate));
206 gobject_class->finalize = g_tls_input_stream_gnutls_finalize;
208 input_stream_class->read_fn = g_tls_input_stream_gnutls_read;
209 input_stream_class->read_async = g_tls_input_stream_gnutls_read_async;
210 input_stream_class->read_finish = g_tls_input_stream_gnutls_read_finish;
214 g_tls_input_stream_gnutls_pollable_iface_init (GPollableInputStreamInterface *iface)
216 iface->is_readable = g_tls_input_stream_gnutls_pollable_is_readable;
217 iface->create_source = g_tls_input_stream_gnutls_pollable_create_source;
218 iface->read_nonblocking = g_tls_input_stream_gnutls_pollable_read_nonblocking;
222 g_tls_input_stream_gnutls_init (GTlsInputStreamGnutls *stream)
224 stream->priv = G_TYPE_INSTANCE_GET_PRIVATE (stream, G_TYPE_TLS_INPUT_STREAM_GNUTLS, GTlsInputStreamGnutlsPrivate);
228 g_tls_input_stream_gnutls_new (GTlsConnectionGnutls *conn)
230 GTlsInputStreamGnutls *tls_stream;
232 tls_stream = g_object_new (G_TYPE_TLS_INPUT_STREAM_GNUTLS, NULL);
233 tls_stream->priv->conn = g_object_ref (conn);
234 return G_INPUT_STREAM (tls_stream);