Merge remote branch 'gvdb/master'
[platform/upstream/glib.git] / gio / gfilteroutputstream.c
1 /* GIO - GLib Input, Output and Streaming Library
2  * 
3  * Copyright (C) 2006-2007 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  * Author: Christian Kellner <gicmo@gnome.org> 
21  */
22
23 #include "config.h"
24 #include "gfilteroutputstream.h"
25 #include "gsimpleasyncresult.h"
26 #include "goutputstream.h"
27 #include "glibintl.h"
28
29 #include "gioalias.h"
30
31 /**
32  * SECTION:gfilteroutputstream
33  * @short_description: Filter Output Stream
34  * @include: gio/gio.h
35  *
36  **/
37
38 enum {
39   PROP_0,
40   PROP_BASE_STREAM,
41   PROP_CLOSE_BASE
42 };
43
44 static void     g_filter_output_stream_set_property (GObject      *object,
45                                                      guint         prop_id,
46                                                      const GValue *value,
47                                                      GParamSpec   *pspec);
48
49 static void     g_filter_output_stream_get_property (GObject    *object,
50                                                      guint       prop_id,
51                                                      GValue     *value,
52                                                      GParamSpec *pspec);
53 static void     g_filter_output_stream_dispose      (GObject *object);
54
55
56 static gssize   g_filter_output_stream_write        (GOutputStream *stream,
57                                                      const void    *buffer,
58                                                      gsize          count,
59                                                      GCancellable  *cancellable,
60                                                      GError       **error);
61 static gboolean g_filter_output_stream_flush        (GOutputStream    *stream,
62                                                      GCancellable  *cancellable,
63                                                      GError          **error);
64 static gboolean g_filter_output_stream_close        (GOutputStream  *stream,
65                                                      GCancellable   *cancellable,
66                                                      GError        **error);
67
68 G_DEFINE_TYPE (GFilterOutputStream, g_filter_output_stream, G_TYPE_OUTPUT_STREAM)
69
70 #define GET_PRIVATE(inst) G_TYPE_INSTANCE_GET_PRIVATE (inst, \
71   G_TYPE_FILTER_OUTPUT_STREAM, GFilterOutputStreamPrivate)
72
73 typedef struct
74 {
75   gboolean close_base;
76 } GFilterOutputStreamPrivate;
77
78 static void
79 g_filter_output_stream_class_init (GFilterOutputStreamClass *klass)
80 {
81   GObjectClass *object_class;
82   GOutputStreamClass *ostream_class;
83
84   object_class = G_OBJECT_CLASS (klass);
85   object_class->get_property = g_filter_output_stream_get_property;
86   object_class->set_property = g_filter_output_stream_set_property;
87   object_class->dispose      = g_filter_output_stream_dispose;
88     
89   ostream_class = G_OUTPUT_STREAM_CLASS (klass);
90   ostream_class->write_fn = g_filter_output_stream_write;
91   ostream_class->flush = g_filter_output_stream_flush;
92   ostream_class->close_fn = g_filter_output_stream_close;
93
94   g_type_class_add_private (klass, sizeof (GFilterOutputStreamPrivate));
95
96   g_object_class_install_property (object_class,
97                                    PROP_BASE_STREAM,
98                                    g_param_spec_object ("base-stream",
99                                                          P_("The Filter Base Stream"),
100                                                          P_("The underlying base stream on which the io ops will be done."),
101                                                          G_TYPE_OUTPUT_STREAM,
102                                                          G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | 
103                                                          G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
104
105   g_object_class_install_property (object_class,
106                                    PROP_CLOSE_BASE,
107                                    g_param_spec_boolean ("close-base-stream",
108                                                          P_("Close Base Stream"),
109                                                          P_("If the base stream should be closed when the filter stream is closed."),
110                                                          TRUE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
111                                                          G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
112 }
113
114 static void
115 g_filter_output_stream_set_property (GObject      *object,
116                                      guint         prop_id,
117                                      const GValue *value,
118                                      GParamSpec   *pspec)
119 {
120   GFilterOutputStream *filter_stream;
121   GObject *obj;
122
123   filter_stream = G_FILTER_OUTPUT_STREAM (object);
124
125   switch (prop_id) 
126     {
127     case PROP_BASE_STREAM:
128       obj = g_value_dup_object (value);
129       filter_stream->base_stream = G_OUTPUT_STREAM (obj);
130       break;
131
132     case PROP_CLOSE_BASE:
133       g_filter_output_stream_set_close_base_stream (filter_stream,
134                                                     g_value_get_boolean (value));
135       break;
136
137     default:
138       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
139       break;
140     }
141
142 }
143
144 static void
145 g_filter_output_stream_get_property (GObject    *object,
146                                      guint       prop_id,
147                                      GValue     *value,
148                                      GParamSpec *pspec)
149 {
150   GFilterOutputStream *filter_stream;
151
152   filter_stream = G_FILTER_OUTPUT_STREAM (object);
153
154   switch (prop_id)
155     {
156     case PROP_BASE_STREAM:
157       g_value_set_object (value, filter_stream->base_stream);
158       break;
159
160     case PROP_CLOSE_BASE:
161       g_value_set_boolean (value, GET_PRIVATE (filter_stream)->close_base);
162       break;
163
164     default:
165       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
166       break;
167     }
168
169 }
170
171 static void
172 g_filter_output_stream_dispose (GObject *object)
173 {
174   GFilterOutputStream *stream;
175
176   stream = G_FILTER_OUTPUT_STREAM (object);
177
178   G_OBJECT_CLASS (g_filter_output_stream_parent_class)->dispose (object);
179   
180   if (stream->base_stream)
181     {
182       g_object_unref (stream->base_stream);
183       stream->base_stream = NULL;
184     }
185 }
186
187
188 static void
189 g_filter_output_stream_init (GFilterOutputStream *stream)
190 {
191 }
192
193 /**
194  * g_filter_output_stream_get_base_stream:
195  * @stream: a #GFilterOutputStream.
196  * 
197  * Gets the base stream for the filter stream.
198  *
199  * Returns: a #GOutputStream.
200  **/
201 GOutputStream *
202 g_filter_output_stream_get_base_stream (GFilterOutputStream *stream)
203 {
204   g_return_val_if_fail (G_IS_FILTER_OUTPUT_STREAM (stream), NULL);
205
206   return stream->base_stream;
207 }
208
209 /**
210  * g_filter_output_stream_get_close_base_stream:
211  * @stream: a #GFilterOutputStream.
212  *
213  * Returns whether the base stream will be closed when @stream is
214  * closed.
215  *
216  * Return value: %TRUE if the base stream will be closed.
217  **/
218 gboolean
219 g_filter_output_stream_get_close_base_stream (GFilterOutputStream *stream)
220 {
221   g_return_val_if_fail (G_IS_FILTER_OUTPUT_STREAM (stream), FALSE);
222
223   return GET_PRIVATE (stream)->close_base;
224 }
225
226 /**
227  * g_filter_output_stream_set_close_base_stream:
228  * @stream: a #GFilterOutputStream.
229  * @close_base: %TRUE to close the base stream.
230  *
231  * Sets whether the base stream will be closed when @stream is closed.
232  **/
233 void
234 g_filter_output_stream_set_close_base_stream (GFilterOutputStream *stream,
235                                               gboolean             close_base)
236 {
237   GFilterOutputStreamPrivate *priv;
238
239   g_return_if_fail (G_IS_FILTER_OUTPUT_STREAM (stream));
240
241   close_base = !!close_base;
242
243   priv = GET_PRIVATE (stream);
244
245   if (priv->close_base != close_base)
246     {
247       priv->close_base = close_base;
248       g_object_notify (G_OBJECT (stream), "close-base-stream");
249     }
250 }
251
252 static gssize
253 g_filter_output_stream_write (GOutputStream  *stream,
254                               const void     *buffer,
255                               gsize           count,
256                               GCancellable   *cancellable,
257                               GError        **error)
258 {
259   GFilterOutputStream *filter_stream;
260   gssize nwritten;
261
262   filter_stream = G_FILTER_OUTPUT_STREAM (stream);
263
264   nwritten = g_output_stream_write (filter_stream->base_stream,
265                                     buffer,
266                                     count,
267                                     cancellable,
268                                     error);
269
270   return nwritten;
271 }
272
273 static gboolean
274 g_filter_output_stream_flush (GOutputStream  *stream,
275                               GCancellable   *cancellable,
276                               GError        **error)
277 {
278   GFilterOutputStream *filter_stream;
279   gboolean res;
280
281   filter_stream = G_FILTER_OUTPUT_STREAM (stream);
282
283   res = g_output_stream_flush (filter_stream->base_stream,
284                                cancellable,
285                                error);
286
287   return res;
288 }
289
290 static gboolean
291 g_filter_output_stream_close (GOutputStream  *stream,
292                               GCancellable   *cancellable,
293                               GError        **error)
294 {
295   gboolean res = TRUE;
296
297   if (GET_PRIVATE (stream)->close_base)
298     {
299       GFilterOutputStream *filter_stream;
300
301       filter_stream = G_FILTER_OUTPUT_STREAM (stream);
302
303       res = g_output_stream_close (filter_stream->base_stream,
304                                    cancellable,
305                                    error);
306     }
307
308   return res;
309 }
310
311 #define __G_FILTER_OUTPUT_STREAM_C__
312 #include "gioaliasdef.c"