Coverage Report

Created: 2025-06-13 06:55

/src/glib/gio/gseekable.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 "gseekable.h"
25
#include "glibintl.h"
26
27
28
/**
29
 * SECTION:gseekable
30
 * @short_description: Stream seeking interface
31
 * @include: gio/gio.h
32
 * @see_also: #GInputStream, #GOutputStream
33
 *
34
 * #GSeekable is implemented by streams (implementations of
35
 * #GInputStream or #GOutputStream) that support seeking.
36
 *
37
 * Seekable streams largely fall into two categories: resizable and
38
 * fixed-size.
39
 *
40
 * #GSeekable on fixed-sized streams is approximately the same as POSIX
41
 * lseek() on a block device (for example: attempting to seek past the
42
 * end of the device is an error).  Fixed streams typically cannot be
43
 * truncated.
44
 *
45
 * #GSeekable on resizable streams is approximately the same as POSIX
46
 * lseek() on a normal file.  Seeking past the end and writing data will
47
 * usually cause the stream to resize by introducing zero bytes.
48
 **/
49
50
typedef GSeekableIface GSeekableInterface;
51
G_DEFINE_INTERFACE (GSeekable, g_seekable, G_TYPE_OBJECT)
52
53
static void
54
g_seekable_default_init (GSeekableInterface *iface)
55
1
{
56
1
}
57
58
/**
59
 * g_seekable_tell:
60
 * @seekable: a #GSeekable.
61
 * 
62
 * Tells the current position within the stream.
63
 * 
64
 * Returns: the (positive or zero) offset from the beginning of the
65
 * buffer, zero if the target is not seekable.
66
 **/
67
goffset
68
g_seekable_tell (GSeekable *seekable)
69
0
{
70
0
  GSeekableIface *iface;
71
72
0
  g_return_val_if_fail (G_IS_SEEKABLE (seekable), 0);
73
74
0
  iface = G_SEEKABLE_GET_IFACE (seekable);
75
76
0
  return (* iface->tell) (seekable);
77
0
}
78
79
/**
80
 * g_seekable_can_seek:
81
 * @seekable: a #GSeekable.
82
 * 
83
 * Tests if the stream supports the #GSeekableIface.
84
 * 
85
 * Returns: %TRUE if @seekable can be seeked. %FALSE otherwise.
86
 **/
87
gboolean
88
g_seekable_can_seek (GSeekable *seekable)
89
0
{
90
0
  GSeekableIface *iface;
91
  
92
0
  g_return_val_if_fail (G_IS_SEEKABLE (seekable), FALSE);
93
94
0
  iface = G_SEEKABLE_GET_IFACE (seekable);
95
96
0
  return (* iface->can_seek) (seekable);
97
0
}
98
99
/**
100
 * g_seekable_seek:
101
 * @seekable: a #GSeekable.
102
 * @offset: a #goffset.
103
 * @type: a #GSeekType.
104
 * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
105
 * @error: a #GError location to store the error occurring, or %NULL to
106
 * ignore.
107
 *
108
 * Seeks in the stream by the given @offset, modified by @type.
109
 *
110
 * Attempting to seek past the end of the stream will have different
111
 * results depending on if the stream is fixed-sized or resizable.  If
112
 * the stream is resizable then seeking past the end and then writing
113
 * will result in zeros filling the empty space.  Seeking past the end
114
 * of a resizable stream and reading will result in EOF.  Seeking past
115
 * the end of a fixed-sized stream will fail.
116
 *
117
 * Any operation that would result in a negative offset will fail.
118
 *
119
 * If @cancellable is not %NULL, then the operation can be cancelled by
120
 * triggering the cancellable object from another thread. If the operation
121
 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
122
 * 
123
 * Returns: %TRUE if successful. If an error
124
 *     has occurred, this function will return %FALSE and set @error
125
 *     appropriately if present.
126
 **/
127
gboolean
128
g_seekable_seek (GSeekable     *seekable,
129
     goffset        offset,
130
     GSeekType      type,
131
     GCancellable  *cancellable,
132
     GError       **error)
133
0
{
134
0
  GSeekableIface *iface;
135
  
136
0
  g_return_val_if_fail (G_IS_SEEKABLE (seekable), FALSE);
137
138
0
  iface = G_SEEKABLE_GET_IFACE (seekable);
139
140
0
  return (* iface->seek) (seekable, offset, type, cancellable, error);
141
0
}
142
143
/**
144
 * g_seekable_can_truncate:
145
 * @seekable: a #GSeekable.
146
 * 
147
 * Tests if the length of the stream can be adjusted with
148
 * g_seekable_truncate().
149
 * 
150
 * Returns: %TRUE if the stream can be truncated, %FALSE otherwise.
151
 **/
152
gboolean
153
g_seekable_can_truncate (GSeekable *seekable)
154
0
{
155
0
  GSeekableIface *iface;
156
  
157
0
  g_return_val_if_fail (G_IS_SEEKABLE (seekable), FALSE);
158
159
0
  iface = G_SEEKABLE_GET_IFACE (seekable);
160
161
0
  return (* iface->can_truncate) (seekable);
162
0
}
163
164
/**
165
 * g_seekable_truncate: (virtual truncate_fn)
166
 * @seekable: a #GSeekable.
167
 * @offset: new length for @seekable, in bytes.
168
 * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. 
169
 * @error: a #GError location to store the error occurring, or %NULL to 
170
 * ignore.
171
 * 
172
 * Sets the length of the stream to @offset. If the stream was previously
173
 * larger than @offset, the extra data is discarded. If the stream was
174
 * previously shorter than @offset, it is extended with NUL ('\0') bytes.
175
 * 
176
 * If @cancellable is not %NULL, then the operation can be cancelled by
177
 * triggering the cancellable object from another thread. If the operation
178
 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. If an
179
 * operation was partially finished when the operation was cancelled the
180
 * partial result will be returned, without an error.
181
 *
182
 * Returns: %TRUE if successful. If an error
183
 *     has occurred, this function will return %FALSE and set @error
184
 *     appropriately if present. 
185
 **/
186
gboolean
187
g_seekable_truncate (GSeekable     *seekable,
188
         goffset        offset,
189
         GCancellable  *cancellable,
190
         GError       **error)
191
0
{
192
0
  GSeekableIface *iface;
193
  
194
0
  g_return_val_if_fail (G_IS_SEEKABLE (seekable), FALSE);
195
196
0
  iface = G_SEEKABLE_GET_IFACE (seekable);
197
198
0
  return (* iface->truncate_fn) (seekable, offset, cancellable, error);
199
0
}