(root)/
glib-2.79.0/
gio/
gseekable.c
       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   * GSeekable:
      30   *
      31   * `GSeekable` is implemented by streams (implementations of
      32   * [class@Gio.InputStream] or [class@Gio.OutputStream]) that support seeking.
      33   *
      34   * Seekable streams largely fall into two categories: resizable and
      35   * fixed-size.
      36   *
      37   * `GSeekable` on fixed-sized streams is approximately the same as POSIX
      38   * [`lseek()`](man:lseek(2)) on a block device (for example: attempting to seek
      39   * past the end of the device is an error).  Fixed streams typically cannot be
      40   * truncated.
      41   *
      42   * `GSeekable` on resizable streams is approximately the same as POSIX
      43   * [`lseek()`](man:lseek(2)) on a normal file.  Seeking past the end and writing
      44   * data will usually cause the stream to resize by introducing zero bytes.
      45   **/
      46  
      47  typedef GSeekableIface GSeekableInterface;
      48  G_DEFINE_INTERFACE (GSeekable, g_seekable, G_TYPE_OBJECT)
      49  
      50  static void
      51  g_seekable_default_init (GSeekableInterface *iface)
      52  {
      53  }
      54  
      55  /**
      56   * g_seekable_tell:
      57   * @seekable: a #GSeekable.
      58   * 
      59   * Tells the current position within the stream.
      60   * 
      61   * Returns: the (positive or zero) offset from the beginning of the
      62   * buffer, zero if the target is not seekable.
      63   **/
      64  goffset
      65  g_seekable_tell (GSeekable *seekable)
      66  {
      67    GSeekableIface *iface;
      68  
      69    g_return_val_if_fail (G_IS_SEEKABLE (seekable), 0);
      70  
      71    iface = G_SEEKABLE_GET_IFACE (seekable);
      72  
      73    return (* iface->tell) (seekable);
      74  }
      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  {
      87    GSeekableIface *iface;
      88    
      89    g_return_val_if_fail (G_IS_SEEKABLE (seekable), FALSE);
      90  
      91    iface = G_SEEKABLE_GET_IFACE (seekable);
      92  
      93    return (* iface->can_seek) (seekable);
      94  }
      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  {
     131    GSeekableIface *iface;
     132    
     133    g_return_val_if_fail (G_IS_SEEKABLE (seekable), FALSE);
     134  
     135    iface = G_SEEKABLE_GET_IFACE (seekable);
     136  
     137    return (* iface->seek) (seekable, offset, type, cancellable, error);
     138  }
     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  {
     152    GSeekableIface *iface;
     153    
     154    g_return_val_if_fail (G_IS_SEEKABLE (seekable), FALSE);
     155  
     156    iface = G_SEEKABLE_GET_IFACE (seekable);
     157  
     158    return (* iface->can_truncate) (seekable);
     159  }
     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  {
     189    GSeekableIface *iface;
     190    
     191    g_return_val_if_fail (G_IS_SEEKABLE (seekable), FALSE);
     192  
     193    iface = G_SEEKABLE_GET_IFACE (seekable);
     194  
     195    return (* iface->truncate_fn) (seekable, offset, cancellable, error);
     196  }