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