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