From bd0b8c60c231c72588d69dfb2018d2e418517f7f Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Tue, 12 May 2009 16:59:36 +0200 Subject: [PATCH] Add GFileIOStream class This is similar to GFileInputStream and GFileOutputStream for GIOStreams. The default implementations chain to the Output stream. --- gio/Makefile.am | 2 + gio/gfileiostream.c | 671 ++++++++++++++++++++++++++++++++++++++++++++ gio/gfileiostream.h | 118 ++++++++ gio/gio.h | 1 + gio/gio.symbols | 10 + gio/giostream.c | 3 - gio/giotypes.h | 1 + 7 files changed, 803 insertions(+), 3 deletions(-) create mode 100644 gio/gfileiostream.c create mode 100644 gio/gfileiostream.h diff --git a/gio/Makefile.am b/gio/Makefile.am index 78c2c3f12..76e402dc4 100644 --- a/gio/Makefile.am +++ b/gio/Makefile.am @@ -199,6 +199,7 @@ libgio_2_0_la_SOURCES = \ gfilemonitor.c \ gfilenamecompleter.c \ gfileoutputstream.c \ + gfileiostream.c \ gfilterinputstream.c \ gfilteroutputstream.c \ gicon.c \ @@ -315,6 +316,7 @@ gio_headers = \ gfilemonitor.h \ gfilenamecompleter.h \ gfileoutputstream.h \ + gfileiostream.h \ gfilterinputstream.h \ gfilteroutputstream.h \ gicon.h \ diff --git a/gio/gfileiostream.c b/gio/gfileiostream.c new file mode 100644 index 000000000..9491e766a --- /dev/null +++ b/gio/gfileiostream.c @@ -0,0 +1,671 @@ +/* GIO - GLib Input, IO and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * 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 + * version 2 of the License, or (at your option) any later version. + * + * 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 + * 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. + * + * Author: Alexander Larsson + */ + +#include "config.h" + +#include +#include +#include +#include "gsimpleasyncresult.h" +#include "gasyncresult.h" +#include "gcancellable.h" +#include "gioerror.h" +#include "gfileoutputstream.h" +#include "glibintl.h" + +#include "gioalias.h" + +/** + * SECTION:gfileiostream + * @short_description: read write streams for File + * @include: gio/gio.h + * @see_also: #GIOStream, #GFileInputStream, #GFileOutputStream, #GSeekable + * + * GFileIOStream provides io streams that both read and write to the same + * file handle. + * + * GFileIOStream implements #GSeekable, which allows the io + * stream to jump to arbitrary positions in the file and to truncate + * the file, provided the filesystem of the file supports these + * operations. In addition to the generic g_seekable_ API, + * GFileIOStream has its own API for seeking and positioning. + * To find the position of a file io stream, use + * g_file_io_stream_tell(). To find out if a file io + * stream supports seeking, use g_file_io_stream_can_seek(). + * To position a file io stream, use g_file_io_stream_seek(). + * To find out if a file io stream supports truncating, use + * g_file_io_stream_can_truncate(). To truncate a file io + * stream, use g_file_io_stream_truncate(). + * + * Since: 2.22 + **/ + +static void g_file_io_stream_seekable_iface_init (GSeekableIface *iface); +static goffset g_file_io_stream_seekable_tell (GSeekable *seekable); +static gboolean g_file_io_stream_seekable_can_seek (GSeekable *seekable); +static gboolean g_file_io_stream_seekable_seek (GSeekable *seekable, + goffset offset, + GSeekType type, + GCancellable *cancellable, + GError **error); +static gboolean g_file_io_stream_seekable_can_truncate (GSeekable *seekable); +static gboolean g_file_io_stream_seekable_truncate (GSeekable *seekable, + goffset offset, + GCancellable *cancellable, + GError **error); +static void g_file_io_stream_real_query_info_async (GFileIOStream *stream, + const char *attributes, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +static GFileInfo *g_file_io_stream_real_query_info_finish (GFileIOStream *stream, + GAsyncResult *result, + GError **error); + +G_DEFINE_TYPE_WITH_CODE (GFileIOStream, g_file_io_stream, G_TYPE_IO_STREAM, + G_IMPLEMENT_INTERFACE (G_TYPE_SEEKABLE, + g_file_io_stream_seekable_iface_init)); + +struct _GFileIOStreamPrivate { + GAsyncReadyCallback outstanding_callback; +}; + +static void +g_file_io_stream_seekable_iface_init (GSeekableIface *iface) +{ + iface->tell = g_file_io_stream_seekable_tell; + iface->can_seek = g_file_io_stream_seekable_can_seek; + iface->seek = g_file_io_stream_seekable_seek; + iface->can_truncate = g_file_io_stream_seekable_can_truncate; + iface->truncate_fn = g_file_io_stream_seekable_truncate; +} + +static void +g_file_io_stream_init (GFileIOStream *stream) +{ + stream->priv = G_TYPE_INSTANCE_GET_PRIVATE (stream, + G_TYPE_FILE_IO_STREAM, + GFileIOStreamPrivate); +} + +/** + * g_file_io_stream_query_info: + * @stream: a #GFileIOStream. + * @attributes: a file attribute query string. + * @cancellable: optional #GCancellable object, %NULL to ignore. + * @error: a #GError, %NULL to ignore. + * + * Queries a file io stream for the given @attributes. + * This function blocks while querying the stream. For the asynchronous + * version of this function, see g_file_io_stream_query_info_async(). + * While the stream is blocked, the stream will set the pending flag + * internally, and any other operations on the stream will fail with + * %G_IO_ERROR_PENDING. + * + * Can fail if the stream was already closed (with @error being set to + * %G_IO_ERROR_CLOSED), the stream has pending operations (with @error being + * set to %G_IO_ERROR_PENDING), or if querying info is not supported for + * the stream's interface (with @error being set to %G_IO_ERROR_NOT_SUPPORTED). I + * all cases of failure, %NULL will be returned. + * + * 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 set, and %NULL will + * be returned. + * + * Returns: a #GFileInfo for the @stream, or %NULL on error. + * + * Since: 2.22 + **/ +GFileInfo * +g_file_io_stream_query_info (GFileIOStream *stream, + const char *attributes, + GCancellable *cancellable, + GError **error) +{ + GFileIOStreamClass *class; + GIOStream *io_stream; + GFileInfo *info; + + g_return_val_if_fail (G_IS_FILE_IO_STREAM (stream), NULL); + + io_stream = G_IO_STREAM (stream); + + if (!g_io_stream_set_pending (io_stream, error)) + return NULL; + + info = NULL; + + if (cancellable) + g_cancellable_push_current (cancellable); + + class = G_FILE_IO_STREAM_GET_CLASS (stream); + if (class->query_info) + info = class->query_info (stream, attributes, cancellable, error); + else + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Stream doesn't support query_info")); + + if (cancellable) + g_cancellable_pop_current (cancellable); + + g_io_stream_clear_pending (io_stream); + + return info; +} + +static void +async_ready_callback_wrapper (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + GFileIOStream *stream = G_FILE_IO_STREAM (source_object); + + g_io_stream_clear_pending (G_IO_STREAM (stream)); + if (stream->priv->outstanding_callback) + (*stream->priv->outstanding_callback) (source_object, res, user_data); + g_object_unref (stream); +} + +/** + * g_file_io_stream_query_info_async: + * @stream: a #GFileIOStream. + * @attributes: a file attribute query string. + * @io_priority: the I/O priority + * of the request. + * @cancellable: optional #GCancellable object, %NULL to ignore. + * @callback: callback to call when the request is satisfied + * @user_data: the data to pass to callback function + * + * Asynchronously queries the @stream for a #GFileInfo. When completed, + * @callback will be called with a #GAsyncResult which can be used to + * finish the operation with g_file_io_stream_query_info_finish(). + * + * For the synchronous version of this function, see + * g_file_io_stream_query_info(). + * + * Since: 2.22 + **/ +void +g_file_io_stream_query_info_async (GFileIOStream *stream, + const char *attributes, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GFileIOStreamClass *klass; + GIOStream *io_stream; + GError *error = NULL; + + g_return_if_fail (G_IS_FILE_IO_STREAM (stream)); + + io_stream = G_IO_STREAM (stream); + + if (!g_io_stream_set_pending (io_stream, &error)) + { + g_simple_async_report_gerror_in_idle (G_OBJECT (stream), + callback, + user_data, + error); + g_error_free (error); + return; + } + + klass = G_FILE_IO_STREAM_GET_CLASS (stream); + + stream->priv->outstanding_callback = callback; + g_object_ref (stream); + klass->query_info_async (stream, attributes, io_priority, cancellable, + async_ready_callback_wrapper, user_data); +} + +/** + * g_file_io_stream_query_info_finish: + * @stream: a #GFileIOStream. + * @result: a #GAsyncResult. + * @error: a #GError, %NULL to ignore. + * + * Finalizes the asynchronous query started + * by g_file_io_stream_query_info_async(). + * + * Returns: A #GFileInfo for the finished query. + * + * Since: 2.22 + **/ +GFileInfo * +g_file_io_stream_query_info_finish (GFileIOStream *stream, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + GFileIOStreamClass *class; + + g_return_val_if_fail (G_IS_FILE_IO_STREAM (stream), NULL); + g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL); + + if (G_IS_SIMPLE_ASYNC_RESULT (result)) + { + simple = G_SIMPLE_ASYNC_RESULT (result); + if (g_simple_async_result_propagate_error (simple, error)) + return NULL; + } + + class = G_FILE_IO_STREAM_GET_CLASS (stream); + return class->query_info_finish (stream, result, error); +} + +/** + * g_file_io_stream_get_etag: + * @stream: a #GFileIOStream. + * + * Gets the entity tag for the file when it has been written. + * This must be called after the stream has been written + * and closed, as the etag can change while writing. + * + * Returns: the entity tag for the stream. + * + * Since: 2.22 + **/ +char * +g_file_io_stream_get_etag (GFileIOStream *stream) +{ + GFileIOStreamClass *class; + GIOStream *io_stream; + char *etag; + + g_return_val_if_fail (G_IS_FILE_IO_STREAM (stream), NULL); + + io_stream = G_IO_STREAM (stream); + + if (!g_io_stream_is_closed (io_stream)) + { + g_warning ("stream is not closed yet, can't get etag"); + return NULL; + } + + etag = NULL; + + class = G_FILE_IO_STREAM_GET_CLASS (stream); + if (class->get_etag) + etag = class->get_etag (stream); + + return etag; +} + +static goffset +g_file_io_stream_tell (GFileIOStream *stream) +{ + GFileIOStreamClass *class; + goffset offset; + + g_return_val_if_fail (G_IS_FILE_IO_STREAM (stream), 0); + + class = G_FILE_IO_STREAM_GET_CLASS (stream); + + offset = 0; + if (class->tell) + offset = class->tell (stream); + + return offset; +} + +static goffset +g_file_io_stream_seekable_tell (GSeekable *seekable) +{ + return g_file_io_stream_tell (G_FILE_IO_STREAM (seekable)); +} + +static gboolean +g_file_io_stream_can_seek (GFileIOStream *stream) +{ + GFileIOStreamClass *class; + gboolean can_seek; + + g_return_val_if_fail (G_IS_FILE_IO_STREAM (stream), FALSE); + + class = G_FILE_IO_STREAM_GET_CLASS (stream); + + can_seek = FALSE; + if (class->seek) + { + can_seek = TRUE; + if (class->can_seek) + can_seek = class->can_seek (stream); + } + + return can_seek; +} + +static gboolean +g_file_io_stream_seekable_can_seek (GSeekable *seekable) +{ + return g_file_io_stream_can_seek (G_FILE_IO_STREAM (seekable)); +} + +static gboolean +g_file_io_stream_seek (GFileIOStream *stream, + goffset offset, + GSeekType type, + GCancellable *cancellable, + GError **error) +{ + GFileIOStreamClass *class; + GIOStream *io_stream; + gboolean res; + + g_return_val_if_fail (G_IS_FILE_IO_STREAM (stream), FALSE); + + io_stream = G_IO_STREAM (stream); + class = G_FILE_IO_STREAM_GET_CLASS (stream); + + if (!class->seek) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Seek not supported on stream")); + return FALSE; + } + + if (!g_io_stream_set_pending (io_stream, error)) + return FALSE; + + if (cancellable) + g_cancellable_push_current (cancellable); + + res = class->seek (stream, offset, type, cancellable, error); + + if (cancellable) + g_cancellable_pop_current (cancellable); + + g_io_stream_clear_pending (io_stream); + + return res; +} + +static gboolean +g_file_io_stream_seekable_seek (GSeekable *seekable, + goffset offset, + GSeekType type, + GCancellable *cancellable, + GError **error) +{ + return g_file_io_stream_seek (G_FILE_IO_STREAM (seekable), + offset, type, cancellable, error); +} + +static gboolean +g_file_io_stream_can_truncate (GFileIOStream *stream) +{ + GFileIOStreamClass *class; + gboolean can_truncate; + + g_return_val_if_fail (G_IS_FILE_IO_STREAM (stream), FALSE); + + class = G_FILE_IO_STREAM_GET_CLASS (stream); + + can_truncate = FALSE; + if (class->truncate_fn) + { + can_truncate = TRUE; + if (class->can_truncate) + can_truncate = class->can_truncate (stream); + } + + return can_truncate; +} + +static gboolean +g_file_io_stream_seekable_can_truncate (GSeekable *seekable) +{ + return g_file_io_stream_can_truncate (G_FILE_IO_STREAM (seekable)); +} + +static gboolean +g_file_io_stream_truncate (GFileIOStream *stream, + goffset size, + GCancellable *cancellable, + GError **error) +{ + GFileIOStreamClass *class; + GIOStream *io_stream; + gboolean res; + + g_return_val_if_fail (G_IS_FILE_IO_STREAM (stream), FALSE); + + io_stream = G_IO_STREAM (stream); + class = G_FILE_IO_STREAM_GET_CLASS (stream); + + if (!class->truncate_fn) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Truncate not supported on stream")); + return FALSE; + } + + if (!g_io_stream_set_pending (io_stream, error)) + return FALSE; + + if (cancellable) + g_cancellable_push_current (cancellable); + + res = class->truncate_fn (stream, size, cancellable, error); + + if (cancellable) + g_cancellable_pop_current (cancellable); + + g_io_stream_clear_pending (io_stream); + + return res; +} + +static gboolean +g_file_io_stream_seekable_truncate (GSeekable *seekable, + goffset size, + GCancellable *cancellable, + GError **error) +{ + return g_file_io_stream_truncate (G_FILE_IO_STREAM (seekable), + size, cancellable, error); +} +/***************************************************** + * Default implementations based on output stream * + *****************************************************/ + +static goffset +g_file_io_stream_real_tell (GFileIOStream *stream) +{ + GOutputStream *out; + GSeekable *seekable; + + out = g_io_stream_get_output_stream (G_IO_STREAM (stream)); + seekable = G_SEEKABLE (out); + + return g_seekable_tell (seekable); +} + +static gboolean +g_file_io_stream_real_can_seek (GFileIOStream *stream) +{ + GOutputStream *out; + GSeekable *seekable; + + out = g_io_stream_get_output_stream (G_IO_STREAM (stream)); + seekable = G_SEEKABLE (out); + + return g_seekable_can_seek (seekable); +} + +static gboolean +g_file_io_stream_real_seek (GFileIOStream *stream, + goffset offset, + GSeekType type, + GCancellable *cancellable, + GError **error) +{ + GOutputStream *out; + GSeekable *seekable; + + out = g_io_stream_get_output_stream (G_IO_STREAM (stream)); + seekable = G_SEEKABLE (out); + + return g_seekable_seek (seekable, offset, type, cancellable, error); +} + +static gboolean +g_file_io_stream_real_can_truncate (GFileIOStream *stream) +{ + GOutputStream *out; + GSeekable *seekable; + + out = g_io_stream_get_output_stream (G_IO_STREAM (stream)); + seekable = G_SEEKABLE (out); + + return g_seekable_can_truncate (seekable); +} + +static gboolean +g_file_io_stream_real_truncate_fn (GFileIOStream *stream, + goffset size, + GCancellable *cancellable, + GError **error) +{ + GOutputStream *out; + GSeekable *seekable; + + out = g_io_stream_get_output_stream (G_IO_STREAM (stream)); + seekable = G_SEEKABLE (out); + + return g_seekable_truncate (seekable, size, cancellable, error); +} + +static char * +g_file_io_stream_real_get_etag (GFileIOStream *stream) +{ + GOutputStream *out; + GFileOutputStream *file_out; + + out = g_io_stream_get_output_stream (G_IO_STREAM (stream)); + file_out = G_FILE_OUTPUT_STREAM (out); + + return g_file_output_stream_get_etag (file_out); +} + +static GFileInfo * +g_file_io_stream_real_query_info (GFileIOStream *stream, + const char *attributes, + GCancellable *cancellable, + GError **error) +{ + GOutputStream *out; + GFileOutputStream *file_out; + + out = g_io_stream_get_output_stream (G_IO_STREAM (stream)); + file_out = G_FILE_OUTPUT_STREAM (out); + + return g_file_output_stream_query_info (file_out, + attributes, cancellable, error); +} + +typedef struct { + GObject *object; + GAsyncReadyCallback callback; + gpointer user_data; +} AsyncOpWrapper; + +static AsyncOpWrapper * +async_op_wrapper_new (gpointer object, + GAsyncReadyCallback callback, + gpointer user_data) +{ + AsyncOpWrapper *data; + + data = g_new0 (AsyncOpWrapper, 1); + data->object = g_object_ref (object); + data->callback = callback; + data->user_data = user_data; +} + +static void +async_op_wrapper_callback (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + AsyncOpWrapper *data = user_data; + data->callback (data->object, res, data->user_data); + g_object_unref (data->object); + g_free (data); +} + +static void +g_file_io_stream_real_query_info_async (GFileIOStream *stream, + const char *attributes, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GOutputStream *out; + GFileOutputStream *file_out; + AsyncOpWrapper *data; + + out = g_io_stream_get_output_stream (G_IO_STREAM (stream)); + file_out = G_FILE_OUTPUT_STREAM (out); + + data = async_op_wrapper_new (stream, callback, user_data); + g_file_output_stream_query_info_async (file_out, + attributes, io_priority, + cancellable, async_op_wrapper_callback, data); +} + +static GFileInfo * +g_file_io_stream_real_query_info_finish (GFileIOStream *stream, + GAsyncResult *res, + GError **error) +{ + GOutputStream *out; + GFileOutputStream *file_out; + + out = g_io_stream_get_output_stream (G_IO_STREAM (stream)); + file_out = G_FILE_OUTPUT_STREAM (out); + + return g_file_output_stream_query_info_finish (file_out, res, error); +} + +static void +g_file_io_stream_class_init (GFileIOStreamClass *klass) +{ + g_type_class_add_private (klass, sizeof (GFileIOStreamPrivate)); + + klass->tell = g_file_io_stream_real_tell; + klass->can_seek = g_file_io_stream_real_can_seek; + klass->seek = g_file_io_stream_real_seek; + klass->can_truncate = g_file_io_stream_real_can_truncate; + klass->truncate_fn = g_file_io_stream_real_truncate_fn; + klass->query_info = g_file_io_stream_real_query_info; + klass->query_info_async = g_file_io_stream_real_query_info_async; + klass->query_info_finish = g_file_io_stream_real_query_info_finish; + klass->get_etag = g_file_io_stream_real_get_etag; +} + +#define __G_FILE_IO_STREAM_C__ +#include "gioaliasdef.c" diff --git a/gio/gfileiostream.h b/gio/gfileiostream.h new file mode 100644 index 000000000..09c99224b --- /dev/null +++ b/gio/gfileiostream.h @@ -0,0 +1,118 @@ +/* GIO - GLib Input, Io and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * 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 + * version 2 of the License, or (at your option) any later version. + * + * 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 + * 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. + * + * Author: Alexander Larsson + */ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_FILE_IO_STREAM_H__ +#define __G_FILE_IO_STREAM_H__ + +#include + +G_BEGIN_DECLS + +#define G_TYPE_FILE_IO_STREAM (g_file_io_stream_get_type ()) +#define G_FILE_IO_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_FILE_IO_STREAM, GFileIOStream)) +#define G_FILE_IO_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_FILE_IO_STREAM, GFileIOStreamClass)) +#define G_IS_FILE_IO_STREAM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_FILE_IO_STREAM)) +#define G_IS_FILE_IO_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_FILE_IO_STREAM)) +#define G_FILE_IO_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_FILE_IO_STREAM, GFileIOStreamClass)) + +/** + * GFileIOStream: + * + * A subclass of GIOStream for opened files. This adds + * a few file-specific operations and seeking and truncating. + * + * #GFileIOStream implements GSeekable. + **/ +typedef struct _GFileIOStreamClass GFileIOStreamClass; +typedef struct _GFileIOStreamPrivate GFileIOStreamPrivate; + +struct _GFileIOStream +{ + GIOStream parent_instance; + + /*< private >*/ + GFileIOStreamPrivate *priv; +}; + +struct _GFileIOStreamClass +{ + GIOStreamClass parent_class; + + goffset (* tell) (GFileIOStream *stream); + gboolean (* can_seek) (GFileIOStream *stream); + gboolean (* seek) (GFileIOStream *stream, + goffset offset, + GSeekType type, + GCancellable *cancellable, + GError **error); + gboolean (* can_truncate) (GFileIOStream *stream); + gboolean (* truncate_fn) (GFileIOStream *stream, + goffset size, + GCancellable *cancellable, + GError **error); + GFileInfo * (* query_info) (GFileIOStream *stream, + const char *attributes, + GCancellable *cancellable, + GError **error); + void (* query_info_async) (GFileIOStream *stream, + const char *attributes, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + GFileInfo * (* query_info_finish) (GFileIOStream *stream, + GAsyncResult *res, + GError **error); + char * (* get_etag) (GFileIOStream *stream); + + /* Padding for future expansion */ + void (*_g_reserved1) (void); + void (*_g_reserved2) (void); + void (*_g_reserved3) (void); + void (*_g_reserved4) (void); + void (*_g_reserved5) (void); +}; + +GType g_file_io_stream_get_type (void) G_GNUC_CONST; + +GFileInfo *g_file_io_stream_query_info (GFileIOStream *stream, + const char *attributes, + GCancellable *cancellable, + GError **error); +void g_file_io_stream_query_info_async (GFileIOStream *stream, + const char *attributes, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GFileInfo *g_file_io_stream_query_info_finish (GFileIOStream *stream, + GAsyncResult *result, + GError **error); +char * g_file_io_stream_get_etag (GFileIOStream *stream); + +G_END_DECLS + +#endif /* __G_FILE_FILE_IO_STREAM_H__ */ diff --git a/gio/gio.h b/gio/gio.h index 63d0b7948..f12d2ed90 100644 --- a/gio/gio.h +++ b/gio/gio.h @@ -58,6 +58,7 @@ #include #include #include +#include #include #include #include diff --git a/gio/gio.symbols b/gio/gio.symbols index 9ebc37c85..26711948f 100644 --- a/gio/gio.symbols +++ b/gio/gio.symbols @@ -458,6 +458,16 @@ g_file_output_stream_get_etag #endif #endif +#if IN_HEADER(__G_FILE_IO_STREAM_H__) +#if IN_FILE(__G_FILE_IO_STREAM_C__) +g_file_io_stream_get_type G_GNUC_CONST +g_file_io_stream_query_info +g_file_io_stream_query_info_async +g_file_io_stream_query_info_finish +g_file_io_stream_get_etag +#endif +#endif + #if IN_HEADER(__G_FILTER_INPUT_STREAM_H__) #if IN_FILE(__G_FILTER_INPUT_STREAM_C__) g_filter_input_stream_get_type G_GNUC_CONST diff --git a/gio/giostream.c b/gio/giostream.c index 6f3de48fa..6c3a07303 100644 --- a/gio/giostream.c +++ b/gio/giostream.c @@ -96,9 +96,6 @@ g_io_stream_finalize (GObject *object) stream = G_IO_STREAM (object); - if (!stream->priv->closed) - g_io_stream_close (stream, NULL, NULL); - G_OBJECT_CLASS (g_io_stream_parent_class)->finalize (object); } diff --git a/gio/giotypes.h b/gio/giotypes.h index 9af865161..3a3c361c4 100644 --- a/gio/giotypes.h +++ b/gio/giotypes.h @@ -70,6 +70,7 @@ typedef struct _GFileAttributeInfo GFileAttributeInfo; typedef struct _GFileAttributeInfoList GFileAttributeInfoList; typedef struct _GFileInputStream GFileInputStream; typedef struct _GFileOutputStream GFileOutputStream; +typedef struct _GFileIOStream GFileIOStream; typedef struct _GFileIcon GFileIcon; typedef struct _GFilenameCompleter GFilenameCompleter;