Made new read-entire-file call with sync. and async. versions since Andy

* libnautilus-extensions/nautilus-file-utilities.h:
	* libnautilus-extensions/nautilus-file-utilities.c:
	(nautilus_read_entire_file), (read_entire_file_close_callback),
	(read_entire_file_close), (read_entire_file_succeeded),
	(read_entire_file_failed), (read_entire_file_read_callback),
	(read_entire_file_read_chunk), (read_entire_file_open_callback),
	(nautilus_read_entire_file_async),
	(nautilus_read_entire_file_cancel): Made new read-entire-file call
	with sync. and async. versions since Andy needs it.

	* libnautilus-extensions/nautilus-directory-private.h:
	* libnautilus-extensions/nautilus-directory-async.c:
	(cancel_metafile_read), (metafile_read_done),
	(metafile_read_failed), (metafile_read_done_callback),
	(metafile_read_start), (nautilus_directory_request_read_metafile):
	* libnautilus-extensions/nautilus-directory.c:
	(nautilus_directory_destroy):
	Changed the metafile reading to use the new stuff.

	* components/services/install/command-line/.cvsignore:
	* components/services/install/server/.cvsignore:
	Ignore a few new generated files.
This commit is contained in:
Darin Adler 2000-06-21 23:20:08 +00:00
parent 466253010c
commit 165d633bcd
13 changed files with 603 additions and 279 deletions

View file

@ -1,3 +1,28 @@
2000-06-21 Darin Adler <darin@eazel.com>
* libnautilus-extensions/nautilus-file-utilities.h:
* libnautilus-extensions/nautilus-file-utilities.c:
(nautilus_read_entire_file), (read_entire_file_close_callback),
(read_entire_file_close), (read_entire_file_succeeded),
(read_entire_file_failed), (read_entire_file_read_callback),
(read_entire_file_read_chunk), (read_entire_file_open_callback),
(nautilus_read_entire_file_async),
(nautilus_read_entire_file_cancel): Made new read-entire-file call
with sync. and async. versions since Andy needs it.
* libnautilus-extensions/nautilus-directory-private.h:
* libnautilus-extensions/nautilus-directory-async.c:
(cancel_metafile_read), (metafile_read_done),
(metafile_read_failed), (metafile_read_done_callback),
(metafile_read_start), (nautilus_directory_request_read_metafile):
* libnautilus-extensions/nautilus-directory.c:
(nautilus_directory_destroy):
Changed the metafile reading to use the new stuff.
* components/services/install/command-line/.cvsignore:
* components/services/install/server/.cvsignore:
Ignore a few new generated files.
2000-06-21 Eskil Heyn Olsen <eskil@eazel.com>
* components/services/install/lib/Makefile.am:
@ -11,9 +36,7 @@
2000-06-21 Eskil Heyn Olsen <eskil@eazel.com>
* components/services/install/server/main.c:
(trilobite_service_factory_destroy),
Forgot this, better commit it before Ramiro kills me.
(eazel_install_service_factory), (main):
* components/services/trilobite/sample/command-line/main.c: (main):
Darins patch reg. unref.
@ -31,8 +54,7 @@
Added the server directory.
* components/services/install/command-line/Makefile.am:
*
components/services/install/command-line/eazel-alt-install-corba.c:
* components/services/install/command-line/eazel-alt-install-corba.c:
(set_parameters_from_command_line),
(eazel_download_progress_signal), (eazel_install_progress_signal),
(download_failed), (install_failed), (dep_check), (create_package),
@ -121,13 +143,9 @@
* components/services/install/lib/eazel-install-types.c:
(rpmfilename_from_packagedata):
* components/services/install/lib/eazel-install-types.h:
*
components/services/install/lib/trilobite-eazel-install-service.oaf
info:
* components/services/install/lib/trilobite-eazel-install-service.oafinfo:
* components/services/install/server/Makefile.am:
*
components/services/install/server/trilobite-eazel-install-service.
oafinfo:
* components/services/install/server/trilobite-eazel-install-service.oafinfo:
Added a load of stuff to make the install service a corba
service. There are corba/c converters in
eazel-install-corba-types, moved a load of the corba magic into
@ -140,13 +158,9 @@
(trilobite_eazel_time_service_initialize):
Changed the default url to the new testmachine.
*
components/services/trilobite/libtrilobite/trilobite-core-distribut
ion.c: (trilobite_get_distribution_name),
(trilobite_get_distribution_enum):
*
components/services/trilobite/libtrilobite/trilobite-core-distribut
ion.h:
* components/services/trilobite/libtrilobite/trilobite-core-distribution.c:
(trilobite_get_distribution_name), (trilobite_get_distribution_enum):
* components/services/trilobite/libtrilobite/trilobite-core-distribution.h:
Added call to get the distro enum from the generated string. Used
for the corbafication of libinstall.

View file

@ -1,6 +1,5 @@
Makefile
Makefile.in
.deps
.libs
eazel-install
eazel-alt-install
Makefile
Makefile.in
eazel-alt-install-corba

View file

@ -0,0 +1,5 @@
.deps
.libs
Makefile
Makefile.in
trilobite-eazel-install-service

View file

@ -49,13 +49,6 @@
#define METAFILE_READ_CHUNK_SIZE (4 * 1024)
#define TOP_LEFT_TEXT_READ_CHUNK_SIZE (4 * 1024)
struct MetafileReadState {
GnomeVFSAsyncHandle *handle;
gboolean is_open;
char *buffer;
int bytes_read;
};
struct MetafileWriteState {
GnomeVFSAsyncHandle *handle;
xmlChar *buffer;
@ -101,7 +94,6 @@ typedef gboolean (* RequestCheck) (const Request *);
typedef gboolean (* FileCheck) (NautilusFile *);
/* Forward declarations for functions that need them. */
static void metafile_read_some (NautilusDirectory *directory);
static void metafile_read_start (NautilusDirectory *directory);
static gboolean request_is_satisfied (NautilusDirectory *directory,
NautilusFile *file,
@ -120,19 +112,6 @@ empty_close_callback (GnomeVFSAsyncHandle *handle,
/* Do nothing. */
}
static void
metafile_read_close (NautilusDirectory *directory)
{
g_assert (directory->details->metafile_read_state->handle != NULL);
if (directory->details->metafile_read_state->is_open) {
gnome_vfs_async_close (directory->details->metafile_read_state->handle,
empty_close_callback,
directory);
directory->details->metafile_read_state->is_open = FALSE;
}
directory->details->metafile_read_state->handle = NULL;
}
static void
cancel_directory_counts (NautilusDirectory *directory)
{
@ -181,12 +160,9 @@ cancel_get_info (NautilusDirectory *directory)
static void
cancel_metafile_read (NautilusDirectory *directory)
{
if (directory->details->metafile_read_state != NULL) {
g_assert (directory->details->metafile_read_state->handle != NULL);
gnome_vfs_async_cancel (directory->details->metafile_read_state->handle);
metafile_read_close (directory);
g_free (directory->details->metafile_read_state);
directory->details->metafile_read_state = NULL;
if (directory->details->metafile_read_handle != NULL) {
nautilus_read_entire_file_cancel (directory->details->metafile_read_handle);
directory->details->metafile_read_handle = NULL;
}
}
@ -202,13 +178,10 @@ nautilus_directory_cancel (NautilusDirectory *directory)
static void
metafile_read_done (NautilusDirectory *directory)
{
g_assert (directory->details->metafile_read_state != NULL);
g_assert (directory->details->metafile_read_state->is_open == FALSE);
g_free (directory->details->metafile_read_state);
g_assert (directory->details->metafile_read_handle != NULL);
directory->details->metafile_read = TRUE;
directory->details->metafile_read_state = NULL;
directory->details->metafile_read_handle = NULL;
/* Move over the changes to the metafile that were in the hash table. */
nautilus_directory_metafile_apply_pending_changes (directory);
@ -225,15 +198,8 @@ metafile_read_failed (NautilusDirectory *directory)
{
g_assert (NAUTILUS_IS_DIRECTORY (directory));
g_assert (directory->details->metafile == NULL);
g_assert (directory->details->metafile_read_state != NULL);
g_assert (directory->details->metafile_read_state->is_open == FALSE);
g_free (directory->details->metafile_read_state->buffer);
if (directory->details->use_alternate_metafile) {
directory->details->metafile_read_state->buffer = NULL;
directory->details->metafile_read_state->bytes_read = 0;
directory->details->use_alternate_metafile = FALSE;
metafile_read_start (directory);
return;
@ -243,19 +209,33 @@ metafile_read_failed (NautilusDirectory *directory)
}
static void
metafile_read_complete (NautilusDirectory *directory)
metafile_read_done_callback (GnomeVFSResult result,
GnomeVFSFileSize file_size,
char *file_contents,
gpointer callback_data)
{
char *buffer;
NautilusDirectory *directory;
int size;
char *buffer;
g_assert (NAUTILUS_IS_DIRECTORY (directory));
directory = NAUTILUS_DIRECTORY (callback_data);
g_assert (directory->details->metafile == NULL);
g_assert (directory->details->metafile_read_state != NULL);
g_assert (directory->details->metafile_read_state->is_open == FALSE);
if (result != GNOME_VFS_OK) {
g_assert (file_contents == NULL);
metafile_read_failed (directory);
return;
}
size = file_size;
if ((GnomeVFSFileSize) size != file_size) {
g_free (file_contents);
metafile_read_failed (directory);
return;
}
/* The gnome-xml parser requires a zero-terminated array. */
size = directory->details->metafile_read_state->bytes_read;
buffer = g_realloc (directory->details->metafile_read_state->buffer, size + 1);
buffer = g_realloc (file_contents, size + 1);
buffer[size] = '\0';
directory->details->metafile = xmlParseMemory (buffer, size);
g_free (buffer);
@ -263,86 +243,23 @@ metafile_read_complete (NautilusDirectory *directory)
metafile_read_done (directory);
}
static void
metafile_read_callback (GnomeVFSAsyncHandle *handle,
GnomeVFSResult result,
gpointer buffer,
GnomeVFSFileSize bytes_requested,
GnomeVFSFileSize bytes_read,
gpointer callback_data)
{
NautilusDirectory *directory;
g_assert (bytes_requested == METAFILE_READ_CHUNK_SIZE);
directory = NAUTILUS_DIRECTORY (callback_data);
g_assert (directory->details->metafile_read_state->handle == handle);
g_assert (directory->details->metafile_read_state->buffer
+ directory->details->metafile_read_state->bytes_read == buffer);
if (result != GNOME_VFS_OK && result != GNOME_VFS_ERROR_EOF) {
metafile_read_close (directory);
metafile_read_failed (directory);
return;
}
directory->details->metafile_read_state->bytes_read += bytes_read;
if (bytes_read != 0 && result == GNOME_VFS_OK) {
metafile_read_some (directory);
return;
}
metafile_read_close (directory);
metafile_read_complete (directory);
}
static void
metafile_read_some (NautilusDirectory *directory)
{
directory->details->metafile_read_state->buffer = g_realloc
(directory->details->metafile_read_state->buffer,
directory->details->metafile_read_state->bytes_read + METAFILE_READ_CHUNK_SIZE);
gnome_vfs_async_read (directory->details->metafile_read_state->handle,
directory->details->metafile_read_state->buffer
+ directory->details->metafile_read_state->bytes_read,
METAFILE_READ_CHUNK_SIZE,
metafile_read_callback,
directory);
}
static void
metafile_read_open_callback (GnomeVFSAsyncHandle *handle,
GnomeVFSResult result,
gpointer callback_data)
{
NautilusDirectory *directory;
directory = NAUTILUS_DIRECTORY (callback_data);
g_assert (directory->details->metafile_read_state->handle == handle);
if (result != GNOME_VFS_OK) {
metafile_read_failed (directory);
return;
}
directory->details->metafile_read_state->is_open = TRUE;
metafile_read_some (directory);
}
static void
metafile_read_start (NautilusDirectory *directory)
{
char *text_uri;
g_assert (NAUTILUS_IS_DIRECTORY (directory));
gnome_vfs_async_open_uri (&directory->details->metafile_read_state->handle,
directory->details->use_alternate_metafile
? directory->details->alternate_metafile_uri
: directory->details->metafile_uri,
GNOME_VFS_OPEN_READ,
metafile_read_open_callback,
directory);
text_uri = gnome_vfs_uri_to_string
(directory->details->use_alternate_metafile
? directory->details->alternate_metafile_uri
: directory->details->metafile_uri,
GNOME_VFS_URI_HIDE_NONE);
directory->details->metafile_read_handle = nautilus_read_entire_file_async
(text_uri, metafile_read_done_callback, directory);
g_free (text_uri);
}
void
@ -358,13 +275,12 @@ nautilus_directory_request_read_metafile (NautilusDirectory *directory)
}
if (directory->details->metafile_read
|| directory->details->metafile_read_state != NULL) {
|| directory->details->metafile_read_handle != NULL) {
return;
}
g_assert (directory->details->metafile == NULL);
directory->details->metafile_read_state = g_new0 (MetafileReadState, 1);
directory->details->use_alternate_metafile = TRUE;
metafile_read_start (directory);
}

View file

@ -31,8 +31,8 @@
#include <tree.h>
#include "nautilus-file.h"
#include "nautilus-file-utilities.h"
typedef struct MetafileReadState MetafileReadState;
typedef struct MetafileWriteState MetafileWriteState;
typedef struct TopLeftTextReadState TopLeftTextReadState;
@ -54,7 +54,7 @@ struct NautilusDirectoryDetails
/* State for reading and writing metadata. */
gboolean use_alternate_metafile;
MetafileReadState *metafile_read_state;
NautilusReadFileHandle *metafile_read_handle;
guint write_metafile_idle_id;
MetafileWriteState *metafile_write_state;

View file

@ -147,7 +147,7 @@ nautilus_directory_destroy (GtkObject *object)
g_assert (directory->details->metafile_write_state == NULL);
nautilus_directory_cancel (directory);
g_assert (directory->details->metafile_read_state == NULL);
g_assert (directory->details->metafile_read_handle == NULL);
g_assert (directory->details->count_in_progress == NULL);
g_assert (directory->details->top_left_read_state == NULL);

View file

@ -33,10 +33,10 @@
#include "nautilus-file.h"
#include "nautilus-link-set.h"
#include "nautilus-metadata.h"
#include "nautilus-string.h"
#include <libgnomevfs/gnome-vfs-utils.h>
#include <libgnomevfs/gnome-vfs-ops.h>
#include <libgnomevfs/gnome-vfs-async-ops.h>
#define NAUTILUS_USER_DIRECTORY_NAME ".nautilus"
#define DEFAULT_NAUTILUS_DIRECTORY_MODE (0755)
@ -48,6 +48,19 @@
#define DEFAULT_SCHEME "file://"
#define READ_CHUNK_SIZE 8192
struct NautilusReadFileHandle {
GnomeVFSAsyncHandle *handle;
NautilusReadFileCallback callback;
gpointer callback_data;
gboolean is_open;
char *buffer;
int bytes_read;
};
static void read_entire_file_read_chunk (NautilusReadFileHandle *handle);
/**
* nautilus_format_uri_for_display:
*
@ -356,3 +369,224 @@ nautilus_pixmap_file (const char *partial_path)
return NULL;
}
}
GnomeVFSResult
nautilus_read_entire_file (const char *uri,
int *file_size,
char **file_contents)
{
GnomeVFSResult result;
GnomeVFSHandle *handle;
char *buffer;
int total_bytes_read;
GnomeVFSFileSize bytes_read;
*file_size = 0;
*file_contents = NULL;
/* Open the file. */
result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
if (result != GNOME_VFS_OK) {
return result;
}
/* Read the whole thing. */
buffer = NULL;
total_bytes_read = 0;
do {
buffer = g_realloc (buffer, total_bytes_read + READ_CHUNK_SIZE);
result = gnome_vfs_read (handle,
buffer + total_bytes_read,
READ_CHUNK_SIZE,
&bytes_read);
if (result != GNOME_VFS_OK && result != GNOME_VFS_ERROR_EOF) {
g_free (buffer);
return result;
}
/* Check for overflow. */
if (total_bytes_read + bytes_read < total_bytes_read) {
g_free (buffer);
return GNOME_VFS_ERROR_TOO_BIG;
}
total_bytes_read += bytes_read;
} while (result == GNOME_VFS_OK);
/* Close the file. */
result = gnome_vfs_close (handle);
if (result != GNOME_VFS_OK) {
g_free (buffer);
return result;
}
/* Return the file. */
*file_size = total_bytes_read;
*file_contents = g_realloc (buffer, total_bytes_read);
return GNOME_VFS_OK;
}
/* When close is complete, there's no more work to do. */
static void
read_entire_file_close_callback (GnomeVFSAsyncHandle *handle,
GnomeVFSResult result,
gpointer callback_data)
{
if (result != GNOME_VFS_OK) {
g_warning ("close failed -- this should never happen");
}
}
/* Do a close if it's needed.
* Be sure to get this right, or we have extra threads hanging around.
*/
static void
read_entire_file_close (NautilusReadFileHandle *read_handle)
{
if (read_handle->is_open) {
gnome_vfs_async_close (read_handle->handle,
read_entire_file_close_callback,
NULL);
read_handle->is_open = FALSE;
}
}
/* Close the file and then tell the caller we succeeded, handing off
* the buffer to the caller.
*/
static void
read_entire_file_succeeded (NautilusReadFileHandle *read_handle)
{
read_entire_file_close (read_handle);
/* Reallocate the buffer to the exact size since it might be
* around for a while.
*/
(* read_handle->callback) (GNOME_VFS_OK,
read_handle->bytes_read,
g_realloc (read_handle->buffer,
read_handle->bytes_read),
read_handle->callback_data);
g_free (read_handle);
}
/* Tell the caller we failed. */
static void
read_entire_file_failed (NautilusReadFileHandle *read_handle, GnomeVFSResult result)
{
read_entire_file_close (read_handle);
g_free (read_handle->buffer);
(* read_handle->callback) (result, 0, NULL, read_handle->callback_data);
g_free (read_handle);
}
/* A read is complete, so we might or might not be done. */
static void
read_entire_file_read_callback (GnomeVFSAsyncHandle *handle,
GnomeVFSResult result,
gpointer buffer,
GnomeVFSFileSize bytes_requested,
GnomeVFSFileSize bytes_read,
gpointer callback_data)
{
NautilusReadFileHandle *read_handle;
/* Do a few reality checks. */
g_assert (bytes_requested == READ_CHUNK_SIZE);
read_handle = callback_data;
g_assert (read_handle->handle == handle);
g_assert (read_handle->buffer + read_handle->bytes_read == buffer);
g_assert (bytes_read <= bytes_requested);
/* Check for a failure. */
if (result != GNOME_VFS_OK && result != GNOME_VFS_ERROR_EOF) {
read_entire_file_failed (read_handle, result);
return;
}
/* Check for the extremely unlikely case where the file size overflows. */
if (read_handle->bytes_read + bytes_read < read_handle->bytes_read) {
read_entire_file_failed (read_handle, GNOME_VFS_ERROR_TOO_BIG);
return;
}
/* Bump the size. */
read_handle->bytes_read += bytes_read;
/* Read more unless we are at the end of the file. */
if (bytes_read != 0 && result == GNOME_VFS_OK) {
read_entire_file_read_chunk (read_handle);
return;
}
/* If at the end of the file, we win! */
read_entire_file_succeeded (read_handle);
}
/* Start reading a chunk. */
static void
read_entire_file_read_chunk (NautilusReadFileHandle *handle)
{
handle->buffer = g_realloc (handle->buffer, handle->bytes_read + READ_CHUNK_SIZE);
gnome_vfs_async_read (handle->handle,
handle->buffer + handle->bytes_read,
READ_CHUNK_SIZE,
read_entire_file_read_callback,
handle);
}
/* Once the open is finished, read a first chunk. */
static void
read_entire_file_open_callback (GnomeVFSAsyncHandle *handle,
GnomeVFSResult result,
gpointer callback_data)
{
NautilusReadFileHandle *read_handle;
read_handle = callback_data;
g_assert (read_handle->handle == handle);
/* Handle the failure case. */
if (result != GNOME_VFS_OK) {
read_entire_file_failed (read_handle, result);
return;
}
/* Handle success by reading the first chunk. */
read_handle->is_open = TRUE;
read_entire_file_read_chunk (read_handle);
}
/* Set up the read handle and start reading. */
NautilusReadFileHandle *
nautilus_read_entire_file_async (const char *uri,
NautilusReadFileCallback callback,
gpointer callback_data)
{
NautilusReadFileHandle *handle;
handle = g_new0 (NautilusReadFileHandle, 1);
handle->callback = callback;
handle->callback_data = callback_data;
gnome_vfs_async_open (&handle->handle,
uri,
GNOME_VFS_OPEN_READ,
read_entire_file_open_callback,
handle);
return handle;
}
/* Stop the presses! */
void
nautilus_read_entire_file_cancel (NautilusReadFileHandle *handle)
{
gnome_vfs_async_cancel (handle->handle);
read_entire_file_close (handle);
g_free (handle->buffer);
g_free (handle);
}

View file

@ -27,7 +27,10 @@
#include <libgnomevfs/gnome-vfs-types.h>
typedef void (* NautilusReadFileCallback) (int file_size, char *file_contents, gpointer callback_data);
typedef void (* NautilusReadFileCallback) (GnomeVFSResult result,
GnomeVFSFileSize file_size,
char *file_contents,
gpointer callback_data);
typedef struct NautilusReadFileHandle NautilusReadFileHandle;
char * nautilus_format_uri_for_display (const char *uri);

View file

@ -49,13 +49,6 @@
#define METAFILE_READ_CHUNK_SIZE (4 * 1024)
#define TOP_LEFT_TEXT_READ_CHUNK_SIZE (4 * 1024)
struct MetafileReadState {
GnomeVFSAsyncHandle *handle;
gboolean is_open;
char *buffer;
int bytes_read;
};
struct MetafileWriteState {
GnomeVFSAsyncHandle *handle;
xmlChar *buffer;
@ -101,7 +94,6 @@ typedef gboolean (* RequestCheck) (const Request *);
typedef gboolean (* FileCheck) (NautilusFile *);
/* Forward declarations for functions that need them. */
static void metafile_read_some (NautilusDirectory *directory);
static void metafile_read_start (NautilusDirectory *directory);
static gboolean request_is_satisfied (NautilusDirectory *directory,
NautilusFile *file,
@ -120,19 +112,6 @@ empty_close_callback (GnomeVFSAsyncHandle *handle,
/* Do nothing. */
}
static void
metafile_read_close (NautilusDirectory *directory)
{
g_assert (directory->details->metafile_read_state->handle != NULL);
if (directory->details->metafile_read_state->is_open) {
gnome_vfs_async_close (directory->details->metafile_read_state->handle,
empty_close_callback,
directory);
directory->details->metafile_read_state->is_open = FALSE;
}
directory->details->metafile_read_state->handle = NULL;
}
static void
cancel_directory_counts (NautilusDirectory *directory)
{
@ -181,12 +160,9 @@ cancel_get_info (NautilusDirectory *directory)
static void
cancel_metafile_read (NautilusDirectory *directory)
{
if (directory->details->metafile_read_state != NULL) {
g_assert (directory->details->metafile_read_state->handle != NULL);
gnome_vfs_async_cancel (directory->details->metafile_read_state->handle);
metafile_read_close (directory);
g_free (directory->details->metafile_read_state);
directory->details->metafile_read_state = NULL;
if (directory->details->metafile_read_handle != NULL) {
nautilus_read_entire_file_cancel (directory->details->metafile_read_handle);
directory->details->metafile_read_handle = NULL;
}
}
@ -202,13 +178,10 @@ nautilus_directory_cancel (NautilusDirectory *directory)
static void
metafile_read_done (NautilusDirectory *directory)
{
g_assert (directory->details->metafile_read_state != NULL);
g_assert (directory->details->metafile_read_state->is_open == FALSE);
g_free (directory->details->metafile_read_state);
g_assert (directory->details->metafile_read_handle != NULL);
directory->details->metafile_read = TRUE;
directory->details->metafile_read_state = NULL;
directory->details->metafile_read_handle = NULL;
/* Move over the changes to the metafile that were in the hash table. */
nautilus_directory_metafile_apply_pending_changes (directory);
@ -225,15 +198,8 @@ metafile_read_failed (NautilusDirectory *directory)
{
g_assert (NAUTILUS_IS_DIRECTORY (directory));
g_assert (directory->details->metafile == NULL);
g_assert (directory->details->metafile_read_state != NULL);
g_assert (directory->details->metafile_read_state->is_open == FALSE);
g_free (directory->details->metafile_read_state->buffer);
if (directory->details->use_alternate_metafile) {
directory->details->metafile_read_state->buffer = NULL;
directory->details->metafile_read_state->bytes_read = 0;
directory->details->use_alternate_metafile = FALSE;
metafile_read_start (directory);
return;
@ -243,19 +209,33 @@ metafile_read_failed (NautilusDirectory *directory)
}
static void
metafile_read_complete (NautilusDirectory *directory)
metafile_read_done_callback (GnomeVFSResult result,
GnomeVFSFileSize file_size,
char *file_contents,
gpointer callback_data)
{
char *buffer;
NautilusDirectory *directory;
int size;
char *buffer;
g_assert (NAUTILUS_IS_DIRECTORY (directory));
directory = NAUTILUS_DIRECTORY (callback_data);
g_assert (directory->details->metafile == NULL);
g_assert (directory->details->metafile_read_state != NULL);
g_assert (directory->details->metafile_read_state->is_open == FALSE);
if (result != GNOME_VFS_OK) {
g_assert (file_contents == NULL);
metafile_read_failed (directory);
return;
}
size = file_size;
if ((GnomeVFSFileSize) size != file_size) {
g_free (file_contents);
metafile_read_failed (directory);
return;
}
/* The gnome-xml parser requires a zero-terminated array. */
size = directory->details->metafile_read_state->bytes_read;
buffer = g_realloc (directory->details->metafile_read_state->buffer, size + 1);
buffer = g_realloc (file_contents, size + 1);
buffer[size] = '\0';
directory->details->metafile = xmlParseMemory (buffer, size);
g_free (buffer);
@ -263,86 +243,23 @@ metafile_read_complete (NautilusDirectory *directory)
metafile_read_done (directory);
}
static void
metafile_read_callback (GnomeVFSAsyncHandle *handle,
GnomeVFSResult result,
gpointer buffer,
GnomeVFSFileSize bytes_requested,
GnomeVFSFileSize bytes_read,
gpointer callback_data)
{
NautilusDirectory *directory;
g_assert (bytes_requested == METAFILE_READ_CHUNK_SIZE);
directory = NAUTILUS_DIRECTORY (callback_data);
g_assert (directory->details->metafile_read_state->handle == handle);
g_assert (directory->details->metafile_read_state->buffer
+ directory->details->metafile_read_state->bytes_read == buffer);
if (result != GNOME_VFS_OK && result != GNOME_VFS_ERROR_EOF) {
metafile_read_close (directory);
metafile_read_failed (directory);
return;
}
directory->details->metafile_read_state->bytes_read += bytes_read;
if (bytes_read != 0 && result == GNOME_VFS_OK) {
metafile_read_some (directory);
return;
}
metafile_read_close (directory);
metafile_read_complete (directory);
}
static void
metafile_read_some (NautilusDirectory *directory)
{
directory->details->metafile_read_state->buffer = g_realloc
(directory->details->metafile_read_state->buffer,
directory->details->metafile_read_state->bytes_read + METAFILE_READ_CHUNK_SIZE);
gnome_vfs_async_read (directory->details->metafile_read_state->handle,
directory->details->metafile_read_state->buffer
+ directory->details->metafile_read_state->bytes_read,
METAFILE_READ_CHUNK_SIZE,
metafile_read_callback,
directory);
}
static void
metafile_read_open_callback (GnomeVFSAsyncHandle *handle,
GnomeVFSResult result,
gpointer callback_data)
{
NautilusDirectory *directory;
directory = NAUTILUS_DIRECTORY (callback_data);
g_assert (directory->details->metafile_read_state->handle == handle);
if (result != GNOME_VFS_OK) {
metafile_read_failed (directory);
return;
}
directory->details->metafile_read_state->is_open = TRUE;
metafile_read_some (directory);
}
static void
metafile_read_start (NautilusDirectory *directory)
{
char *text_uri;
g_assert (NAUTILUS_IS_DIRECTORY (directory));
gnome_vfs_async_open_uri (&directory->details->metafile_read_state->handle,
directory->details->use_alternate_metafile
? directory->details->alternate_metafile_uri
: directory->details->metafile_uri,
GNOME_VFS_OPEN_READ,
metafile_read_open_callback,
directory);
text_uri = gnome_vfs_uri_to_string
(directory->details->use_alternate_metafile
? directory->details->alternate_metafile_uri
: directory->details->metafile_uri,
GNOME_VFS_URI_HIDE_NONE);
directory->details->metafile_read_handle = nautilus_read_entire_file_async
(text_uri, metafile_read_done_callback, directory);
g_free (text_uri);
}
void
@ -358,13 +275,12 @@ nautilus_directory_request_read_metafile (NautilusDirectory *directory)
}
if (directory->details->metafile_read
|| directory->details->metafile_read_state != NULL) {
|| directory->details->metafile_read_handle != NULL) {
return;
}
g_assert (directory->details->metafile == NULL);
directory->details->metafile_read_state = g_new0 (MetafileReadState, 1);
directory->details->use_alternate_metafile = TRUE;
metafile_read_start (directory);
}

View file

@ -31,8 +31,8 @@
#include <tree.h>
#include "nautilus-file.h"
#include "nautilus-file-utilities.h"
typedef struct MetafileReadState MetafileReadState;
typedef struct MetafileWriteState MetafileWriteState;
typedef struct TopLeftTextReadState TopLeftTextReadState;
@ -54,7 +54,7 @@ struct NautilusDirectoryDetails
/* State for reading and writing metadata. */
gboolean use_alternate_metafile;
MetafileReadState *metafile_read_state;
NautilusReadFileHandle *metafile_read_handle;
guint write_metafile_idle_id;
MetafileWriteState *metafile_write_state;

View file

@ -147,7 +147,7 @@ nautilus_directory_destroy (GtkObject *object)
g_assert (directory->details->metafile_write_state == NULL);
nautilus_directory_cancel (directory);
g_assert (directory->details->metafile_read_state == NULL);
g_assert (directory->details->metafile_read_handle == NULL);
g_assert (directory->details->count_in_progress == NULL);
g_assert (directory->details->top_left_read_state == NULL);

View file

@ -33,10 +33,10 @@
#include "nautilus-file.h"
#include "nautilus-link-set.h"
#include "nautilus-metadata.h"
#include "nautilus-string.h"
#include <libgnomevfs/gnome-vfs-utils.h>
#include <libgnomevfs/gnome-vfs-ops.h>
#include <libgnomevfs/gnome-vfs-async-ops.h>
#define NAUTILUS_USER_DIRECTORY_NAME ".nautilus"
#define DEFAULT_NAUTILUS_DIRECTORY_MODE (0755)
@ -48,6 +48,19 @@
#define DEFAULT_SCHEME "file://"
#define READ_CHUNK_SIZE 8192
struct NautilusReadFileHandle {
GnomeVFSAsyncHandle *handle;
NautilusReadFileCallback callback;
gpointer callback_data;
gboolean is_open;
char *buffer;
int bytes_read;
};
static void read_entire_file_read_chunk (NautilusReadFileHandle *handle);
/**
* nautilus_format_uri_for_display:
*
@ -356,3 +369,224 @@ nautilus_pixmap_file (const char *partial_path)
return NULL;
}
}
GnomeVFSResult
nautilus_read_entire_file (const char *uri,
int *file_size,
char **file_contents)
{
GnomeVFSResult result;
GnomeVFSHandle *handle;
char *buffer;
int total_bytes_read;
GnomeVFSFileSize bytes_read;
*file_size = 0;
*file_contents = NULL;
/* Open the file. */
result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
if (result != GNOME_VFS_OK) {
return result;
}
/* Read the whole thing. */
buffer = NULL;
total_bytes_read = 0;
do {
buffer = g_realloc (buffer, total_bytes_read + READ_CHUNK_SIZE);
result = gnome_vfs_read (handle,
buffer + total_bytes_read,
READ_CHUNK_SIZE,
&bytes_read);
if (result != GNOME_VFS_OK && result != GNOME_VFS_ERROR_EOF) {
g_free (buffer);
return result;
}
/* Check for overflow. */
if (total_bytes_read + bytes_read < total_bytes_read) {
g_free (buffer);
return GNOME_VFS_ERROR_TOO_BIG;
}
total_bytes_read += bytes_read;
} while (result == GNOME_VFS_OK);
/* Close the file. */
result = gnome_vfs_close (handle);
if (result != GNOME_VFS_OK) {
g_free (buffer);
return result;
}
/* Return the file. */
*file_size = total_bytes_read;
*file_contents = g_realloc (buffer, total_bytes_read);
return GNOME_VFS_OK;
}
/* When close is complete, there's no more work to do. */
static void
read_entire_file_close_callback (GnomeVFSAsyncHandle *handle,
GnomeVFSResult result,
gpointer callback_data)
{
if (result != GNOME_VFS_OK) {
g_warning ("close failed -- this should never happen");
}
}
/* Do a close if it's needed.
* Be sure to get this right, or we have extra threads hanging around.
*/
static void
read_entire_file_close (NautilusReadFileHandle *read_handle)
{
if (read_handle->is_open) {
gnome_vfs_async_close (read_handle->handle,
read_entire_file_close_callback,
NULL);
read_handle->is_open = FALSE;
}
}
/* Close the file and then tell the caller we succeeded, handing off
* the buffer to the caller.
*/
static void
read_entire_file_succeeded (NautilusReadFileHandle *read_handle)
{
read_entire_file_close (read_handle);
/* Reallocate the buffer to the exact size since it might be
* around for a while.
*/
(* read_handle->callback) (GNOME_VFS_OK,
read_handle->bytes_read,
g_realloc (read_handle->buffer,
read_handle->bytes_read),
read_handle->callback_data);
g_free (read_handle);
}
/* Tell the caller we failed. */
static void
read_entire_file_failed (NautilusReadFileHandle *read_handle, GnomeVFSResult result)
{
read_entire_file_close (read_handle);
g_free (read_handle->buffer);
(* read_handle->callback) (result, 0, NULL, read_handle->callback_data);
g_free (read_handle);
}
/* A read is complete, so we might or might not be done. */
static void
read_entire_file_read_callback (GnomeVFSAsyncHandle *handle,
GnomeVFSResult result,
gpointer buffer,
GnomeVFSFileSize bytes_requested,
GnomeVFSFileSize bytes_read,
gpointer callback_data)
{
NautilusReadFileHandle *read_handle;
/* Do a few reality checks. */
g_assert (bytes_requested == READ_CHUNK_SIZE);
read_handle = callback_data;
g_assert (read_handle->handle == handle);
g_assert (read_handle->buffer + read_handle->bytes_read == buffer);
g_assert (bytes_read <= bytes_requested);
/* Check for a failure. */
if (result != GNOME_VFS_OK && result != GNOME_VFS_ERROR_EOF) {
read_entire_file_failed (read_handle, result);
return;
}
/* Check for the extremely unlikely case where the file size overflows. */
if (read_handle->bytes_read + bytes_read < read_handle->bytes_read) {
read_entire_file_failed (read_handle, GNOME_VFS_ERROR_TOO_BIG);
return;
}
/* Bump the size. */
read_handle->bytes_read += bytes_read;
/* Read more unless we are at the end of the file. */
if (bytes_read != 0 && result == GNOME_VFS_OK) {
read_entire_file_read_chunk (read_handle);
return;
}
/* If at the end of the file, we win! */
read_entire_file_succeeded (read_handle);
}
/* Start reading a chunk. */
static void
read_entire_file_read_chunk (NautilusReadFileHandle *handle)
{
handle->buffer = g_realloc (handle->buffer, handle->bytes_read + READ_CHUNK_SIZE);
gnome_vfs_async_read (handle->handle,
handle->buffer + handle->bytes_read,
READ_CHUNK_SIZE,
read_entire_file_read_callback,
handle);
}
/* Once the open is finished, read a first chunk. */
static void
read_entire_file_open_callback (GnomeVFSAsyncHandle *handle,
GnomeVFSResult result,
gpointer callback_data)
{
NautilusReadFileHandle *read_handle;
read_handle = callback_data;
g_assert (read_handle->handle == handle);
/* Handle the failure case. */
if (result != GNOME_VFS_OK) {
read_entire_file_failed (read_handle, result);
return;
}
/* Handle success by reading the first chunk. */
read_handle->is_open = TRUE;
read_entire_file_read_chunk (read_handle);
}
/* Set up the read handle and start reading. */
NautilusReadFileHandle *
nautilus_read_entire_file_async (const char *uri,
NautilusReadFileCallback callback,
gpointer callback_data)
{
NautilusReadFileHandle *handle;
handle = g_new0 (NautilusReadFileHandle, 1);
handle->callback = callback;
handle->callback_data = callback_data;
gnome_vfs_async_open (&handle->handle,
uri,
GNOME_VFS_OPEN_READ,
read_entire_file_open_callback,
handle);
return handle;
}
/* Stop the presses! */
void
nautilus_read_entire_file_cancel (NautilusReadFileHandle *handle)
{
gnome_vfs_async_cancel (handle->handle);
read_entire_file_close (handle);
g_free (handle->buffer);
g_free (handle);
}

View file

@ -27,7 +27,10 @@
#include <libgnomevfs/gnome-vfs-types.h>
typedef void (* NautilusReadFileCallback) (int file_size, char *file_contents, gpointer callback_data);
typedef void (* NautilusReadFileCallback) (GnomeVFSResult result,
GnomeVFSFileSize file_size,
char *file_contents,
gpointer callback_data);
typedef struct NautilusReadFileHandle NautilusReadFileHandle;
char * nautilus_format_uri_for_display (const char *uri);