[libsoup] Implement skip for SoupClientInputStream and SoupFilterInputStream
- From: Patrick Griffis <pgriffis src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libsoup] Implement skip for SoupClientInputStream and SoupFilterInputStream
- Date: Mon, 8 Mar 2021 18:14:17 +0000 (UTC)
commit 12cfc749653ab2b869df2ec20c9b10e1264894e7
Author: Daniel Kolesa <dkolesa igalia com>
Date: Mon Mar 8 17:56:13 2021 +0100
Implement skip for SoupClientInputStream and SoupFilterInputStream
this enables calling `g_input_stream_skip` on response body input
streams and getting predictable behavior (i.e. read but without
explicit storage)
the `skip` implementation for body input stream was insufficient,
resulting in the stream state never incrementing properly
libsoup/soup-body-input-stream.c | 26 +++++++++-----------------
libsoup/soup-client-input-stream.c | 18 ++++++++++++++++++
libsoup/soup-filter-input-stream.c | 24 +++++++++++++++++++++++-
3 files changed, 50 insertions(+), 18 deletions(-)
---
diff --git a/libsoup/soup-body-input-stream.c b/libsoup/soup-body-input-stream.c
index 88ccd2ed..56a87cda 100644
--- a/libsoup/soup-body-input-stream.c
+++ b/libsoup/soup-body-input-stream.c
@@ -136,10 +136,13 @@ soup_body_input_stream_read_raw (SoupBodyInputStream *bistream,
SoupBodyInputStreamPrivate *priv = soup_body_input_stream_get_instance_private (bistream);
gssize nread;
- nread = g_pollable_stream_read (priv->base_stream,
- buffer, count,
- blocking,
- cancellable, error);
+ if (!buffer && blocking)
+ nread = g_input_stream_skip (priv->base_stream, count, cancellable, error);
+ else
+ nread = g_pollable_stream_read (priv->base_stream,
+ buffer, count,
+ blocking,
+ cancellable, error);
if (nread == 0) {
priv->eof = TRUE;
if (priv->encoding != SOUP_ENCODING_EOF) {
@@ -288,19 +291,8 @@ soup_body_input_stream_skip (GInputStream *stream,
GCancellable *cancellable,
GError **error)
{
- SoupBodyInputStreamPrivate *priv = soup_body_input_stream_get_instance_private
(SOUP_BODY_INPUT_STREAM(stream));
- gssize skipped;
-
- skipped = g_input_stream_skip (G_FILTER_INPUT_STREAM (stream)->base_stream,
- MIN (count, priv->read_length),
- cancellable, error);
-
- if (skipped == 0)
- priv->eof = TRUE;
- else if (skipped > 0)
- priv->pos += skipped;
-
- return skipped;
+ return read_internal (stream, NULL, count, TRUE,
+ cancellable, error);
}
static gssize
diff --git a/libsoup/soup-client-input-stream.c b/libsoup/soup-client-input-stream.c
index d3a75467..2b452fe5 100644
--- a/libsoup/soup-client-input-stream.c
+++ b/libsoup/soup-client-input-stream.c
@@ -111,6 +111,23 @@ soup_client_input_stream_read_fn (GInputStream *stream,
return nread;
}
+static gssize
+soup_client_input_stream_skip (GInputStream *stream,
+ gsize count,
+ GCancellable *cancellable,
+ GError **error)
+{
+ gssize nread;
+
+ nread = G_INPUT_STREAM_CLASS (soup_client_input_stream_parent_class)->
+ skip (stream, count, cancellable, error);
+
+ if (nread == 0)
+ g_signal_emit (stream, signals[SIGNAL_EOF], 0);
+
+ return nread;
+}
+
static gssize
soup_client_input_stream_read_nonblocking (GPollableInputStream *stream,
void *buffer,
@@ -233,6 +250,7 @@ soup_client_input_stream_class_init (SoupClientInputStreamClass *stream_class)
object_class->get_property = soup_client_input_stream_get_property;
input_stream_class->read_fn = soup_client_input_stream_read_fn;
+ input_stream_class->skip = soup_client_input_stream_skip;
input_stream_class->close_fn = soup_client_input_stream_close_fn;
input_stream_class->close_async = soup_client_input_stream_close_async;
input_stream_class->close_finish = soup_client_input_stream_close_finish;
diff --git a/libsoup/soup-filter-input-stream.c b/libsoup/soup-filter-input-stream.c
index fd4466f1..d3af6b72 100644
--- a/libsoup/soup-filter-input-stream.c
+++ b/libsoup/soup-filter-input-stream.c
@@ -57,7 +57,8 @@ read_from_buf (SoupFilterInputStream *fstream, gpointer buffer, gsize count)
if (buf->len < count)
count = buf->len;
- memcpy (buffer, buf->data, count);
+ if (buffer)
+ memcpy (buffer, buf->data, count);
if (count == buf->len) {
g_byte_array_free (buf, TRUE);
@@ -93,6 +94,26 @@ soup_filter_input_stream_read_fn (GInputStream *stream,
}
}
+static gssize
+soup_filter_input_stream_skip (GInputStream *stream,
+ gsize count,
+ GCancellable *cancellable,
+ GError **error)
+{
+ SoupFilterInputStream *fstream = SOUP_FILTER_INPUT_STREAM (stream);
+ SoupFilterInputStreamPrivate *priv = soup_filter_input_stream_get_instance_private (fstream);
+
+ if (!priv->in_read_until)
+ priv->need_more = FALSE;
+
+ if (priv->buf && !priv->in_read_until) {
+ return read_from_buf (fstream, NULL, count);
+ } else {
+ return g_input_stream_skip (G_FILTER_INPUT_STREAM (fstream)->base_stream,
+ count, cancellable, error);
+ }
+}
+
static gboolean
soup_filter_input_stream_is_readable (GPollableInputStream *stream)
{
@@ -156,6 +177,7 @@ soup_filter_input_stream_class_init (SoupFilterInputStreamClass *stream_class)
object_class->finalize = soup_filter_input_stream_finalize;
input_stream_class->read_fn = soup_filter_input_stream_read_fn;
+ input_stream_class->skip = soup_filter_input_stream_skip;
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]