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