gsourceclosure: use g_cclosure_marshal_generic
[platform/upstream/glib.git] / gio / gpollableutils.c
1 /* GIO - GLib Input, Output and Streaming Library
2  *
3  * Copyright (C) 2010 Red Hat, Inc.
4  *
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.
9  *
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.
14  *
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.
19  */
20
21 #include "config.h"
22
23 #include <errno.h>
24
25 #include "gpollableinputstream.h"
26 #include "gasynchelper.h"
27 #include "glibintl.h"
28
29 /**
30  * SECTION:gpollableutils
31  * @short_description: Utilities for pollable streams
32  * @include: gio/gio.h
33  *
34  * Utility functions for #GPollableInputStream and
35  * #GPollableOutputStream implementations.
36  */
37
38 typedef struct {
39   GSource       source;
40
41   GObject      *stream;
42 } GPollableSource;
43
44 static gboolean
45 pollable_source_prepare (GSource *source,
46                          gint    *timeout)
47 {
48   *timeout = -1;
49   return FALSE;
50 }
51
52 static gboolean
53 pollable_source_check (GSource *source)
54 {
55   return FALSE;
56 }
57
58 static gboolean
59 pollable_source_dispatch (GSource     *source,
60                           GSourceFunc  callback,
61                           gpointer     user_data)
62 {
63   GPollableSourceFunc func = (GPollableSourceFunc)callback;
64   GPollableSource *pollable_source = (GPollableSource *)source;
65
66   return (*func) (pollable_source->stream, user_data);
67 }
68
69 static void
70 pollable_source_finalize (GSource *source)
71 {
72   GPollableSource *pollable_source = (GPollableSource *)source;
73
74   g_object_unref (pollable_source->stream);
75 }
76
77 static gboolean
78 pollable_source_closure_callback (GObject  *stream,
79                                   gpointer  data)
80 {
81   GClosure *closure = data;
82
83   GValue param = G_VALUE_INIT;
84   GValue result_value = G_VALUE_INIT;
85   gboolean result;
86
87   g_value_init (&result_value, G_TYPE_BOOLEAN);
88
89   g_value_init (&param, G_TYPE_OBJECT);
90   g_value_set_object (&param, stream);
91
92   g_closure_invoke (closure, &result_value, 1, &param, NULL);
93
94   result = g_value_get_boolean (&result_value);
95   g_value_unset (&result_value);
96   g_value_unset (&param);
97
98   return result;
99 }
100
101 static GSourceFuncs pollable_source_funcs =
102 {
103   pollable_source_prepare,
104   pollable_source_check,
105   pollable_source_dispatch,
106   pollable_source_finalize,
107   (GSourceFunc)pollable_source_closure_callback,
108 };
109
110 /**
111  * g_pollable_source_new:
112  * @pollable_stream: the stream associated with the new source
113  *
114  * Utility method for #GPollableInputStream and #GPollableOutputStream
115  * implementations. Creates a new #GSource that expects a callback of
116  * type #GPollableSourceFunc. The new source does not actually do
117  * anything on its own; use g_source_add_child_source() to add other
118  * sources to it to cause it to trigger.
119  *
120  * Return value: (transfer full): the new #GSource.
121  *
122  * Since: 2.28
123  */
124 GSource *
125 g_pollable_source_new (GObject *pollable_stream)
126 {
127   GSource *source;
128   GPollableSource *pollable_source;
129
130   g_return_val_if_fail (G_IS_POLLABLE_INPUT_STREAM (pollable_stream) ||
131                         G_IS_POLLABLE_OUTPUT_STREAM (pollable_stream), NULL);
132
133   source = g_source_new (&pollable_source_funcs, sizeof (GPollableSource));
134   g_source_set_name (source, "GPollableSource");
135   pollable_source = (GPollableSource *)source;
136   pollable_source->stream = g_object_ref (pollable_stream);
137
138   return source;
139 }
140
141 /**
142  * g_pollable_source_new_full:
143  * @pollable_stream: (type GObject): the stream associated with the
144  *   new source
145  * @child_source: (allow-none): optional child source to attach
146  * @cancellable: (allow-none): optional #GCancellable to attach
147  *
148  * Utility method for #GPollableInputStream and #GPollableOutputStream
149  * implementations. Creates a new #GSource, as with
150  * g_pollable_source_new(), but also attaching @child_source (with a
151  * dummy callback), and @cancellable, if they are non-%NULL.
152  *
153  * Return value: (transfer full): the new #GSource.
154  *
155  * Since: 2.34
156  */
157 GSource *
158 g_pollable_source_new_full (gpointer      pollable_stream,
159                             GSource      *child_source,
160                             GCancellable *cancellable)
161 {
162   GSource *source;
163
164   g_return_val_if_fail (G_IS_POLLABLE_INPUT_STREAM (pollable_stream) ||
165                         G_IS_POLLABLE_OUTPUT_STREAM (pollable_stream), NULL);
166
167   source = g_pollable_source_new (pollable_stream);
168   if (child_source)
169     {
170       g_source_set_dummy_callback (child_source);
171       g_source_add_child_source (source, child_source);
172     }
173   if (cancellable)
174     {
175       GSource *cancellable_source = g_cancellable_source_new (cancellable);
176
177       g_source_set_dummy_callback (cancellable_source);
178       g_source_add_child_source (source, cancellable_source);
179       g_source_unref (cancellable_source);
180     }
181
182   return source;
183 }
184
185 /**
186  * g_pollable_stream_read:
187  * @stream: a #GInputStream
188  * @buffer: a buffer to read data into
189  * @count: the number of bytes to read
190  * @blocking: whether to do blocking I/O
191  * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
192  * @error: location to store the error occurring, or %NULL to ignore
193  *
194  * Tries to read from @stream, as with g_input_stream_read() (if
195  * @blocking is %TRUE) or g_pollable_input_stream_read_nonblocking()
196  * (if @blocking is %FALSE). This can be used to more easily share
197  * code between blocking and non-blocking implementations of a method.
198  *
199  * If @blocking is %FALSE, then @stream must be a
200  * #GPollableInputStream for which g_pollable_input_stream_can_poll()
201  * returns %TRUE, or else the behavior is undefined. If @blocking is
202  * %TRUE, then @stream does not need to be a #GPollableInputStream.
203  *
204  * Returns: the number of bytes read, or -1 on error.
205  *
206  * Since: 2.34
207  */
208 gssize
209 g_pollable_stream_read (GInputStream   *stream,
210                         void           *buffer,
211                         gsize           count,
212                         gboolean        blocking,
213                         GCancellable   *cancellable,
214                         GError        **error)
215 {
216   if (blocking)
217     {
218       return g_input_stream_read (stream,
219                                   buffer, count,
220                                   cancellable, error);
221     }
222   else
223     {
224       return g_pollable_input_stream_read_nonblocking (G_POLLABLE_INPUT_STREAM (stream),
225                                                        buffer, count,
226                                                        cancellable, error);
227     }
228 }
229
230 /**
231  * g_pollable_stream_write:
232  * @stream: a #GOutputStream.
233  * @buffer: (array length=count) (element-type guint8): the buffer
234  *   containing the data to write.
235  * @count: the number of bytes to write
236  * @blocking: whether to do blocking I/O
237  * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
238  * @error: location to store the error occurring, or %NULL to ignore
239  *
240  * Tries to write to @stream, as with g_output_stream_write() (if
241  * @blocking is %TRUE) or g_pollable_output_stream_write_nonblocking()
242  * (if @blocking is %FALSE). This can be used to more easily share
243  * code between blocking and non-blocking implementations of a method.
244  *
245  * If @blocking is %FALSE, then @stream must be a
246  * #GPollableOutputStream for which
247  * g_pollable_output_stream_can_poll() returns %TRUE or else the
248  * behavior is undefined. If @blocking is %TRUE, then @stream does not
249  * need to be a #GPollableOutputStream.
250  *
251  * Returns: the number of bytes written, or -1 on error.
252  *
253  * Since: 2.34
254  */
255 gssize
256 g_pollable_stream_write (GOutputStream   *stream,
257                          const void      *buffer,
258                          gsize            count,
259                          gboolean         blocking,
260                          GCancellable    *cancellable,
261                          GError         **error)
262 {
263   if (blocking)
264     {
265       return g_output_stream_write (stream,
266                                     buffer, count,
267                                     cancellable, error);
268     }
269   else
270     {
271       return g_pollable_output_stream_write_nonblocking (G_POLLABLE_OUTPUT_STREAM (stream),
272                                                          buffer, count,
273                                                          cancellable, error);
274     }
275 }
276
277 /**
278  * g_pollable_stream_write_all:
279  * @stream: a #GOutputStream.
280  * @buffer: (array length=count) (element-type guint8): the buffer
281  *   containing the data to write.
282  * @count: the number of bytes to write
283  * @blocking: whether to do blocking I/O
284  * @bytes_written: (out): location to store the number of bytes that was 
285  *   written to the stream
286  * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
287  * @error: location to store the error occurring, or %NULL to ignore
288  *
289  * Tries to write @count bytes to @stream, as with
290  * g_output_stream_write_all(), but using g_pollable_stream_write()
291  * rather than g_output_stream_write().
292  *
293  * On a successful write of @count bytes, %TRUE is returned, and
294  * @bytes_written is set to @count.
295  * 
296  * If there is an error during the operation (including
297  * %G_IO_ERROR_WOULD_BLOCK in the non-blocking case), %FALSE is
298  * returned and @error is set to indicate the error status,
299  * @bytes_written is updated to contain the number of bytes written
300  * into the stream before the error occurred.
301  *
302  * As with g_pollable_stream_write(), if @blocking is %FALSE, then
303  * @stream must be a #GPollableOutputStream for which
304  * g_pollable_output_stream_can_poll() returns %TRUE or else the
305  * behavior is undefined. If @blocking is %TRUE, then @stream does not
306  * need to be a #GPollableOutputStream.
307  *
308  * Return value: %TRUE on success, %FALSE if there was an error
309  *
310  * Since: 2.34
311  */
312 gboolean
313 g_pollable_stream_write_all (GOutputStream  *stream,
314                              const void     *buffer,
315                              gsize           count,
316                              gboolean        blocking,
317                              gsize          *bytes_written,
318                              GCancellable   *cancellable,
319                              GError        **error)
320 {
321   gsize _bytes_written;
322   gssize res;
323
324   _bytes_written = 0;
325   while (_bytes_written < count)
326     {
327       res = g_pollable_stream_write (stream,
328                                      (char *)buffer + _bytes_written,
329                                      count - _bytes_written,
330                                      blocking,
331                                      cancellable, error);
332       if (res == -1)
333         {
334           if (bytes_written)
335             *bytes_written = _bytes_written;
336           return FALSE;
337         }
338
339       if (res == 0)
340         g_warning ("Write returned zero without error");
341
342       _bytes_written += res;
343     }
344
345   if (bytes_written)
346     *bytes_written = _bytes_written;
347
348   return TRUE;
349 }