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_dispose (GObject *object)
43 GTlsInputStreamGnutls *stream = G_TLS_INPUT_STREAM_GNUTLS (object);
45 if (stream->priv->conn)
47 g_object_remove_weak_pointer (G_OBJECT (stream->priv->conn),
48 (gpointer *)&stream->priv->conn);
49 stream->priv->conn = NULL;
52 G_OBJECT_CLASS (g_tls_input_stream_gnutls_parent_class)->dispose (object);
56 g_tls_input_stream_gnutls_read (GInputStream *stream,
59 GCancellable *cancellable,
62 GTlsInputStreamGnutls *tls_stream = G_TLS_INPUT_STREAM_GNUTLS (stream);
64 g_return_val_if_fail (tls_stream->priv->conn != NULL, -1);
66 return g_tls_connection_gnutls_read (tls_stream->priv->conn,
72 g_tls_input_stream_gnutls_read_ready (GPollableInputStream *stream,
75 GTlsInputStreamGnutls *tls_stream;
76 GSimpleAsyncResult *simple = user_data;
80 tls_stream = G_TLS_INPUT_STREAM_GNUTLS (g_async_result_get_source_object (G_ASYNC_RESULT (simple)));
81 g_object_unref (tls_stream);
83 nread = g_tls_connection_gnutls_read (tls_stream->priv->conn,
84 tls_stream->priv->buffer,
85 tls_stream->priv->count, FALSE,
86 tls_stream->priv->cancellable,
89 g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK))
97 g_simple_async_result_set_from_error (simple, error);
101 g_simple_async_result_set_op_res_gssize (simple, nread);
103 if (tls_stream->priv->cancellable)
104 g_object_unref (tls_stream->priv->cancellable);
105 g_simple_async_result_complete (simple);
106 g_object_unref (simple);
112 g_tls_input_stream_gnutls_read_async (GInputStream *stream,
116 GCancellable *cancellable,
117 GAsyncReadyCallback callback,
120 GTlsInputStreamGnutls *tls_stream = G_TLS_INPUT_STREAM_GNUTLS (stream);
121 GSimpleAsyncResult *simple;
123 GError *error = NULL;
126 g_return_if_fail (tls_stream->priv->conn != NULL);
128 simple = g_simple_async_result_new (G_OBJECT (stream), callback, user_data,
129 g_tls_input_stream_gnutls_read_async);
130 nread = g_tls_connection_gnutls_read (tls_stream->priv->conn,
131 buffer, count, FALSE,
132 cancellable, &error);
135 !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK))
139 g_simple_async_result_set_from_error (simple, error);
140 g_error_free (error);
143 g_simple_async_result_set_op_res_gssize (simple, nread);
144 g_simple_async_result_complete_in_idle (simple);
145 g_object_unref (simple);
149 tls_stream->priv->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
150 tls_stream->priv->buffer = buffer;
151 tls_stream->priv->count = count;
153 source = g_tls_connection_gnutls_create_source (tls_stream->priv->conn,
155 tls_stream->priv->cancellable);
156 g_source_set_callback (source,
157 (GSourceFunc) g_tls_input_stream_gnutls_read_ready,
159 g_source_attach (source, g_main_context_get_thread_default ());
160 g_source_unref (source);
164 g_tls_input_stream_gnutls_read_finish (GInputStream *stream,
165 GAsyncResult *result,
168 g_return_val_if_fail (G_IS_TLS_INPUT_STREAM_GNUTLS (stream), -1);
169 g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (stream), g_tls_input_stream_gnutls_read_async), -1);
171 return g_simple_async_result_get_op_res_gssize (G_SIMPLE_ASYNC_RESULT (result));
175 g_tls_input_stream_gnutls_pollable_is_readable (GPollableInputStream *pollable)
177 GTlsInputStreamGnutls *tls_stream = G_TLS_INPUT_STREAM_GNUTLS (pollable);
179 g_return_val_if_fail (tls_stream->priv->conn != NULL, FALSE);
181 return g_tls_connection_gnutls_check (tls_stream->priv->conn, G_IO_IN);
185 g_tls_input_stream_gnutls_pollable_create_source (GPollableInputStream *pollable,
186 GCancellable *cancellable)
188 GTlsInputStreamGnutls *tls_stream = G_TLS_INPUT_STREAM_GNUTLS (pollable);
190 g_return_val_if_fail (tls_stream->priv->conn != NULL, NULL);
192 return g_tls_connection_gnutls_create_source (tls_stream->priv->conn,
198 g_tls_input_stream_gnutls_pollable_read_nonblocking (GPollableInputStream *pollable,
203 GTlsInputStreamGnutls *tls_stream = G_TLS_INPUT_STREAM_GNUTLS (pollable);
205 return g_tls_connection_gnutls_read (tls_stream->priv->conn,
211 g_tls_input_stream_gnutls_class_init (GTlsInputStreamGnutlsClass *klass)
213 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
214 GInputStreamClass *input_stream_class = G_INPUT_STREAM_CLASS (klass);
216 g_type_class_add_private (klass, sizeof (GTlsInputStreamGnutlsPrivate));
218 gobject_class->dispose = g_tls_input_stream_gnutls_dispose;
220 input_stream_class->read_fn = g_tls_input_stream_gnutls_read;
221 input_stream_class->read_async = g_tls_input_stream_gnutls_read_async;
222 input_stream_class->read_finish = g_tls_input_stream_gnutls_read_finish;
226 g_tls_input_stream_gnutls_pollable_iface_init (GPollableInputStreamInterface *iface)
228 iface->is_readable = g_tls_input_stream_gnutls_pollable_is_readable;
229 iface->create_source = g_tls_input_stream_gnutls_pollable_create_source;
230 iface->read_nonblocking = g_tls_input_stream_gnutls_pollable_read_nonblocking;
234 g_tls_input_stream_gnutls_init (GTlsInputStreamGnutls *stream)
236 stream->priv = G_TYPE_INSTANCE_GET_PRIVATE (stream, G_TYPE_TLS_INPUT_STREAM_GNUTLS, GTlsInputStreamGnutlsPrivate);
240 g_tls_input_stream_gnutls_new (GTlsConnectionGnutls *conn)
242 GTlsInputStreamGnutls *tls_stream;
244 tls_stream = g_object_new (G_TYPE_TLS_INPUT_STREAM_GNUTLS, NULL);
245 tls_stream->priv->conn = conn;
246 g_object_add_weak_pointer (G_OBJECT (conn),
247 (gpointer *)&tls_stream->priv->conn);
249 return G_INPUT_STREAM (tls_stream);