* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General
- * Public License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
+ * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
*
* Author: Alexander Larsson <alexl@redhat.com>
*/
#include "glibintl.h"
#include "ginputstream.h"
+#include "gioprivate.h"
#include "gseekable.h"
#include "gcancellable.h"
#include "gasyncresult.h"
* All of these functions have async variants too.
**/
-G_DEFINE_ABSTRACT_TYPE (GInputStream, g_input_stream, G_TYPE_OBJECT);
-
struct _GInputStreamPrivate {
guint closed : 1;
guint pending : 1;
GAsyncReadyCallback outstanding_callback;
};
+G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GInputStream, g_input_stream, G_TYPE_OBJECT)
+
static gssize g_input_stream_real_skip (GInputStream *stream,
gsize count,
GCancellable *cancellable,
GError **error);
static void
-g_input_stream_finalize (GObject *object)
-{
- G_OBJECT_CLASS (g_input_stream_parent_class)->finalize (object);
-}
-
-static void
g_input_stream_dispose (GObject *object)
{
GInputStream *stream;
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- g_type_class_add_private (klass, sizeof (GInputStreamPrivate));
-
- gobject_class->finalize = g_input_stream_finalize;
gobject_class->dispose = g_input_stream_dispose;
klass->skip = g_input_stream_real_skip;
static void
g_input_stream_init (GInputStream *stream)
{
- stream->priv = G_TYPE_INSTANCE_GET_PRIVATE (stream,
- G_TYPE_INPUT_STREAM,
- GInputStreamPrivate);
+ stream->priv = g_input_stream_get_instance_private (stream);
}
/**
* g_input_stream_read:
* @stream: a #GInputStream.
- * @buffer: a buffer to read data into (which should be at least count bytes long).
+ * @buffer: (array length=count) (element-type guint8): a buffer to
+ * read data into (which should be at least count bytes long).
* @count: the number of bytes that will be read from the stream
* @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
* @error: location to store the error occurring, or %NULL to ignore
* can happen e.g. near the end of a file. Zero is returned on end of file
* (or if @count is zero), but never otherwise.
*
+ * The returned @buffer is not a nul-terminated string, it can contain nul bytes
+ * at any position, and this function doesn't nul-terminate the @buffer.
+ *
* 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
*
* On error -1 is returned and @error is set accordingly.
*
- * Return value: Number of bytes read, or -1 on error, or 0 on end of file.
+ * Returns: Number of bytes read, or -1 on error, or 0 on end of file.
**/
gssize
g_input_stream_read (GInputStream *stream,
/**
* g_input_stream_read_all:
* @stream: a #GInputStream.
- * @buffer: a buffer to read data into (which should be at least count bytes long).
+ * @buffer: (array length=count) (element-type guint8): a buffer to
+ * read data into (which should be at least count bytes long).
* @count: the number of bytes that will be read from the stream
* @bytes_read: (out): location to store the number of bytes that was read from the stream
* @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
* is set to indicate the error status, @bytes_read is updated to contain
* the number of bytes read into @buffer before the error occurred.
*
- * Return value: %TRUE on success, %FALSE if there was an error
+ * Returns: %TRUE on success, %FALSE if there was an error
**/
gboolean
g_input_stream_read_all (GInputStream *stream,
*
* On error %NULL is returned and @error is set accordingly.
*
- * Return value: a new #GBytes, or %NULL on error
+ * Returns: a new #GBytes, or %NULL on error
+ *
+ * Since: 2.34
**/
GBytes *
g_input_stream_read_bytes (GInputStream *stream,
* operation was partially finished when the operation was cancelled the
* partial result will be returned, without an error.
*
- * Return value: Number of bytes skipped, or -1 on error
+ * Returns: Number of bytes skipped, or -1 on error
**/
gssize
g_input_stream_skip (GInputStream *stream,
* Cancelling a close will still leave the stream closed, but some streams
* can use a faster close that doesn't block to e.g. check errors.
*
- * Return value: %TRUE on success, %FALSE on failure
+ * Returns: %TRUE on success, %FALSE on failure
**/
gboolean
g_input_stream_close (GInputStream *stream,
/**
* g_input_stream_read_async:
* @stream: A #GInputStream.
- * @buffer: a buffer to read data into (which should be at least count bytes long).
+ * @buffer: (array length=count) (element-type guint8): a buffer to
+ * read data into (which should be at least count bytes long).
* @count: the number of bytes that will be read from the stream
- * @io_priority: the <link linkend="io-priority">I/O priority</link>
+ * @io_priority: the [I/O priority][io-priority]
* of the request.
* @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
* @callback: (scope async): callback to call when the request is satisfied
* g_input_stream_read_bytes_async:
* @stream: A #GInputStream.
* @count: the number of bytes that will be read from the stream
- * @io_priority: the <link linkend="io-priority">I/O priority</link>
- * of the request.
+ * @io_priority: the [I/O priority][io-priority] of the request
* @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
* @callback: (scope async): callback to call when the request is satisfied
* @user_data: (closure): the data to pass to callback function
* Any outstanding I/O request with higher priority (lower numerical
* value) will be executed before an outstanding request with lower
* priority. Default priority is %G_PRIORITY_DEFAULT.
+ *
+ * Since: 2.34
**/
void
g_input_stream_read_bytes_async (GInputStream *stream,
* Finishes an asynchronous stream read-into-#GBytes operation.
*
* Returns: the newly-allocated #GBytes, or %NULL on error
+ *
+ * Since: 2.34
**/
GBytes *
g_input_stream_read_bytes_finish (GInputStream *stream,
* g_input_stream_skip_async:
* @stream: A #GInputStream.
* @count: the number of bytes that will be skipped from the stream
- * @io_priority: the <link linkend="io-priority">I/O priority</link>
- * of the request.
+ * @io_priority: the [I/O priority][io-priority] of the request
* @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
* @callback: (scope async): callback to call when the request is satisfied
* @user_data: (closure): the data to pass to callback function
/**
* g_input_stream_close_async:
* @stream: A #GInputStream.
- * @io_priority: the <link linkend="io-priority">I/O priority</link>
- * of the request.
+ * @io_priority: the [I/O priority][io-priority] of the request
* @cancellable: (allow-none): optional cancellable object
* @callback: (scope async): callback to call when the request is satisfied
* @user_data: (closure): the data to pass to callback function
* already set or @stream is closed, it will return %FALSE and set
* @error.
*
- * Return value: %TRUE if pending was previously unset and is now set.
+ * Returns: %TRUE if pending was previously unset and is now set.
**/
gboolean
g_input_stream_set_pending (GInputStream *stream, GError **error)
stream->priv->pending = FALSE;
}
+/**
+ * g_input_stream_async_read_is_via_threads:
+ * @stream: input stream
+ *
+ * Checks if an input stream's read_async function uses threads.
+ *
+ * Returns: %TRUE if @stream's read_async function uses threads.
+ **/
+gboolean
+g_input_stream_async_read_is_via_threads (GInputStream *stream)
+{
+ GInputStreamClass *class;
+
+ g_return_val_if_fail (G_IS_INPUT_STREAM (stream), FALSE);
+
+ class = G_INPUT_STREAM_GET_CLASS (stream);
+
+ return (class->read_async == g_input_stream_real_read_async &&
+ !(G_IS_POLLABLE_INPUT_STREAM (stream) &&
+ g_pollable_input_stream_can_poll (G_POLLABLE_INPUT_STREAM (stream))));
+}
+
/********************************************
* Default implementation of async ops *
********************************************/
/* g_input_stream_real_read_async() unrefs task */
}
+
static void
g_input_stream_real_read_async (GInputStream *stream,
void *buffer,
op->buffer = buffer;
op->count = count;
- if (G_IS_POLLABLE_INPUT_STREAM (stream) &&
- g_pollable_input_stream_can_poll (G_POLLABLE_INPUT_STREAM (stream)))
+ if (!g_input_stream_async_read_is_via_threads (stream))
read_async_pollable (G_POLLABLE_INPUT_STREAM (stream), task);
else
g_task_run_in_thread (task, read_async_thread);
char buffer[8192];
gsize count;
gsize count_skipped;
- gpointer user_data;
- GAsyncReadyCallback callback;
} SkipFallbackAsyncData;
static void
data->buffer, MIN (8192, data->count),
g_task_get_priority (task),
g_task_get_cancellable (task),
- skip_callback_wrapper, data);
+ skip_callback_wrapper, task);
return;
}
}
task = g_task_new (stream, cancellable, callback, user_data);
g_task_set_priority (task, io_priority);
- if (class->read_async == g_input_stream_real_read_async)
+ if (g_input_stream_async_read_is_via_threads (stream))
{
/* Read is thread-using async fallback.
* Make skip use threads too, so that we can use a possible sync skip
data = g_new (SkipFallbackAsyncData, 1);
data->count = count;
data->count_skipped = 0;
- data->callback = callback;
- data->user_data = user_data;
g_task_set_task_data (task, data, g_free);
g_task_set_check_cancellable (task, FALSE);
class->read_async (stream, data->buffer, MIN (8192, count), io_priority, cancellable,
- skip_callback_wrapper, data);
+ skip_callback_wrapper, task);
}
}