/src/pango/subprojects/glib/gio/gdataoutputstream.c
Line | Count | Source (jump to first uncovered line) |
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: Alexander Larsson <alexl@redhat.com> |
21 | | */ |
22 | | |
23 | | #include "config.h" |
24 | | #include <string.h> |
25 | | #include "gdataoutputstream.h" |
26 | | #include "gseekable.h" |
27 | | #include "gioenumtypes.h" |
28 | | #include "gioerror.h" |
29 | | #include "glibintl.h" |
30 | | |
31 | | |
32 | | /** |
33 | | * GDataOutputStream: |
34 | | * |
35 | | * Data output stream implements [class@Gio.OutputStream] and includes functions |
36 | | * for writing data directly to an output stream. |
37 | | */ |
38 | | |
39 | | |
40 | | struct _GDataOutputStreamPrivate { |
41 | | GDataStreamByteOrder byte_order; |
42 | | }; |
43 | | |
44 | | enum { |
45 | | PROP_0, |
46 | | PROP_BYTE_ORDER |
47 | | }; |
48 | | |
49 | | static void g_data_output_stream_set_property (GObject *object, |
50 | | guint prop_id, |
51 | | const GValue *value, |
52 | | GParamSpec *pspec); |
53 | | static void g_data_output_stream_get_property (GObject *object, |
54 | | guint prop_id, |
55 | | GValue *value, |
56 | | GParamSpec *pspec); |
57 | | |
58 | | static void g_data_output_stream_seekable_iface_init (GSeekableIface *iface); |
59 | | static goffset g_data_output_stream_tell (GSeekable *seekable); |
60 | | static gboolean g_data_output_stream_can_seek (GSeekable *seekable); |
61 | | static gboolean g_data_output_stream_seek (GSeekable *seekable, |
62 | | goffset offset, |
63 | | GSeekType type, |
64 | | GCancellable *cancellable, |
65 | | GError **error); |
66 | | static gboolean g_data_output_stream_can_truncate (GSeekable *seekable); |
67 | | static gboolean g_data_output_stream_truncate (GSeekable *seekable, |
68 | | goffset offset, |
69 | | GCancellable *cancellable, |
70 | | GError **error); |
71 | | |
72 | | G_DEFINE_TYPE_WITH_CODE (GDataOutputStream, |
73 | | g_data_output_stream, |
74 | | G_TYPE_FILTER_OUTPUT_STREAM, |
75 | | G_ADD_PRIVATE (GDataOutputStream) |
76 | | G_IMPLEMENT_INTERFACE (G_TYPE_SEEKABLE, |
77 | | g_data_output_stream_seekable_iface_init)) |
78 | | |
79 | | |
80 | | static void |
81 | | g_data_output_stream_class_init (GDataOutputStreamClass *klass) |
82 | 0 | { |
83 | 0 | GObjectClass *object_class; |
84 | |
|
85 | 0 | object_class = G_OBJECT_CLASS (klass); |
86 | 0 | object_class->get_property = g_data_output_stream_get_property; |
87 | 0 | object_class->set_property = g_data_output_stream_set_property; |
88 | | |
89 | | /** |
90 | | * GDataOutputStream:byte-order: |
91 | | * |
92 | | * Determines the byte ordering that is used when writing |
93 | | * multi-byte entities (such as integers) to the stream. |
94 | | */ |
95 | 0 | g_object_class_install_property (object_class, |
96 | 0 | PROP_BYTE_ORDER, |
97 | 0 | g_param_spec_enum ("byte-order", NULL, NULL, |
98 | 0 | G_TYPE_DATA_STREAM_BYTE_ORDER, |
99 | 0 | G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN, |
100 | 0 | G_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_BLURB)); |
101 | |
|
102 | 0 | } |
103 | | |
104 | | static void |
105 | | g_data_output_stream_set_property (GObject *object, |
106 | | guint prop_id, |
107 | | const GValue *value, |
108 | | GParamSpec *pspec) |
109 | 0 | { |
110 | 0 | GDataOutputStream *dstream; |
111 | |
|
112 | 0 | dstream = G_DATA_OUTPUT_STREAM (object); |
113 | |
|
114 | 0 | switch (prop_id) |
115 | 0 | { |
116 | 0 | case PROP_BYTE_ORDER: |
117 | 0 | g_data_output_stream_set_byte_order (dstream, g_value_get_enum (value)); |
118 | 0 | break; |
119 | | |
120 | 0 | default: |
121 | 0 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
122 | 0 | break; |
123 | 0 | } |
124 | 0 | } |
125 | | |
126 | | static void |
127 | | g_data_output_stream_get_property (GObject *object, |
128 | | guint prop_id, |
129 | | GValue *value, |
130 | | GParamSpec *pspec) |
131 | 0 | { |
132 | 0 | GDataOutputStreamPrivate *priv; |
133 | 0 | GDataOutputStream *dstream; |
134 | |
|
135 | 0 | dstream = G_DATA_OUTPUT_STREAM (object); |
136 | 0 | priv = dstream->priv; |
137 | |
|
138 | 0 | switch (prop_id) |
139 | 0 | { |
140 | 0 | case PROP_BYTE_ORDER: |
141 | 0 | g_value_set_enum (value, priv->byte_order); |
142 | 0 | break; |
143 | | |
144 | 0 | default: |
145 | 0 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
146 | 0 | break; |
147 | 0 | } |
148 | 0 | } |
149 | | |
150 | | static void |
151 | | g_data_output_stream_init (GDataOutputStream *stream) |
152 | 0 | { |
153 | 0 | stream->priv = g_data_output_stream_get_instance_private (stream); |
154 | 0 | stream->priv->byte_order = G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN; |
155 | 0 | } |
156 | | |
157 | | static void |
158 | | g_data_output_stream_seekable_iface_init (GSeekableIface *iface) |
159 | 0 | { |
160 | 0 | iface->tell = g_data_output_stream_tell; |
161 | 0 | iface->can_seek = g_data_output_stream_can_seek; |
162 | 0 | iface->seek = g_data_output_stream_seek; |
163 | 0 | iface->can_truncate = g_data_output_stream_can_truncate; |
164 | 0 | iface->truncate_fn = g_data_output_stream_truncate; |
165 | 0 | } |
166 | | |
167 | | /** |
168 | | * g_data_output_stream_new: |
169 | | * @base_stream: a #GOutputStream. |
170 | | * |
171 | | * Creates a new data output stream for @base_stream. |
172 | | * |
173 | | * Returns: #GDataOutputStream. |
174 | | **/ |
175 | | GDataOutputStream * |
176 | | g_data_output_stream_new (GOutputStream *base_stream) |
177 | 0 | { |
178 | 0 | GDataOutputStream *stream; |
179 | |
|
180 | 0 | g_return_val_if_fail (G_IS_OUTPUT_STREAM (base_stream), NULL); |
181 | | |
182 | 0 | stream = g_object_new (G_TYPE_DATA_OUTPUT_STREAM, |
183 | 0 | "base-stream", base_stream, |
184 | 0 | NULL); |
185 | |
|
186 | 0 | return stream; |
187 | 0 | } |
188 | | |
189 | | /** |
190 | | * g_data_output_stream_set_byte_order: |
191 | | * @stream: a #GDataOutputStream. |
192 | | * @order: a %GDataStreamByteOrder. |
193 | | * |
194 | | * Sets the byte order of the data output stream to @order. |
195 | | **/ |
196 | | void |
197 | | g_data_output_stream_set_byte_order (GDataOutputStream *stream, |
198 | | GDataStreamByteOrder order) |
199 | 0 | { |
200 | 0 | GDataOutputStreamPrivate *priv; |
201 | 0 | g_return_if_fail (G_IS_DATA_OUTPUT_STREAM (stream)); |
202 | 0 | priv = stream->priv; |
203 | 0 | if (priv->byte_order != order) |
204 | 0 | { |
205 | 0 | priv->byte_order = order; |
206 | 0 | g_object_notify (G_OBJECT (stream), "byte-order"); |
207 | 0 | } |
208 | 0 | } |
209 | | |
210 | | /** |
211 | | * g_data_output_stream_get_byte_order: |
212 | | * @stream: a #GDataOutputStream. |
213 | | * |
214 | | * Gets the byte order for the stream. |
215 | | * |
216 | | * Returns: the #GDataStreamByteOrder for the @stream. |
217 | | **/ |
218 | | GDataStreamByteOrder |
219 | | g_data_output_stream_get_byte_order (GDataOutputStream *stream) |
220 | 0 | { |
221 | 0 | g_return_val_if_fail (G_IS_DATA_OUTPUT_STREAM (stream), G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN); |
222 | | |
223 | 0 | return stream->priv->byte_order; |
224 | 0 | } |
225 | | |
226 | | /** |
227 | | * g_data_output_stream_put_byte: |
228 | | * @stream: a #GDataOutputStream. |
229 | | * @data: a #guchar. |
230 | | * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. |
231 | | * @error: a #GError, %NULL to ignore. |
232 | | * |
233 | | * Puts a byte into the output stream. |
234 | | * |
235 | | * Returns: %TRUE if @data was successfully added to the @stream. |
236 | | **/ |
237 | | gboolean |
238 | | g_data_output_stream_put_byte (GDataOutputStream *stream, |
239 | | guchar data, |
240 | | GCancellable *cancellable, |
241 | | GError **error) |
242 | 0 | { |
243 | 0 | gsize bytes_written; |
244 | | |
245 | 0 | g_return_val_if_fail (G_IS_DATA_OUTPUT_STREAM (stream), FALSE); |
246 | | |
247 | 0 | return g_output_stream_write_all (G_OUTPUT_STREAM (stream), |
248 | 0 | &data, 1, |
249 | 0 | &bytes_written, |
250 | 0 | cancellable, error); |
251 | 0 | } |
252 | | |
253 | | /** |
254 | | * g_data_output_stream_put_int16: |
255 | | * @stream: a #GDataOutputStream. |
256 | | * @data: a #gint16. |
257 | | * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. |
258 | | * @error: a #GError, %NULL to ignore. |
259 | | * |
260 | | * Puts a signed 16-bit integer into the output stream. |
261 | | * |
262 | | * Returns: %TRUE if @data was successfully added to the @stream. |
263 | | **/ |
264 | | gboolean |
265 | | g_data_output_stream_put_int16 (GDataOutputStream *stream, |
266 | | gint16 data, |
267 | | GCancellable *cancellable, |
268 | | GError **error) |
269 | 0 | { |
270 | 0 | gsize bytes_written; |
271 | | |
272 | 0 | g_return_val_if_fail (G_IS_DATA_OUTPUT_STREAM (stream), FALSE); |
273 | | |
274 | 0 | switch (stream->priv->byte_order) |
275 | 0 | { |
276 | 0 | case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN: |
277 | 0 | data = GINT16_TO_BE (data); |
278 | 0 | break; |
279 | 0 | case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN: |
280 | 0 | data = GINT16_TO_LE (data); |
281 | 0 | break; |
282 | 0 | case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN: |
283 | 0 | default: |
284 | 0 | break; |
285 | 0 | } |
286 | | |
287 | 0 | return g_output_stream_write_all (G_OUTPUT_STREAM (stream), |
288 | 0 | &data, 2, |
289 | 0 | &bytes_written, |
290 | 0 | cancellable, error); |
291 | 0 | } |
292 | | |
293 | | /** |
294 | | * g_data_output_stream_put_uint16: |
295 | | * @stream: a #GDataOutputStream. |
296 | | * @data: a #guint16. |
297 | | * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. |
298 | | * @error: a #GError, %NULL to ignore. |
299 | | * |
300 | | * Puts an unsigned 16-bit integer into the output stream. |
301 | | * |
302 | | * Returns: %TRUE if @data was successfully added to the @stream. |
303 | | **/ |
304 | | gboolean |
305 | | g_data_output_stream_put_uint16 (GDataOutputStream *stream, |
306 | | guint16 data, |
307 | | GCancellable *cancellable, |
308 | | GError **error) |
309 | 0 | { |
310 | 0 | gsize bytes_written; |
311 | | |
312 | 0 | g_return_val_if_fail (G_IS_DATA_OUTPUT_STREAM (stream), FALSE); |
313 | | |
314 | 0 | switch (stream->priv->byte_order) |
315 | 0 | { |
316 | 0 | case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN: |
317 | 0 | data = GUINT16_TO_BE (data); |
318 | 0 | break; |
319 | 0 | case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN: |
320 | 0 | data = GUINT16_TO_LE (data); |
321 | 0 | break; |
322 | 0 | case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN: |
323 | 0 | default: |
324 | 0 | break; |
325 | 0 | } |
326 | | |
327 | 0 | return g_output_stream_write_all (G_OUTPUT_STREAM (stream), |
328 | 0 | &data, 2, |
329 | 0 | &bytes_written, |
330 | 0 | cancellable, error); |
331 | 0 | } |
332 | | |
333 | | /** |
334 | | * g_data_output_stream_put_int32: |
335 | | * @stream: a #GDataOutputStream. |
336 | | * @data: a #gint32. |
337 | | * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. |
338 | | * @error: a #GError, %NULL to ignore. |
339 | | * |
340 | | * Puts a signed 32-bit integer into the output stream. |
341 | | * |
342 | | * Returns: %TRUE if @data was successfully added to the @stream. |
343 | | **/ |
344 | | gboolean |
345 | | g_data_output_stream_put_int32 (GDataOutputStream *stream, |
346 | | gint32 data, |
347 | | GCancellable *cancellable, |
348 | | GError **error) |
349 | 0 | { |
350 | 0 | gsize bytes_written; |
351 | | |
352 | 0 | g_return_val_if_fail (G_IS_DATA_OUTPUT_STREAM (stream), FALSE); |
353 | | |
354 | 0 | switch (stream->priv->byte_order) |
355 | 0 | { |
356 | 0 | case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN: |
357 | 0 | data = GINT32_TO_BE (data); |
358 | 0 | break; |
359 | 0 | case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN: |
360 | 0 | data = GINT32_TO_LE (data); |
361 | 0 | break; |
362 | 0 | case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN: |
363 | 0 | default: |
364 | 0 | break; |
365 | 0 | } |
366 | | |
367 | 0 | return g_output_stream_write_all (G_OUTPUT_STREAM (stream), |
368 | 0 | &data, 4, |
369 | 0 | &bytes_written, |
370 | 0 | cancellable, error); |
371 | 0 | } |
372 | | |
373 | | /** |
374 | | * g_data_output_stream_put_uint32: |
375 | | * @stream: a #GDataOutputStream. |
376 | | * @data: a #guint32. |
377 | | * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. |
378 | | * @error: a #GError, %NULL to ignore. |
379 | | * |
380 | | * Puts an unsigned 32-bit integer into the stream. |
381 | | * |
382 | | * Returns: %TRUE if @data was successfully added to the @stream. |
383 | | **/ |
384 | | gboolean |
385 | | g_data_output_stream_put_uint32 (GDataOutputStream *stream, |
386 | | guint32 data, |
387 | | GCancellable *cancellable, |
388 | | GError **error) |
389 | 0 | { |
390 | 0 | gsize bytes_written; |
391 | | |
392 | 0 | g_return_val_if_fail (G_IS_DATA_OUTPUT_STREAM (stream), FALSE); |
393 | | |
394 | 0 | switch (stream->priv->byte_order) |
395 | 0 | { |
396 | 0 | case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN: |
397 | 0 | data = GUINT32_TO_BE (data); |
398 | 0 | break; |
399 | 0 | case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN: |
400 | 0 | data = GUINT32_TO_LE (data); |
401 | 0 | break; |
402 | 0 | case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN: |
403 | 0 | default: |
404 | 0 | break; |
405 | 0 | } |
406 | | |
407 | 0 | return g_output_stream_write_all (G_OUTPUT_STREAM (stream), |
408 | 0 | &data, 4, |
409 | 0 | &bytes_written, |
410 | 0 | cancellable, error); |
411 | 0 | } |
412 | | |
413 | | /** |
414 | | * g_data_output_stream_put_int64: |
415 | | * @stream: a #GDataOutputStream. |
416 | | * @data: a #gint64. |
417 | | * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. |
418 | | * @error: a #GError, %NULL to ignore. |
419 | | * |
420 | | * Puts a signed 64-bit integer into the stream. |
421 | | * |
422 | | * Returns: %TRUE if @data was successfully added to the @stream. |
423 | | **/ |
424 | | gboolean |
425 | | g_data_output_stream_put_int64 (GDataOutputStream *stream, |
426 | | gint64 data, |
427 | | GCancellable *cancellable, |
428 | | GError **error) |
429 | 0 | { |
430 | 0 | gsize bytes_written; |
431 | | |
432 | 0 | g_return_val_if_fail (G_IS_DATA_OUTPUT_STREAM (stream), FALSE); |
433 | | |
434 | 0 | switch (stream->priv->byte_order) |
435 | 0 | { |
436 | 0 | case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN: |
437 | 0 | data = GINT64_TO_BE (data); |
438 | 0 | break; |
439 | 0 | case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN: |
440 | 0 | data = GINT64_TO_LE (data); |
441 | 0 | break; |
442 | 0 | case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN: |
443 | 0 | default: |
444 | 0 | break; |
445 | 0 | } |
446 | | |
447 | 0 | return g_output_stream_write_all (G_OUTPUT_STREAM (stream), |
448 | 0 | &data, 8, |
449 | 0 | &bytes_written, |
450 | 0 | cancellable, error); |
451 | 0 | } |
452 | | |
453 | | /** |
454 | | * g_data_output_stream_put_uint64: |
455 | | * @stream: a #GDataOutputStream. |
456 | | * @data: a #guint64. |
457 | | * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. |
458 | | * @error: a #GError, %NULL to ignore. |
459 | | * |
460 | | * Puts an unsigned 64-bit integer into the stream. |
461 | | * |
462 | | * Returns: %TRUE if @data was successfully added to the @stream. |
463 | | **/ |
464 | | gboolean |
465 | | g_data_output_stream_put_uint64 (GDataOutputStream *stream, |
466 | | guint64 data, |
467 | | GCancellable *cancellable, |
468 | | GError **error) |
469 | 0 | { |
470 | 0 | gsize bytes_written; |
471 | | |
472 | 0 | g_return_val_if_fail (G_IS_DATA_OUTPUT_STREAM (stream), FALSE); |
473 | | |
474 | 0 | switch (stream->priv->byte_order) |
475 | 0 | { |
476 | 0 | case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN: |
477 | 0 | data = GUINT64_TO_BE (data); |
478 | 0 | break; |
479 | 0 | case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN: |
480 | 0 | data = GUINT64_TO_LE (data); |
481 | 0 | break; |
482 | 0 | case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN: |
483 | 0 | default: |
484 | 0 | break; |
485 | 0 | } |
486 | | |
487 | 0 | return g_output_stream_write_all (G_OUTPUT_STREAM (stream), |
488 | 0 | &data, 8, |
489 | 0 | &bytes_written, |
490 | 0 | cancellable, error); |
491 | 0 | } |
492 | | |
493 | | /** |
494 | | * g_data_output_stream_put_string: |
495 | | * @stream: a #GDataOutputStream. |
496 | | * @str: a string. |
497 | | * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. |
498 | | * @error: a #GError, %NULL to ignore. |
499 | | * |
500 | | * Puts a string into the output stream. |
501 | | * |
502 | | * Returns: %TRUE if @string was successfully added to the @stream. |
503 | | **/ |
504 | | gboolean |
505 | | g_data_output_stream_put_string (GDataOutputStream *stream, |
506 | | const char *str, |
507 | | GCancellable *cancellable, |
508 | | GError **error) |
509 | 0 | { |
510 | 0 | gsize bytes_written; |
511 | | |
512 | 0 | g_return_val_if_fail (G_IS_DATA_OUTPUT_STREAM (stream), FALSE); |
513 | 0 | g_return_val_if_fail (str != NULL, FALSE); |
514 | | |
515 | 0 | return g_output_stream_write_all (G_OUTPUT_STREAM (stream), |
516 | 0 | str, strlen (str), |
517 | 0 | &bytes_written, |
518 | 0 | cancellable, error); |
519 | 0 | } |
520 | | |
521 | | static goffset |
522 | | g_data_output_stream_tell (GSeekable *seekable) |
523 | 0 | { |
524 | 0 | GOutputStream *base_stream; |
525 | 0 | GSeekable *base_stream_seekable; |
526 | |
|
527 | 0 | base_stream = G_FILTER_OUTPUT_STREAM (seekable)->base_stream; |
528 | 0 | if (!G_IS_SEEKABLE (base_stream)) |
529 | 0 | return 0; |
530 | 0 | base_stream_seekable = G_SEEKABLE (base_stream); |
531 | 0 | return g_seekable_tell (base_stream_seekable); |
532 | 0 | } |
533 | | |
534 | | static gboolean |
535 | | g_data_output_stream_can_seek (GSeekable *seekable) |
536 | 0 | { |
537 | 0 | GOutputStream *base_stream; |
538 | | |
539 | 0 | base_stream = G_FILTER_OUTPUT_STREAM (seekable)->base_stream; |
540 | 0 | return G_IS_SEEKABLE (base_stream) && g_seekable_can_seek (G_SEEKABLE (base_stream)); |
541 | 0 | } |
542 | | |
543 | | static gboolean |
544 | | g_data_output_stream_seek (GSeekable *seekable, |
545 | | goffset offset, |
546 | | GSeekType type, |
547 | | GCancellable *cancellable, |
548 | | GError **error) |
549 | 0 | { |
550 | 0 | GOutputStream *base_stream; |
551 | 0 | GSeekable *base_stream_seekable; |
552 | |
|
553 | 0 | base_stream = G_FILTER_OUTPUT_STREAM (seekable)->base_stream; |
554 | 0 | if (!G_IS_SEEKABLE (base_stream)) |
555 | 0 | { |
556 | 0 | g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, |
557 | 0 | _("Seek not supported on base stream")); |
558 | 0 | return FALSE; |
559 | 0 | } |
560 | | |
561 | 0 | base_stream_seekable = G_SEEKABLE (base_stream); |
562 | 0 | return g_seekable_seek (base_stream_seekable, offset, type, cancellable, error); |
563 | 0 | } |
564 | | |
565 | | static gboolean |
566 | | g_data_output_stream_can_truncate (GSeekable *seekable) |
567 | 0 | { |
568 | 0 | GOutputStream *base_stream; |
569 | | |
570 | 0 | base_stream = G_FILTER_OUTPUT_STREAM (seekable)->base_stream; |
571 | 0 | return G_IS_SEEKABLE (base_stream) && g_seekable_can_truncate (G_SEEKABLE (base_stream)); |
572 | 0 | } |
573 | | |
574 | | static gboolean |
575 | | g_data_output_stream_truncate (GSeekable *seekable, |
576 | | goffset offset, |
577 | | GCancellable *cancellable, |
578 | | GError **error) |
579 | 0 | { |
580 | 0 | GOutputStream *base_stream; |
581 | 0 | GSeekable *base_stream_seekable; |
582 | |
|
583 | 0 | base_stream = G_FILTER_OUTPUT_STREAM (seekable)->base_stream; |
584 | 0 | if (!G_IS_SEEKABLE (base_stream)) |
585 | 0 | { |
586 | 0 | g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, |
587 | 0 | _("Truncate not supported on base stream")); |
588 | 0 | return FALSE; |
589 | 0 | } |
590 | | |
591 | 0 | base_stream_seekable = G_SEEKABLE (base_stream); |
592 | 0 | return g_seekable_truncate (base_stream_seekable, offset, cancellable, error); |
593 | 0 | } |