| 
									
										
										
										
											2007-11-26 16:13:05 +00:00
										 |  |  | /* GIO - GLib Input, Output and Streaming Library
 | 
					
						
							|  |  |  |  *  | 
					
						
							|  |  |  |  * Copyright (C) 2006-2007 Red Hat, Inc. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2022-05-18 09:12:45 +01:00
										 |  |  |  * SPDX-License-Identifier: LGPL-2.1-or-later | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2007-11-26 16:13:05 +00:00
										 |  |  |  * This library is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU Lesser General Public | 
					
						
							|  |  |  |  * License as published by the Free Software Foundation; either | 
					
						
							| 
									
										
										
										
											2017-05-27 18:21:30 +02:00
										 |  |  |  * version 2.1 of the License, or (at your option) any later version. | 
					
						
							| 
									
										
										
										
											2007-11-26 16:13:05 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * This library is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
					
						
							|  |  |  |  * Lesser General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU Lesser General | 
					
						
							| 
									
										
										
										
											2014-01-23 12:58:29 +01:00
										 |  |  |  * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
 | 
					
						
							| 
									
										
										
										
											2007-11-26 16:13:05 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Author: Alexander Larsson <alexl@redhat.com> | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-22 15:10:51 +00:00
										 |  |  | #include "config.h"
 | 
					
						
							| 
									
										
										
										
											2007-11-26 16:13:05 +00:00
										 |  |  | #include "gseekable.h"
 | 
					
						
							|  |  |  | #include "glibintl.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-28 12:39:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-27 14:00:13 +00:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2023-10-24 10:56:19 +01:00
										 |  |  |  * GSeekable: | 
					
						
							| 
									
										
										
										
											2013-10-22 15:01:16 -04:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2023-10-24 10:56:19 +01:00
										 |  |  |  * `GSeekable` is implemented by streams (implementations of | 
					
						
							|  |  |  |  * [class@Gio.InputStream] or [class@Gio.OutputStream]) that support seeking. | 
					
						
							| 
									
										
										
										
											2013-10-22 15:01:16 -04:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Seekable streams largely fall into two categories: resizable and | 
					
						
							|  |  |  |  * fixed-size. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2023-10-24 10:56:19 +01:00
										 |  |  |  * `GSeekable` on fixed-sized streams is approximately the same as POSIX | 
					
						
							|  |  |  |  * [`lseek()`](man:lseek(2)) on a block device (for example: attempting to seek | 
					
						
							|  |  |  |  * past the end of the device is an error).  Fixed streams typically cannot be | 
					
						
							| 
									
										
										
										
											2013-10-22 15:01:16 -04:00
										 |  |  |  * truncated. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2023-10-24 10:56:19 +01:00
										 |  |  |  * `GSeekable` on resizable streams is approximately the same as POSIX | 
					
						
							|  |  |  |  * [`lseek()`](man:lseek(2)) on a normal file.  Seeking past the end and writing | 
					
						
							|  |  |  |  * data will usually cause the stream to resize by introducing zero bytes. | 
					
						
							| 
									
										
										
										
											2007-11-27 14:00:13 +00:00
										 |  |  |  **/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-01 10:42:58 +01:00
										 |  |  | typedef GSeekableIface GSeekableInterface; | 
					
						
							|  |  |  | G_DEFINE_INTERFACE (GSeekable, g_seekable, G_TYPE_OBJECT) | 
					
						
							| 
									
										
										
										
											2007-11-26 16:13:05 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							| 
									
										
										
										
											2009-12-01 10:42:58 +01:00
										 |  |  | g_seekable_default_init (GSeekableInterface *iface) | 
					
						
							| 
									
										
										
										
											2007-11-26 16:13:05 +00:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * g_seekable_tell: | 
					
						
							| 
									
										
										
										
											2007-11-27 14:00:13 +00:00
										 |  |  |  * @seekable: a #GSeekable. | 
					
						
							| 
									
										
										
										
											2007-11-26 16:13:05 +00:00
										 |  |  |  *  | 
					
						
							| 
									
										
										
										
											2007-11-27 14:00:13 +00:00
										 |  |  |  * Tells the current position within the stream. | 
					
						
							|  |  |  |  *  | 
					
						
							| 
									
										
										
										
											2021-04-22 14:33:18 +02:00
										 |  |  |  * Returns: the (positive or zero) offset from the beginning of the | 
					
						
							|  |  |  |  * buffer, zero if the target is not seekable. | 
					
						
							| 
									
										
										
										
											2007-11-26 16:13:05 +00:00
										 |  |  |  **/ | 
					
						
							|  |  |  | goffset | 
					
						
							|  |  |  | g_seekable_tell (GSeekable *seekable) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GSeekableIface *iface; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   g_return_val_if_fail (G_IS_SEEKABLE (seekable), 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   iface = G_SEEKABLE_GET_IFACE (seekable); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return (* iface->tell) (seekable); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * g_seekable_can_seek: | 
					
						
							| 
									
										
										
										
											2007-11-27 14:00:13 +00:00
										 |  |  |  * @seekable: a #GSeekable. | 
					
						
							|  |  |  |  *  | 
					
						
							|  |  |  |  * Tests if the stream supports the #GSeekableIface. | 
					
						
							| 
									
										
										
										
											2007-11-26 16:13:05 +00:00
										 |  |  |  *  | 
					
						
							|  |  |  |  * Returns: %TRUE if @seekable can be seeked. %FALSE otherwise. | 
					
						
							|  |  |  |  **/ | 
					
						
							|  |  |  | gboolean | 
					
						
							|  |  |  | g_seekable_can_seek (GSeekable *seekable) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GSeekableIface *iface; | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   g_return_val_if_fail (G_IS_SEEKABLE (seekable), FALSE); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   iface = G_SEEKABLE_GET_IFACE (seekable); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return (* iface->can_seek) (seekable); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * g_seekable_seek: | 
					
						
							| 
									
										
										
										
											2007-11-27 14:00:13 +00:00
										 |  |  |  * @seekable: a #GSeekable. | 
					
						
							|  |  |  |  * @offset: a #goffset. | 
					
						
							|  |  |  |  * @type: a #GSeekType. | 
					
						
							| 
									
										
										
										
											2016-10-28 18:29:02 -07:00
										 |  |  |  * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. | 
					
						
							| 
									
										
										
										
											2013-10-22 15:01:16 -04:00
										 |  |  |  * @error: a #GError location to store the error occurring, or %NULL to | 
					
						
							| 
									
										
										
										
											2007-11-26 16:13:05 +00:00
										 |  |  |  * ignore. | 
					
						
							| 
									
										
										
										
											2013-10-22 15:01:16 -04:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2007-11-27 14:00:13 +00:00
										 |  |  |  * Seeks in the stream by the given @offset, modified by @type. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-10-22 15:01:16 -04:00
										 |  |  |  * Attempting to seek past the end of the stream will have different | 
					
						
							|  |  |  |  * results depending on if the stream is fixed-sized or resizable.  If | 
					
						
							|  |  |  |  * the stream is resizable then seeking past the end and then writing | 
					
						
							|  |  |  |  * will result in zeros filling the empty space.  Seeking past the end | 
					
						
							|  |  |  |  * of a resizable stream and reading will result in EOF.  Seeking past | 
					
						
							|  |  |  |  * the end of a fixed-sized stream will fail. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Any operation that would result in a negative offset will fail. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2007-11-27 14:00:13 +00:00
										 |  |  |  * If @cancellable is not %NULL, then the operation can be cancelled by | 
					
						
							|  |  |  |  * triggering the cancellable object from another thread. If the operation | 
					
						
							|  |  |  |  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.  | 
					
						
							|  |  |  |  *  | 
					
						
							|  |  |  |  * Returns: %TRUE if successful. If an error | 
					
						
							| 
									
										
										
										
											2008-01-16 20:00:23 +00:00
										 |  |  |  *     has occurred, this function will return %FALSE and set @error | 
					
						
							| 
									
										
										
										
											2007-11-30 05:11:25 +00:00
										 |  |  |  *     appropriately if present. | 
					
						
							| 
									
										
										
										
											2007-11-26 16:13:05 +00:00
										 |  |  |  **/ | 
					
						
							|  |  |  | gboolean | 
					
						
							|  |  |  | g_seekable_seek (GSeekable     *seekable, | 
					
						
							|  |  |  | 		 goffset        offset, | 
					
						
							|  |  |  | 		 GSeekType      type, | 
					
						
							|  |  |  | 		 GCancellable  *cancellable, | 
					
						
							|  |  |  | 		 GError       **error) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GSeekableIface *iface; | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   g_return_val_if_fail (G_IS_SEEKABLE (seekable), FALSE); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   iface = G_SEEKABLE_GET_IFACE (seekable); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return (* iface->seek) (seekable, offset, type, cancellable, error); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * g_seekable_can_truncate: | 
					
						
							| 
									
										
										
										
											2007-11-27 14:00:13 +00:00
										 |  |  |  * @seekable: a #GSeekable. | 
					
						
							|  |  |  |  *  | 
					
						
							| 
									
										
										
										
											2017-11-01 14:41:00 +00:00
										 |  |  |  * Tests if the length of the stream can be adjusted with | 
					
						
							|  |  |  |  * g_seekable_truncate(). | 
					
						
							| 
									
										
										
										
											2007-11-26 16:13:05 +00:00
										 |  |  |  *  | 
					
						
							| 
									
										
										
										
											2007-11-27 14:00:13 +00:00
										 |  |  |  * Returns: %TRUE if the stream can be truncated, %FALSE otherwise. | 
					
						
							| 
									
										
										
										
											2007-11-26 16:13:05 +00:00
										 |  |  |  **/ | 
					
						
							|  |  |  | gboolean | 
					
						
							|  |  |  | g_seekable_can_truncate (GSeekable *seekable) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GSeekableIface *iface; | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   g_return_val_if_fail (G_IS_SEEKABLE (seekable), FALSE); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   iface = G_SEEKABLE_GET_IFACE (seekable); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return (* iface->can_truncate) (seekable); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2017-11-04 20:05:37 +01:00
										 |  |  |  * g_seekable_truncate: (virtual truncate_fn) | 
					
						
							| 
									
										
										
										
											2007-11-27 14:00:13 +00:00
										 |  |  |  * @seekable: a #GSeekable. | 
					
						
							| 
									
										
										
										
											2017-11-01 14:41:00 +00:00
										 |  |  |  * @offset: new length for @seekable, in bytes. | 
					
						
							| 
									
										
										
										
											2016-10-28 18:29:02 -07:00
										 |  |  |  * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.  | 
					
						
							| 
									
										
										
										
											2011-08-29 14:49:32 -04:00
										 |  |  |  * @error: a #GError location to store the error occurring, or %NULL to  | 
					
						
							| 
									
										
										
										
											2007-11-26 16:13:05 +00:00
										 |  |  |  * ignore. | 
					
						
							| 
									
										
										
										
											2007-11-27 14:00:13 +00:00
										 |  |  |  *  | 
					
						
							| 
									
										
										
										
											2017-11-01 14:41:00 +00:00
										 |  |  |  * Sets the length of the stream to @offset. If the stream was previously | 
					
						
							|  |  |  |  * larger than @offset, the extra data is discarded. If the stream was | 
					
						
							| 
									
										
										
										
											2020-06-12 14:02:30 +01:00
										 |  |  |  * previously shorter than @offset, it is extended with NUL ('\0') bytes. | 
					
						
							| 
									
										
										
										
											2007-11-27 14:00:13 +00:00
										 |  |  |  *  | 
					
						
							|  |  |  |  * If @cancellable is not %NULL, then the operation can be cancelled by | 
					
						
							|  |  |  |  * triggering the cancellable object from another thread. If the operation | 
					
						
							|  |  |  |  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. If an | 
					
						
							|  |  |  |  * operation was partially finished when the operation was cancelled the | 
					
						
							|  |  |  |  * partial result will be returned, without an error. | 
					
						
							| 
									
										
										
										
											2010-09-24 18:24:41 -03:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2007-11-27 14:00:13 +00:00
										 |  |  |  * Returns: %TRUE if successful. If an error | 
					
						
							| 
									
										
										
										
											2008-01-16 20:00:23 +00:00
										 |  |  |  *     has occurred, this function will return %FALSE and set @error | 
					
						
							| 
									
										
										
										
											2007-11-30 05:11:25 +00:00
										 |  |  |  *     appropriately if present.  | 
					
						
							| 
									
										
										
										
											2007-11-26 16:13:05 +00:00
										 |  |  |  **/ | 
					
						
							|  |  |  | gboolean | 
					
						
							|  |  |  | g_seekable_truncate (GSeekable     *seekable, | 
					
						
							|  |  |  | 		     goffset        offset, | 
					
						
							|  |  |  | 		     GCancellable  *cancellable, | 
					
						
							|  |  |  | 		     GError       **error) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GSeekableIface *iface; | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   g_return_val_if_fail (G_IS_SEEKABLE (seekable), FALSE); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   iface = G_SEEKABLE_GET_IFACE (seekable); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-05 10:38:03 +00:00
										 |  |  |   return (* iface->truncate_fn) (seekable, offset, cancellable, error); | 
					
						
							| 
									
										
										
										
											2007-11-26 16:13:05 +00:00
										 |  |  | } |