/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 | } |