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