mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-04 18:26:19 +01:00
Add GIOStream operations to GFile
g_file_open_readwrite, g_file_create_readwrite, g_file_replace_readwrite and async variants, with default implementations using threads.
This commit is contained in:
parent
bd0b8c60c2
commit
7a2d4889b5
666
gio/gfile.c
666
gio/gfile.c
@ -192,6 +192,34 @@ static void g_file_real_replace_async (GFile
|
||||
static GFileOutputStream *g_file_real_replace_finish (GFile *file,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
static void g_file_real_open_readwrite_async (GFile *file,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
static GFileIOStream * g_file_real_open_readwrite_finish (GFile *file,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
static void g_file_real_create_readwrite_async (GFile *file,
|
||||
GFileCreateFlags flags,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
static GFileIOStream * g_file_real_create_readwrite_finish (GFile *file,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
static void g_file_real_replace_readwrite_async (GFile *file,
|
||||
const char *etag,
|
||||
gboolean make_backup,
|
||||
GFileCreateFlags flags,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
static GFileIOStream * g_file_real_replace_readwrite_finish (GFile *file,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
static gboolean g_file_real_set_attributes_from_info (GFile *file,
|
||||
GFileInfo *info,
|
||||
GFileQueryInfoFlags flags,
|
||||
@ -293,6 +321,12 @@ g_file_class_init (gpointer g_class,
|
||||
iface->create_finish = g_file_real_create_finish;
|
||||
iface->replace_async = g_file_real_replace_async;
|
||||
iface->replace_finish = g_file_real_replace_finish;
|
||||
iface->open_readwrite_async = g_file_real_open_readwrite_async;
|
||||
iface->open_readwrite_finish = g_file_real_open_readwrite_finish;
|
||||
iface->create_readwrite_async = g_file_real_create_readwrite_async;
|
||||
iface->create_readwrite_finish = g_file_real_create_readwrite_finish;
|
||||
iface->replace_readwrite_async = g_file_real_replace_readwrite_async;
|
||||
iface->replace_readwrite_finish = g_file_real_replace_readwrite_finish;
|
||||
iface->find_enclosing_mount_async = g_file_real_find_enclosing_mount_async;
|
||||
iface->find_enclosing_mount_finish = g_file_real_find_enclosing_mount_finish;
|
||||
iface->set_attributes_from_info = g_file_real_set_attributes_from_info;
|
||||
@ -1631,6 +1665,173 @@ g_file_replace (GFile *file,
|
||||
return (* iface->replace) (file, etag, make_backup, flags, cancellable, error);
|
||||
}
|
||||
|
||||
/**
|
||||
* g_file_open_readwrite:
|
||||
* @file: #GFile to open
|
||||
* @cancellable: a #GCancellable
|
||||
* @error: a #GError, or %NULL
|
||||
*
|
||||
* Opens an existing file for reading and writing. The result is
|
||||
* a #GFileIOStream that can be used to read and write the contents of the file.
|
||||
*
|
||||
* 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 the file does not exist, the G_IO_ERROR_NOT_FOUND error will be returned.
|
||||
* If the file is a directory, the G_IO_ERROR_IS_DIRECTORY error will be returned.
|
||||
* Other errors are possible too, and depend on what kind of filesystem the file is on.
|
||||
* Note that in many non-local file cases read and write streams are not supported,
|
||||
* so make sure you really need to do read and write streaming, rather than
|
||||
* just opening for reading or writing.
|
||||
*
|
||||
* Returns: #GFileIOStream or %NULL on error.
|
||||
* Free the returned object with g_object_unref().
|
||||
*
|
||||
* Since: 2.22
|
||||
**/
|
||||
GFileIOStream *
|
||||
g_file_open_readwrite (GFile *file,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
GFileIface *iface;
|
||||
|
||||
g_return_val_if_fail (G_IS_FILE (file), NULL);
|
||||
|
||||
if (g_cancellable_set_error_if_cancelled (cancellable, error))
|
||||
return NULL;
|
||||
|
||||
iface = G_FILE_GET_IFACE (file);
|
||||
|
||||
if (iface->open_readwrite == NULL)
|
||||
{
|
||||
g_set_error_literal (error, G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_SUPPORTED,
|
||||
_("Operation not supported"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (* iface->open_readwrite) (file, cancellable, error);
|
||||
}
|
||||
|
||||
/**
|
||||
* g_file_create_readwrite:
|
||||
* @file: input #GFile.
|
||||
* @flags: a set of #GFileCreateFlags.
|
||||
* @cancellable: optional #GCancellable object, %NULL to ignore.
|
||||
* @error: a #GError, or %NULL
|
||||
*
|
||||
* Creates a new file and returns a stream for reading and writing to it.
|
||||
* The file must not already exist.
|
||||
*
|
||||
* By default files created are generally readable by everyone,
|
||||
* but if you pass #G_FILE_CREATE_PRIVATE in @flags the file
|
||||
* will be made readable only to the current user, to the level that
|
||||
* is supported on the target filesystem.
|
||||
*
|
||||
* 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 a file or directory with this name already exists the G_IO_ERROR_EXISTS
|
||||
* error will be returned.
|
||||
* Some file systems don't allow all file names, and may
|
||||
* return an G_IO_ERROR_INVALID_FILENAME error, and if the name
|
||||
* is to long G_IO_ERROR_FILENAME_TOO_LONG will be returned.
|
||||
* Other errors are possible too, and depend on what kind of
|
||||
* filesystem the file is on.
|
||||
*
|
||||
* Note that in many non-local file cases read and write streams are not supported,
|
||||
* so make sure you really need to do read and write streaming, rather than
|
||||
* just opening for reading or writing.
|
||||
*
|
||||
* Returns: a #GFileIOStream for the newly created file, or
|
||||
* %NULL on error.
|
||||
* Free the returned object with g_object_unref().
|
||||
*
|
||||
* Since: 2.22
|
||||
**/
|
||||
GFileIOStream *
|
||||
g_file_create_readwrite (GFile *file,
|
||||
GFileCreateFlags flags,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
GFileIface *iface;
|
||||
|
||||
g_return_val_if_fail (G_IS_FILE (file), NULL);
|
||||
|
||||
if (g_cancellable_set_error_if_cancelled (cancellable, error))
|
||||
return NULL;
|
||||
|
||||
iface = G_FILE_GET_IFACE (file);
|
||||
|
||||
if (iface->create_readwrite == NULL)
|
||||
{
|
||||
g_set_error_literal (error, G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_SUPPORTED,
|
||||
_("Operation not supported"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (* iface->create_readwrite) (file, flags, cancellable, error);
|
||||
}
|
||||
|
||||
/**
|
||||
* g_file_replace:
|
||||
* @file: input #GFile.
|
||||
* @etag: an optional <link linkend="gfile-etag">entity tag</link> for the
|
||||
* current #GFile, or #NULL to ignore.
|
||||
* @make_backup: %TRUE if a backup should be created.
|
||||
* @flags: a set of #GFileCreateFlags.
|
||||
* @cancellable: optional #GCancellable object, %NULL to ignore.
|
||||
* @error: a #GError, or %NULL
|
||||
*
|
||||
* Returns an output stream for overwriting the file in readwrite mode,
|
||||
* possibly creating a backup copy of the file first. If the file doesn't exist,
|
||||
* it will be created.
|
||||
*
|
||||
* For details about the behaviour, see g_file_replace() which does the same
|
||||
* thing but returns an output stream only.
|
||||
*
|
||||
* Note that in many non-local file cases read and write streams are not supported,
|
||||
* so make sure you really need to do read and write streaming, rather than
|
||||
* just opening for reading or writing.
|
||||
*
|
||||
* Returns: a #GFileIOStream or %NULL on error.
|
||||
* Free the returned object with g_object_unref().
|
||||
*
|
||||
* Since: 2.22
|
||||
**/
|
||||
GFileIOStream *
|
||||
g_file_replace_readwrite (GFile *file,
|
||||
const char *etag,
|
||||
gboolean make_backup,
|
||||
GFileCreateFlags flags,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
GFileIface *iface;
|
||||
|
||||
g_return_val_if_fail (G_IS_FILE (file), NULL);
|
||||
|
||||
if (g_cancellable_set_error_if_cancelled (cancellable, error))
|
||||
return NULL;
|
||||
|
||||
iface = G_FILE_GET_IFACE (file);
|
||||
|
||||
if (iface->replace_readwrite == NULL)
|
||||
{
|
||||
g_set_error_literal (error, G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_SUPPORTED,
|
||||
_("Operation not supported"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (* iface->replace_readwrite) (file, etag, make_backup, flags, cancellable, error);
|
||||
}
|
||||
|
||||
/**
|
||||
* g_file_read_async:
|
||||
* @file: input #GFile.
|
||||
@ -1925,6 +2126,242 @@ g_file_replace_finish (GFile *file,
|
||||
return (* iface->replace_finish) (file, res, error);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* g_file_open_readwrite_async:
|
||||
* @file: input #GFile.
|
||||
* @io_priority: the <link linkend="io-priority">I/O priority</link>
|
||||
* of the request.
|
||||
* @cancellable: optional #GCancellable object, %NULL to ignore.
|
||||
* @callback: a #GAsyncReadyCallback to call when the request is satisfied
|
||||
* @user_data: the data to pass to callback function
|
||||
*
|
||||
* Asynchronously opens @file for reading and writing.
|
||||
*
|
||||
* For more details, see g_file_open_readwrite() which is
|
||||
* the synchronous version of this call.
|
||||
*
|
||||
* When the operation is finished, @callback will be called. You can then call
|
||||
* g_file_open_readwrite_finish() to get the result of the operation.
|
||||
*
|
||||
* Since: 2.22
|
||||
**/
|
||||
void
|
||||
g_file_open_readwrite_async (GFile *file,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GFileIface *iface;
|
||||
|
||||
g_return_if_fail (G_IS_FILE (file));
|
||||
|
||||
iface = G_FILE_GET_IFACE (file);
|
||||
(* iface->open_readwrite_async) (file,
|
||||
io_priority,
|
||||
cancellable,
|
||||
callback,
|
||||
user_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* g_file_open_readwrite_finish:
|
||||
* @file: input #GFile.
|
||||
* @res: a #GAsyncResult.
|
||||
* @error: a #GError, or %NULL
|
||||
*
|
||||
* Finishes an asynchronous file read operation started with
|
||||
* g_file_open_readwrite_async().
|
||||
*
|
||||
* Returns: a #GFileIOStream or %NULL on error.
|
||||
* Free the returned object with g_object_unref().
|
||||
*
|
||||
* Since: 2.22
|
||||
**/
|
||||
GFileIOStream *
|
||||
g_file_open_readwrite_finish (GFile *file,
|
||||
GAsyncResult *res,
|
||||
GError **error)
|
||||
{
|
||||
GFileIface *iface;
|
||||
|
||||
g_return_val_if_fail (G_IS_FILE (file), NULL);
|
||||
g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
|
||||
|
||||
if (G_IS_SIMPLE_ASYNC_RESULT (res))
|
||||
{
|
||||
GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
|
||||
if (g_simple_async_result_propagate_error (simple, error))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
iface = G_FILE_GET_IFACE (file);
|
||||
return (* iface->open_readwrite_finish) (file, res, error);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* g_file_create_readwrite_async:
|
||||
* @file: input #GFile.
|
||||
* @flags: a set of #GFileCreateFlags.
|
||||
* @io_priority: the <link linkend="io-priority">I/O priority</link>
|
||||
* of the request.
|
||||
* @cancellable: optional #GCancellable object, %NULL to ignore.
|
||||
* @callback: a #GAsyncReadyCallback to call when the request is satisfied
|
||||
* @user_data: the data to pass to callback function
|
||||
*
|
||||
* Asynchronously creates a new file and returns a stream for reading and writing
|
||||
* to it. The file must not already exist.
|
||||
*
|
||||
* For more details, see g_file_create_readwrite() which is
|
||||
* the synchronous version of this call.
|
||||
*
|
||||
* When the operation is finished, @callback will be called. You can then call
|
||||
* g_file_create_readwrite_finish() to get the result of the operation.
|
||||
*
|
||||
* Since: 2.22
|
||||
**/
|
||||
void
|
||||
g_file_create_readwrite_async (GFile *file,
|
||||
GFileCreateFlags flags,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GFileIface *iface;
|
||||
|
||||
g_return_if_fail (G_IS_FILE (file));
|
||||
|
||||
iface = G_FILE_GET_IFACE (file);
|
||||
(* iface->create_readwrite_async) (file,
|
||||
flags,
|
||||
io_priority,
|
||||
cancellable,
|
||||
callback,
|
||||
user_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* g_file_create_readwrite_finish:
|
||||
* @file: input #GFile.
|
||||
* @res: a #GAsyncResult.
|
||||
* @error: a #GError, or %NULL
|
||||
*
|
||||
* Finishes an asynchronous file create operation started with
|
||||
* g_file_create_readwrite_async().
|
||||
*
|
||||
* Returns: a #GFileIOStream or %NULL on error.
|
||||
* Free the returned object with g_object_unref().
|
||||
*
|
||||
* Since: 2.22
|
||||
**/
|
||||
GFileIOStream *
|
||||
g_file_create_readwrite_finish (GFile *file,
|
||||
GAsyncResult *res,
|
||||
GError **error)
|
||||
{
|
||||
GFileIface *iface;
|
||||
|
||||
g_return_val_if_fail (G_IS_FILE (file), NULL);
|
||||
g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
|
||||
|
||||
if (G_IS_SIMPLE_ASYNC_RESULT (res))
|
||||
{
|
||||
GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
|
||||
if (g_simple_async_result_propagate_error (simple, error))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
iface = G_FILE_GET_IFACE (file);
|
||||
return (* iface->create_readwrite_finish) (file, res, error);
|
||||
}
|
||||
|
||||
/**
|
||||
* g_file_replace_readwrite_async:
|
||||
* @file: input #GFile.
|
||||
* @etag: an <link linkend="gfile-etag">entity tag</link> for the
|
||||
* current #GFile, or NULL to ignore.
|
||||
* @make_backup: %TRUE if a backup should be created.
|
||||
* @flags: a set of #GFileCreateFlags.
|
||||
* @io_priority: the <link linkend="io-priority">I/O priority</link>
|
||||
* of the request.
|
||||
* @cancellable: optional #GCancellable object, %NULL to ignore.
|
||||
* @callback: a #GAsyncReadyCallback to call when the request is satisfied
|
||||
* @user_data: the data to pass to callback function
|
||||
*
|
||||
* Asynchronously overwrites the file in read-write mode, replacing the contents,
|
||||
* possibly creating a backup copy of the file first.
|
||||
*
|
||||
* For more details, see g_file_replace_readwrite() which is
|
||||
* the synchronous version of this call.
|
||||
*
|
||||
* When the operation is finished, @callback will be called. You can then call
|
||||
* g_file_replace_readwrite_finish() to get the result of the operation.
|
||||
*
|
||||
* Since: 2.22
|
||||
**/
|
||||
void
|
||||
g_file_replace_readwrite_async (GFile *file,
|
||||
const char *etag,
|
||||
gboolean make_backup,
|
||||
GFileCreateFlags flags,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GFileIface *iface;
|
||||
|
||||
g_return_if_fail (G_IS_FILE (file));
|
||||
|
||||
iface = G_FILE_GET_IFACE (file);
|
||||
(* iface->replace_readwrite_async) (file,
|
||||
etag,
|
||||
make_backup,
|
||||
flags,
|
||||
io_priority,
|
||||
cancellable,
|
||||
callback,
|
||||
user_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* g_file_replace_readwrite_finish:
|
||||
* @file: input #GFile.
|
||||
* @res: a #GAsyncResult.
|
||||
* @error: a #GError, or %NULL
|
||||
*
|
||||
* Finishes an asynchronous file replace operation started with
|
||||
* g_file_replace_readwrite_async().
|
||||
*
|
||||
* Returns: a #GFileIOStream, or %NULL on error.
|
||||
* Free the returned object with g_object_unref().
|
||||
*
|
||||
* Since: 2.22
|
||||
**/
|
||||
GFileIOStream *
|
||||
g_file_replace_readwrite_finish (GFile *file,
|
||||
GAsyncResult *res,
|
||||
GError **error)
|
||||
{
|
||||
GFileIface *iface;
|
||||
|
||||
g_return_val_if_fail (G_IS_FILE (file), NULL);
|
||||
g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
|
||||
|
||||
if (G_IS_SIMPLE_ASYNC_RESULT (res))
|
||||
{
|
||||
GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
|
||||
if (g_simple_async_result_propagate_error (simple, error))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
iface = G_FILE_GET_IFACE (file);
|
||||
return (* iface->replace_readwrite_finish) (file, res, error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
copy_symlink (GFile *destination,
|
||||
GFileCopyFlags flags,
|
||||
@ -4505,6 +4942,235 @@ g_file_real_replace_finish (GFile *file,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
open_readwrite_async_thread (GSimpleAsyncResult *res,
|
||||
GObject *object,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
GFileIface *iface;
|
||||
GFileIOStream *stream;
|
||||
GError *error = NULL;
|
||||
|
||||
iface = G_FILE_GET_IFACE (object);
|
||||
|
||||
if (iface->open_readwrite == NULL)
|
||||
{
|
||||
g_set_error_literal (&error, G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_SUPPORTED,
|
||||
_("Operation not supported"));
|
||||
|
||||
g_simple_async_result_set_from_error (res, error);
|
||||
g_error_free (error);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
stream = iface->open_readwrite (G_FILE (object), cancellable, &error);
|
||||
|
||||
if (stream == NULL)
|
||||
{
|
||||
g_simple_async_result_set_from_error (res, error);
|
||||
g_error_free (error);
|
||||
}
|
||||
else
|
||||
g_simple_async_result_set_op_res_gpointer (res, stream, g_object_unref);
|
||||
}
|
||||
|
||||
static void
|
||||
g_file_real_open_readwrite_async (GFile *file,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GSimpleAsyncResult *res;
|
||||
|
||||
res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_open_readwrite_async);
|
||||
|
||||
g_simple_async_result_run_in_thread (res, open_readwrite_async_thread, io_priority, cancellable);
|
||||
g_object_unref (res);
|
||||
}
|
||||
|
||||
static GFileIOStream *
|
||||
g_file_real_open_readwrite_finish (GFile *file,
|
||||
GAsyncResult *res,
|
||||
GError **error)
|
||||
{
|
||||
GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
|
||||
gpointer op;
|
||||
|
||||
g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_open_readwrite_async);
|
||||
|
||||
op = g_simple_async_result_get_op_res_gpointer (simple);
|
||||
if (op)
|
||||
return g_object_ref (op);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
create_readwrite_async_thread (GSimpleAsyncResult *res,
|
||||
GObject *object,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
GFileIface *iface;
|
||||
GFileCreateFlags *data;
|
||||
GFileIOStream *stream;
|
||||
GError *error = NULL;
|
||||
|
||||
iface = G_FILE_GET_IFACE (object);
|
||||
|
||||
data = g_simple_async_result_get_op_res_gpointer (res);
|
||||
|
||||
if (iface->create_readwrite == NULL)
|
||||
{
|
||||
g_set_error_literal (&error, G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_SUPPORTED,
|
||||
_("Operation not supported"));
|
||||
|
||||
g_simple_async_result_set_from_error (res, error);
|
||||
g_error_free (error);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
stream = iface->create_readwrite (G_FILE (object), *data, cancellable, &error);
|
||||
|
||||
if (stream == NULL)
|
||||
{
|
||||
g_simple_async_result_set_from_error (res, error);
|
||||
g_error_free (error);
|
||||
}
|
||||
else
|
||||
g_simple_async_result_set_op_res_gpointer (res, stream, g_object_unref);
|
||||
}
|
||||
|
||||
static void
|
||||
g_file_real_create_readwrite_async (GFile *file,
|
||||
GFileCreateFlags flags,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GFileCreateFlags *data;
|
||||
GSimpleAsyncResult *res;
|
||||
|
||||
data = g_new0 (GFileCreateFlags, 1);
|
||||
*data = flags;
|
||||
|
||||
res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_create_readwrite_async);
|
||||
g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)g_free);
|
||||
|
||||
g_simple_async_result_run_in_thread (res, create_readwrite_async_thread, io_priority, cancellable);
|
||||
g_object_unref (res);
|
||||
}
|
||||
|
||||
static GFileIOStream *
|
||||
g_file_real_create_readwrite_finish (GFile *file,
|
||||
GAsyncResult *res,
|
||||
GError **error)
|
||||
{
|
||||
GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
|
||||
gpointer op;
|
||||
|
||||
g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_create_readwrite_async);
|
||||
|
||||
op = g_simple_async_result_get_op_res_gpointer (simple);
|
||||
if (op)
|
||||
return g_object_ref (op);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
GFileIOStream *stream;
|
||||
char *etag;
|
||||
gboolean make_backup;
|
||||
GFileCreateFlags flags;
|
||||
} ReplaceRWAsyncData;
|
||||
|
||||
static void
|
||||
replace_rw_async_data_free (ReplaceRWAsyncData *data)
|
||||
{
|
||||
if (data->stream)
|
||||
g_object_unref (data->stream);
|
||||
g_free (data->etag);
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
static void
|
||||
replace_readwrite_async_thread (GSimpleAsyncResult *res,
|
||||
GObject *object,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
GFileIface *iface;
|
||||
GFileIOStream *stream;
|
||||
GError *error = NULL;
|
||||
ReplaceRWAsyncData *data;
|
||||
|
||||
iface = G_FILE_GET_IFACE (object);
|
||||
|
||||
data = g_simple_async_result_get_op_res_gpointer (res);
|
||||
|
||||
stream = iface->replace_readwrite (G_FILE (object),
|
||||
data->etag,
|
||||
data->make_backup,
|
||||
data->flags,
|
||||
cancellable,
|
||||
&error);
|
||||
|
||||
if (stream == NULL)
|
||||
{
|
||||
g_simple_async_result_set_from_error (res, error);
|
||||
g_error_free (error);
|
||||
}
|
||||
else
|
||||
data->stream = stream;
|
||||
}
|
||||
|
||||
static void
|
||||
g_file_real_replace_readwrite_async (GFile *file,
|
||||
const char *etag,
|
||||
gboolean make_backup,
|
||||
GFileCreateFlags flags,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GSimpleAsyncResult *res;
|
||||
ReplaceRWAsyncData *data;
|
||||
|
||||
data = g_new0 (ReplaceRWAsyncData, 1);
|
||||
data->etag = g_strdup (etag);
|
||||
data->make_backup = make_backup;
|
||||
data->flags = flags;
|
||||
|
||||
res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_replace_readwrite_async);
|
||||
g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)replace_rw_async_data_free);
|
||||
|
||||
g_simple_async_result_run_in_thread (res, replace_readwrite_async_thread, io_priority, cancellable);
|
||||
g_object_unref (res);
|
||||
}
|
||||
|
||||
static GFileIOStream *
|
||||
g_file_real_replace_readwrite_finish (GFile *file,
|
||||
GAsyncResult *res,
|
||||
GError **error)
|
||||
{
|
||||
GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
|
||||
ReplaceRWAsyncData *data;
|
||||
|
||||
g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_replace_readwrite_async);
|
||||
|
||||
data = g_simple_async_result_get_op_res_gpointer (simple);
|
||||
if (data->stream)
|
||||
return g_object_ref (data->stream);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
GFile *file;
|
||||
|
83
gio/gfile.h
83
gio/gfile.h
@ -431,6 +431,48 @@ struct _GFileIface
|
||||
GFileMonitorFlags flags,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
GFileIOStream * (* open_readwrite) (GFile *file,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
void (* open_readwrite_async) (GFile *file,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
GFileIOStream * (* open_readwrite_finish) (GFile *file,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
GFileIOStream * (* create_readwrite) (GFile *file,
|
||||
GFileCreateFlags flags,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
void (* create_readwrite_async) (GFile *file,
|
||||
GFileCreateFlags flags,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
GFileIOStream * (* create_readwrite_finish) (GFile *file,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
GFileIOStream * (* replace_readwrite) (GFile *file,
|
||||
const char *etag,
|
||||
gboolean make_backup,
|
||||
GFileCreateFlags flags,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
void (* replace_readwrite_async) (GFile *file,
|
||||
const char *etag,
|
||||
gboolean make_backup,
|
||||
GFileCreateFlags flags,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
GFileIOStream * (* replace_readwrite_finish) (GFile *file,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
};
|
||||
|
||||
GType g_file_get_type (void) G_GNUC_CONST;
|
||||
@ -517,6 +559,47 @@ void g_file_replace_async (GFile
|
||||
GFileOutputStream * g_file_replace_finish (GFile *file,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
GFileIOStream * g_file_open_readwrite (GFile *file,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
void g_file_open_readwrite_async (GFile *file,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
GFileIOStream * g_file_open_readwrite_finish (GFile *file,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
GFileIOStream * g_file_create_readwrite (GFile *file,
|
||||
GFileCreateFlags flags,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
void g_file_create_readwrite_async (GFile *file,
|
||||
GFileCreateFlags flags,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
GFileIOStream * g_file_create_readwrite_finish (GFile *file,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
GFileIOStream * g_file_replace_readwrite (GFile *file,
|
||||
const char *etag,
|
||||
gboolean make_backup,
|
||||
GFileCreateFlags flags,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
void g_file_replace_readwrite_async (GFile *file,
|
||||
const char *etag,
|
||||
gboolean make_backup,
|
||||
GFileCreateFlags flags,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
GFileIOStream * g_file_replace_readwrite_finish (GFile *file,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
gboolean g_file_query_exists (GFile *file,
|
||||
GCancellable *cancellable);
|
||||
GFileType g_file_query_file_type (GFile *file,
|
||||
|
Loading…
Reference in New Issue
Block a user