mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-11-11 11:56:16 +01:00
Merge branch '587-seek-behaviour' into 'master'
ginputstream: Don’t skip off the end of resizable streams Closes #587 See merge request GNOME/glib!1952
This commit is contained in:
commit
7ec5405c5a
@ -411,12 +411,41 @@ g_input_stream_real_skip (GInputStream *stream,
|
||||
|
||||
if (G_IS_SEEKABLE (stream) && g_seekable_can_seek (G_SEEKABLE (stream)))
|
||||
{
|
||||
GSeekable *seekable = G_SEEKABLE (stream);
|
||||
goffset start, end;
|
||||
gboolean success;
|
||||
|
||||
/* g_seekable_seek() may try to set pending itself */
|
||||
stream->priv->pending = FALSE;
|
||||
|
||||
start = g_seekable_tell (seekable);
|
||||
|
||||
if (g_seekable_seek (G_SEEKABLE (stream),
|
||||
count,
|
||||
G_SEEK_CUR,
|
||||
cancellable,
|
||||
NULL))
|
||||
return count;
|
||||
0,
|
||||
G_SEEK_END,
|
||||
cancellable,
|
||||
NULL))
|
||||
{
|
||||
end = g_seekable_tell (seekable);
|
||||
g_assert (end >= start);
|
||||
if (start > G_MAXSIZE - count || start + count > end)
|
||||
{
|
||||
stream->priv->pending = TRUE;
|
||||
return end - start;
|
||||
}
|
||||
|
||||
success = g_seekable_seek (G_SEEKABLE (stream),
|
||||
start + count,
|
||||
G_SEEK_SET,
|
||||
cancellable,
|
||||
error);
|
||||
stream->priv->pending = TRUE;
|
||||
|
||||
if (success)
|
||||
return count;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* If not seekable, or seek failed, fall back to reading data: */
|
||||
|
@ -68,10 +68,6 @@ static gssize g_local_file_input_stream_read (GInputStream *strea
|
||||
gsize count,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
static gssize g_local_file_input_stream_skip (GInputStream *stream,
|
||||
gsize count,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
static gboolean g_local_file_input_stream_close (GInputStream *stream,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
@ -104,7 +100,6 @@ g_local_file_input_stream_class_init (GLocalFileInputStreamClass *klass)
|
||||
GFileInputStreamClass *file_stream_class = G_FILE_INPUT_STREAM_CLASS (klass);
|
||||
|
||||
stream_class->read_fn = g_local_file_input_stream_read;
|
||||
stream_class->skip = g_local_file_input_stream_skip;
|
||||
stream_class->close_fn = g_local_file_input_stream_close;
|
||||
file_stream_class->tell = g_local_file_input_stream_tell;
|
||||
file_stream_class->can_seek = g_local_file_input_stream_can_seek;
|
||||
@ -175,62 +170,6 @@ g_local_file_input_stream_read (GInputStream *stream,
|
||||
return res;
|
||||
}
|
||||
|
||||
static gssize
|
||||
g_local_file_input_stream_skip (GInputStream *stream,
|
||||
gsize count,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
off_t start, end;
|
||||
GLocalFileInputStream *file;
|
||||
|
||||
file = G_LOCAL_FILE_INPUT_STREAM (stream);
|
||||
|
||||
if (g_cancellable_set_error_if_cancelled (cancellable, error))
|
||||
return -1;
|
||||
|
||||
start = lseek (file->priv->fd, 0, SEEK_CUR);
|
||||
if (start == -1)
|
||||
{
|
||||
int errsv = errno;
|
||||
|
||||
g_set_error (error, G_IO_ERROR,
|
||||
g_io_error_from_errno (errsv),
|
||||
_("Error seeking in file: %s"),
|
||||
g_strerror (errsv));
|
||||
return -1;
|
||||
}
|
||||
|
||||
end = lseek (file->priv->fd, 0, SEEK_END);
|
||||
if (end == -1)
|
||||
{
|
||||
int errsv = errno;
|
||||
|
||||
g_set_error (error, G_IO_ERROR,
|
||||
g_io_error_from_errno (errsv),
|
||||
_("Error seeking in file: %s"),
|
||||
g_strerror (errsv));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (end - start > count)
|
||||
{
|
||||
end = lseek (file->priv->fd, count - (end - start), SEEK_CUR);
|
||||
if (end == -1)
|
||||
{
|
||||
int errsv = errno;
|
||||
|
||||
g_set_error (error, G_IO_ERROR,
|
||||
g_io_error_from_errno (errsv),
|
||||
_("Error seeking in file: %s"),
|
||||
g_strerror (errsv));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return end - start;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
g_local_file_input_stream_close (GInputStream *stream,
|
||||
GCancellable *cancellable,
|
||||
|
Loading…
Reference in New Issue
Block a user