Change LGPL-2.1+ to LGPL-2.1-or-later
[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  * SPDX-License-Identifier: LGPL-2.1-or-later
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General
18  * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
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 typedef struct
71 {
72   gboolean close_base;
73 } GFilterOutputStreamPrivate;
74
75 G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GFilterOutputStream, g_filter_output_stream, G_TYPE_OUTPUT_STREAM)
76
77 static void
78 g_filter_output_stream_class_init (GFilterOutputStreamClass *klass)
79 {
80   GObjectClass *object_class;
81   GOutputStreamClass *ostream_class;
82
83   object_class = G_OBJECT_CLASS (klass);
84   object_class->get_property = g_filter_output_stream_get_property;
85   object_class->set_property = g_filter_output_stream_set_property;
86   object_class->dispose      = g_filter_output_stream_dispose;
87     
88   ostream_class = G_OUTPUT_STREAM_CLASS (klass);
89   ostream_class->write_fn = g_filter_output_stream_write;
90   ostream_class->flush = g_filter_output_stream_flush;
91   ostream_class->close_fn = g_filter_output_stream_close;
92
93   g_object_class_install_property (object_class,
94                                    PROP_BASE_STREAM,
95                                    g_param_spec_object ("base-stream",
96                                                          P_("The Filter Base Stream"),
97                                                          P_("The underlying base stream on which the io ops will be done."),
98                                                          G_TYPE_OUTPUT_STREAM,
99                                                          G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | 
100                                                          G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
101
102   g_object_class_install_property (object_class,
103                                    PROP_CLOSE_BASE,
104                                    g_param_spec_boolean ("close-base-stream",
105                                                          P_("Close Base Stream"),
106                                                          P_("If the base stream should be closed when the filter stream is closed."),
107                                                          TRUE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
108                                                          G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
109 }
110
111 static void
112 g_filter_output_stream_set_property (GObject      *object,
113                                      guint         prop_id,
114                                      const GValue *value,
115                                      GParamSpec   *pspec)
116 {
117   GFilterOutputStream *filter_stream;
118   GObject *obj;
119
120   filter_stream = G_FILTER_OUTPUT_STREAM (object);
121
122   switch (prop_id) 
123     {
124     case PROP_BASE_STREAM:
125       obj = g_value_dup_object (value);
126       filter_stream->base_stream = G_OUTPUT_STREAM (obj);
127       break;
128
129     case PROP_CLOSE_BASE:
130       g_filter_output_stream_set_close_base_stream (filter_stream,
131                                                     g_value_get_boolean (value));
132       break;
133
134     default:
135       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
136       break;
137     }
138
139 }
140
141 static void
142 g_filter_output_stream_get_property (GObject    *object,
143                                      guint       prop_id,
144                                      GValue     *value,
145                                      GParamSpec *pspec)
146 {
147   GFilterOutputStream *filter_stream;
148   GFilterOutputStreamPrivate *priv;
149
150   filter_stream = G_FILTER_OUTPUT_STREAM (object);
151   priv = g_filter_output_stream_get_instance_private (filter_stream);
152
153   switch (prop_id)
154     {
155     case PROP_BASE_STREAM:
156       g_value_set_object (value, filter_stream->base_stream);
157       break;
158
159     case PROP_CLOSE_BASE:
160       g_value_set_boolean (value, priv->close_base);
161       break;
162
163     default:
164       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
165       break;
166     }
167
168 }
169
170 static void
171 g_filter_output_stream_dispose (GObject *object)
172 {
173   GFilterOutputStream *stream;
174
175   stream = G_FILTER_OUTPUT_STREAM (object);
176
177   G_OBJECT_CLASS (g_filter_output_stream_parent_class)->dispose (object);
178   
179   if (stream->base_stream)
180     {
181       g_object_unref (stream->base_stream);
182       stream->base_stream = NULL;
183     }
184 }
185
186
187 static void
188 g_filter_output_stream_init (GFilterOutputStream *stream)
189 {
190 }
191
192 /**
193  * g_filter_output_stream_get_base_stream:
194  * @stream: a #GFilterOutputStream.
195  * 
196  * Gets the base stream for the filter stream.
197  *
198  * Returns: (transfer none): a #GOutputStream.
199  **/
200 GOutputStream *
201 g_filter_output_stream_get_base_stream (GFilterOutputStream *stream)
202 {
203   g_return_val_if_fail (G_IS_FILTER_OUTPUT_STREAM (stream), NULL);
204
205   return stream->base_stream;
206 }
207
208 /**
209  * g_filter_output_stream_get_close_base_stream:
210  * @stream: a #GFilterOutputStream.
211  *
212  * Returns whether the base stream will be closed when @stream is
213  * closed.
214  *
215  * Returns: %TRUE if the base stream will be closed.
216  **/
217 gboolean
218 g_filter_output_stream_get_close_base_stream (GFilterOutputStream *stream)
219 {
220   GFilterOutputStreamPrivate *priv;
221
222   g_return_val_if_fail (G_IS_FILTER_OUTPUT_STREAM (stream), FALSE);
223
224   priv = g_filter_output_stream_get_instance_private (stream);
225
226   return priv->close_base;
227 }
228
229 /**
230  * g_filter_output_stream_set_close_base_stream:
231  * @stream: a #GFilterOutputStream.
232  * @close_base: %TRUE to close the base stream.
233  *
234  * Sets whether the base stream will be closed when @stream is closed.
235  **/
236 void
237 g_filter_output_stream_set_close_base_stream (GFilterOutputStream *stream,
238                                               gboolean             close_base)
239 {
240   GFilterOutputStreamPrivate *priv;
241
242   g_return_if_fail (G_IS_FILTER_OUTPUT_STREAM (stream));
243
244   close_base = !!close_base;
245
246   priv = g_filter_output_stream_get_instance_private (stream);
247
248   if (priv->close_base != close_base)
249     {
250       priv->close_base = close_base;
251       g_object_notify (G_OBJECT (stream), "close-base-stream");
252     }
253 }
254
255 static gssize
256 g_filter_output_stream_write (GOutputStream  *stream,
257                               const void     *buffer,
258                               gsize           count,
259                               GCancellable   *cancellable,
260                               GError        **error)
261 {
262   GFilterOutputStream *filter_stream;
263   gssize nwritten;
264
265   filter_stream = G_FILTER_OUTPUT_STREAM (stream);
266
267   nwritten = g_output_stream_write (filter_stream->base_stream,
268                                     buffer,
269                                     count,
270                                     cancellable,
271                                     error);
272
273   return nwritten;
274 }
275
276 static gboolean
277 g_filter_output_stream_flush (GOutputStream  *stream,
278                               GCancellable   *cancellable,
279                               GError        **error)
280 {
281   GFilterOutputStream *filter_stream;
282   gboolean res;
283
284   filter_stream = G_FILTER_OUTPUT_STREAM (stream);
285
286   res = g_output_stream_flush (filter_stream->base_stream,
287                                cancellable,
288                                error);
289
290   return res;
291 }
292
293 static gboolean
294 g_filter_output_stream_close (GOutputStream  *stream,
295                               GCancellable   *cancellable,
296                               GError        **error)
297 {
298   GFilterOutputStream *filter_stream = G_FILTER_OUTPUT_STREAM (stream);
299   GFilterOutputStreamPrivate *priv = g_filter_output_stream_get_instance_private (filter_stream);
300   gboolean res = TRUE;
301
302   if (priv->close_base)
303     {
304       res = g_output_stream_close (filter_stream->base_stream,
305                                    cancellable,
306                                    error);
307     }
308
309   return res;
310 }