[patch] gnome_desktop_item_new_from_string
- From: Darin Adler <darin bentspoon com>
- To: desktop-devel-list gnome org
- Subject: [patch] gnome_desktop_item_new_from_string
- Date: Wed, 20 Feb 2002 14:32:46 -0800
Here's a patch to add the call I need for Nautilus.
I also fixed some bugs I found.
Is this the right list to send it to?
May I commit?
Index: libgnome-desktop/ChangeLog
===================================================================
RCS file: /cvs/gnome/gnome-desktop/libgnome-desktop/ChangeLog,v
retrieving revision 1.64
diff -p -u -r1.64 ChangeLog
--- libgnome-desktop/ChangeLog 2002/02/14 18:48:53 1.64
+++ libgnome-desktop/ChangeLog 2002/02/20 22:04:18
@@ -1,3 +1,48 @@
+2002-02-20 Darin Adler <darin bentspoon com>
+
+ * gnome-desktop-item.h:
+ * gnome-desktop-item.c: (readbuf_getc): Handle case where you try
+ to keep reading and the handle is NULL by treating it as EOF. This
+ is also the case at the end of the string. Set a new
+ "past_first_read" flag, used to optimize rewinding for the vast
+ majority of desktop files that fit entirely in the buffer.
+ (readbuf_gets): More g_return_if_fail.
+ (readbuf_open): Add a GError parameter, and include the
+ GnomeVFSResult in the error. Allocate the buf, which is now a
+ separate object.
+ (readbuf_new_from_string): New function, which creates a readbuf
+ from an existing string.
+ (readbuf_rewind): Reset eof and pos to make this actually work.
+ Check the past_first_read flag to avoid re-reading if the entire
+ file fits in the buffer. Reset size to trigger a read if we decide
+ to re-read the buffer. Make it try to reopen the file instead of
+ just malfunctioning if the GnomeVFSFileHandle is already NULL.
+ (readbuf_close): Free the buf if needed.
+ (read_sort_order): Pass NULL for GError * to readbuf_open.
+ (gnome_desktop_item_new_from_uri): Use the GnomeVFSResult for the
+ error code, rather than errno. Get rid of unneeded
+ gnome_vfs_file_info_clear just before gnome_vfs_file_info_unref.
+ Use the new readbuf_open, since ditem_load now takes a ReadBuf *
+ instead of a URI.
+ (gnome_desktop_item_new_from_string): New.
+ (get_encoding): Do the check for valid UTF-8 as we read the file
+ rather than re-reading it again at the end. Also get the URI from
+ the ReadBuf rather than passing it separately for the "guess by
+ location" hack, which is not really necessary, since the validate
+ heuristic will get it right anyway. Also handle the case of a NULL
+ URI properly.
+ (setup_type): Rename filename to uri to make it clearer what's
+ really going on here.
+ (sanitize): Handle the case of a NULL URI. Also add a fallback
+ name for the case where you have neither a URI nor a name in the
+ file. Also fix a storage leak.
+ (ditem_load): Take a ReadBuf * parameters instead of a URI, so we
+ can share this between the file and non-file cases. Also fix an
+ error format string to avoid segfault.
+ (ditem_save): Share the error handling code for gnome_vfs_open
+ and gnome_vfs_create since they did the same thing. Also change
+ to use GnomeVFSResult instead of errno.
+
2002-02-14 Nitin Madhukar Yewale <nitin yewale wipro com>
reviewed by: Mark McLoughlin <mark skynet ie>
Index: libgnome-desktop/gnome-desktop-item.c
===================================================================
RCS file: /cvs/gnome/gnome-desktop/libgnome-desktop/gnome-desktop-item.c,v
retrieving revision 1.90
diff -p -u -r1.90 gnome-desktop-item.c
--- libgnome-desktop/gnome-desktop-item.c 2002/02/11 14:09:48 1.90
+++ libgnome-desktop/gnome-desktop-item.c 2002/02/20 22:04:18
@@ -35,7 +35,6 @@
#include <glib.h>
#include <sys/types.h>
#include <dirent.h>
-#include <errno.h>
#include <unistd.h>
#include <time.h>
#include <string.h>
@@ -95,25 +94,30 @@ typedef enum {
ENCODING_LEGACY_MIXED
} Encoding;
-static GnomeDesktopItem * ditem_load (const char *uri,
- gboolean no_translations,
- GError **error);
-static gboolean ditem_save (GnomeDesktopItem *item,
- const char *uri,
- GError **error);
-
/*
* GnomeVFS reading utils, that look like the libc buffered io stuff
*/
+
+#define READ_BUF_SIZE (32 * 1024)
+
typedef struct {
GnomeVFSHandle *handle;
char *uri;
gboolean eof;
- char buf[BUFSIZ];
+ char *buf;
+ gboolean buf_needs_free;
gsize size;
gsize pos;
+ gboolean past_first_read;
} ReadBuf;
+static GnomeDesktopItem *ditem_load (ReadBuf *rb,
+ gboolean no_translations,
+ GError **error);
+static gboolean ditem_save (GnomeDesktopItem *item,
+ const char *uri,
+ GError **error);
+
static int
readbuf_getc (ReadBuf *rb)
{
@@ -123,24 +127,29 @@ readbuf_getc (ReadBuf *rb)
if (rb->size == 0 ||
rb->pos == rb->size) {
GnomeVFSFileSize bytes_read;
- /* FIXME: handle other errors */
- if (gnome_vfs_read (rb->handle,
- rb->buf,
- BUFSIZ,
- &bytes_read) != GNOME_VFS_OK) {
+
+ /* FIXME: handle errors other than EOF */
+ if (rb->handle == NULL
+ || gnome_vfs_read (rb->handle,
+ rb->buf,
+ READ_BUF_SIZE,
+ &bytes_read) != GNOME_VFS_OK) {
+ bytes_read = 0;
+ }
+
+ if (bytes_read == 0) {
rb->eof = TRUE;
return EOF;
}
+
+ if (rb->size != 0)
+ rb->past_first_read = TRUE;
rb->size = bytes_read;
rb->pos = 0;
- if (rb->size == 0) {
- rb->eof = TRUE;
- return EOF;
- }
}
- return (int)rb->buf[rb->pos++];
+ return (guchar) rb->buf[rb->pos++];
}
/* Note, does not include the trailing \n */
@@ -150,6 +159,7 @@ readbuf_gets (char *buf, gsize bufsize,
int c;
gsize pos;
+ g_return_val_if_fail (buf != NULL, NULL);
g_return_val_if_fail (rb != NULL, NULL);
pos = 0;
@@ -157,14 +167,12 @@ readbuf_gets (char *buf, gsize bufsize,
do {
c = readbuf_getc (rb);
- if (c == EOF ||
- c == '\n')
+ if (c == EOF || c == '\n')
break;
buf[pos++] = c;
} while (pos < bufsize-1);
- if (c == EOF &&
- pos == 0)
+ if (c == EOF && pos == 0)
return NULL;
buf[pos++] = '\0';
@@ -173,40 +181,69 @@ readbuf_gets (char *buf, gsize bufsize,
}
static ReadBuf *
-readbuf_open (const char *uri)
+readbuf_open (const char *uri, GError **error)
{
+ GnomeVFSResult result;
GnomeVFSHandle *handle;
ReadBuf *rb;
g_return_val_if_fail (uri != NULL, NULL);
- if (gnome_vfs_open (&handle, uri,
- GNOME_VFS_OPEN_READ) != GNOME_VFS_OK)
+ result = gnome_vfs_open (&handle, uri,
+ GNOME_VFS_OPEN_READ);
+ if (result != GNOME_VFS_OK) {
+ g_set_error (error,
+ /* FIXME: better errors */
+ GNOME_DESKTOP_ITEM_ERROR,
+ GNOME_DESKTOP_ITEM_ERROR_CANNOT_OPEN,
+ _("Error reading file '%s': %s"),
+ uri, gnome_vfs_result_to_string (result));
return NULL;
+ }
rb = g_new0 (ReadBuf, 1);
rb->handle = handle;
rb->uri = g_strdup (uri);
- rb->eof = FALSE;
- rb->size = 0;
- rb->pos = 0;
+ rb->buf = g_malloc (READ_BUF_SIZE);
+ rb->buf_needs_free = TRUE;
return rb;
}
+static ReadBuf *
+readbuf_new_from_string (const char *uri, const char *string, gssize length)
+{
+ ReadBuf *rb;
+
+ g_return_val_if_fail (string != NULL, NULL);
+ g_return_val_if_fail (length >= 0, NULL);
+
+ rb = g_new0 (ReadBuf, 1);
+ rb->uri = g_strdup (uri);
+ rb->buf = (char *) string;
+ rb->size = length;
+
+ return rb;
+}
+
static gboolean
readbuf_rewind (ReadBuf *rb)
{
- if (gnome_vfs_seek (rb->handle,
- GNOME_VFS_SEEK_START, 0) == GNOME_VFS_OK)
+ rb->eof = FALSE;
+ rb->pos = 0;
+ if (!rb->past_first_read)
return TRUE;
-
- gnome_vfs_close (rb->handle);
- rb->handle = NULL;
+ rb->size = 0;
+ if (rb->handle != NULL) {
+ if (gnome_vfs_seek (rb->handle,
+ GNOME_VFS_SEEK_START, 0) == GNOME_VFS_OK)
+ return TRUE;
+ gnome_vfs_close (rb->handle);
+ rb->handle = NULL;
+ }
if (gnome_vfs_open (&rb->handle, rb->uri,
GNOME_VFS_OPEN_READ) == GNOME_VFS_OK)
return TRUE;
-
return FALSE;
}
@@ -215,14 +252,12 @@ readbuf_close (ReadBuf *rb)
{
if (rb->handle != NULL)
gnome_vfs_close (rb->handle);
- rb->handle = NULL;
g_free (rb->uri);
- rb->uri = NULL;
-
+ if (rb->buf_needs_free)
+ g_free (rb->buf);
g_free (rb);
}
-
static GnomeDesktopItemType G_GNUC_CONST
type_from_string (const char *type)
{
@@ -361,7 +396,7 @@ read_sort_order (GnomeDesktopItem *item,
ReadBuf *rb;
file = g_build_filename (dir, ".order", NULL);
- rb = readbuf_open (file);
+ rb = readbuf_open (file, NULL);
g_free (file);
if (rb == NULL)
@@ -469,19 +504,22 @@ gnome_desktop_item_new_from_uri (const c
char *subfn, *dir;
GnomeVFSFileInfo *info;
time_t mtime = 0;
+ ReadBuf *rb;
+ GnomeVFSResult result;
g_return_val_if_fail (uri != NULL, NULL);
info = gnome_vfs_file_info_new ();
- if (gnome_vfs_get_file_info (uri, info,
- GNOME_VFS_FILE_INFO_DEFAULT) != GNOME_VFS_OK) {
+ result = gnome_vfs_get_file_info (uri, info,
+ GNOME_VFS_FILE_INFO_DEFAULT);
+ if (result != GNOME_VFS_OK) {
g_set_error (error,
/* FIXME: better errors */
GNOME_DESKTOP_ITEM_ERROR,
GNOME_DESKTOP_ITEM_ERROR_CANNOT_OPEN,
_("Error reading file '%s': %s"),
- uri, strerror (errno));
+ uri, gnome_vfs_result_to_string (result));
gnome_vfs_file_info_unref (info);
@@ -512,11 +550,17 @@ gnome_desktop_item_new_from_uri (const c
subfn = g_strdup (uri);
}
- gnome_vfs_file_info_clear (info);
gnome_vfs_file_info_unref (info);
+
+ rb = readbuf_open (subfn, error);
+
+ if (rb == NULL) {
+ g_free (subfn);
+ return NULL;
+ }
- retval = ditem_load (subfn,
- flags & GNOME_DESKTOP_ITEM_LOAD_NO_TRANSLATIONS,
+ retval = ditem_load (rb,
+ (flags & GNOME_DESKTOP_ITEM_LOAD_NO_TRANSLATIONS) != 0,
error);
if (retval == NULL) {
@@ -547,6 +591,45 @@ gnome_desktop_item_new_from_uri (const c
}
/**
+ * gnome_desktop_item_new_from_string:
+ * @string: string to load the GnomeDesktopItem from
+ * @length: length of string, or -1 to use strlen
+ * @flags: Flags to influence the loading process
+ * @error: place to put errors
+ *
+ * This function turns the contents of the string into a GnomeDesktopItem.
+ *
+ * Returns: The newly loaded item.
+ */
+GnomeDesktopItem *
+gnome_desktop_item_new_from_string (const char *uri,
+ const char *string,
+ gssize length,
+ GnomeDesktopItemLoadFlags flags,
+ GError **error)
+{
+ GnomeDesktopItem *retval;
+ ReadBuf *rb;
+
+ g_return_val_if_fail (string != NULL, NULL);
+ g_return_val_if_fail (length >= -1, NULL);
+
+ rb = readbuf_new_from_string (uri, string, length);
+
+ retval = ditem_load (rb,
+ (flags & GNOME_DESKTOP_ITEM_LOAD_NO_TRANSLATIONS) != 0,
+ error);
+
+ if (retval == NULL) {
+ return NULL;
+ }
+
+ /* FIXME: Sort order? */
+
+ return retval;
+}
+
+/**
* gnome_desktop_item_save:
* @item: A desktop item
* @under: A new uri (location) for this #GnomeDesktopItem
@@ -2636,15 +2719,13 @@ get_encoding_from_locale (const char *lo
}
static Encoding
-get_encoding (const char *uri, ReadBuf *rb)
+get_encoding (ReadBuf *rb)
{
- gboolean old_kde = FALSE;
- GnomeVFSURI *tmp_uri;
- int c;
- char buf [BUFSIZ];
- char *path;
-
- gchar *contents = NULL;
+ gboolean old_kde = FALSE;
+ int c;
+ char buf [BUFSIZ];
+ char *path;
+ gboolean all_valid_utf8 = TRUE;
while (readbuf_gets (buf, sizeof (buf), rb) != NULL) {
if (strncmp (GNOME_DESKTOP_ITEM_ENCODING,
@@ -2672,42 +2753,28 @@ get_encoding (const char *uri, ReadBuf *
/* don't break yet, we still want to support
* Encoding even here */
}
+ if (all_valid_utf8 && ! g_utf8_validate (buf, -1, NULL))
+ all_valid_utf8 = FALSE;
}
if (old_kde)
return ENCODING_LEGACY_MIXED;
/* try to guess by location */
- if (strstr (uri, "gnome/apps/") != NULL) {
+ if (rb->uri != NULL && strstr (rb->uri, "gnome/apps/") != NULL) {
/* old gnome */
return ENCODING_LEGACY_MIXED;
}
-
- /* FIXME: fix for gnome-vfs */
- /* A dillema, new KDE files are in UTF-8 but have no Encoding
+ /* A dilemma, new KDE files are in UTF-8 but have no Encoding
* info, at this time we really can't tell. The best thing to
* do right now is to just assume UTF-8 if the whole file
* validates as utf8 I suppose */
- tmp_uri = gnome_vfs_uri_new (uri);
- path = gnome_vfs_uri_get_path (tmp_uri);
- g_free (tmp_uri);
-
- if (!g_file_get_contents (path, &contents, NULL, NULL))
- return ENCODING_LEGACY_MIXED;
-
- if (contents == NULL) /* Ooooooops ! */
- return ENCODING_LEGACY_MIXED;
-
- if (g_utf8_validate (contents, -1, NULL)) {
- g_free (contents);
+ if (all_valid_utf8)
return ENCODING_UTF8;
- } else {
- g_free (contents);
+ else
return ENCODING_LEGACY_MIXED;
- }
-
}
static char *
@@ -2890,12 +2957,12 @@ insert_key (GnomeDesktopItem *item,
}
static void
-setup_type (GnomeDesktopItem *item, const char *filename)
+setup_type (GnomeDesktopItem *item, const char *uri)
{
const char *type = g_hash_table_lookup (item->main_hash,
GNOME_DESKTOP_ITEM_TYPE);
- if (type == NULL && filename != NULL) {
- char *base = g_path_get_basename (filename);
+ if (type == NULL && uri != NULL) {
+ char *base = g_path_get_basename (uri);
if (base != NULL &&
strcmp (base, ".directory") == 0) {
/* This gotta be a directory */
@@ -2940,7 +3007,7 @@ try_english_key (GnomeDesktopItem *item,
static void
-sanitize (GnomeDesktopItem *item, const char *file)
+sanitize (GnomeDesktopItem *item, const char *uri)
{
const char *type;
@@ -2961,11 +3028,14 @@ sanitize (GnomeDesktopItem *item, const
if (lookup (item, GNOME_DESKTOP_ITEM_NAME) == NULL) {
char *name = try_english_key (item, GNOME_DESKTOP_ITEM_NAME);
/* If no name, use the basename */
+ if (name == NULL && uri != NULL)
+ name = g_path_get_basename (uri);
+ /* If no uri either, use same default as gnome_desktop_item_new */
if (name == NULL)
- name = g_path_get_basename (file);
+ name = g_strdup (_("No name"));
g_hash_table_replace (item->main_hash,
g_strdup (GNOME_DESKTOP_ITEM_NAME),
- g_path_get_basename (file));
+ name);
item->keys = g_list_prepend
(item->keys, g_strdup (GNOME_DESKTOP_ITEM_NAME));
}
@@ -2998,11 +3068,10 @@ enum {
};
static GnomeDesktopItem *
-ditem_load (const char *uri,
+ditem_load (ReadBuf *rb,
gboolean no_translations,
GError **error)
{
- ReadBuf *rb;
int state;
char CharBuffer [1024];
char *next = CharBuffer;
@@ -3012,20 +3081,8 @@ ditem_load (const char *uri,
Section *cur_section = NULL;
char *key = NULL;
gboolean old_kde = FALSE;
-
- rb = readbuf_open (uri);
-
- if (rb == NULL) {
- g_set_error (error,
- /* FIXME: better errors */
- GNOME_DESKTOP_ITEM_ERROR,
- GNOME_DESKTOP_ITEM_ERROR_CANNOT_OPEN,
- _("Error reading file '%s': %s"),
- uri, strerror (errno));
- return NULL;
- }
- encoding = get_encoding (uri, rb);
+ encoding = get_encoding (rb);
if (encoding == ENCODING_UNKNOWN) {
readbuf_close (rb);
/* spec says, don't read this file */
@@ -3033,19 +3090,19 @@ ditem_load (const char *uri,
GNOME_DESKTOP_ITEM_ERROR,
GNOME_DESKTOP_ITEM_ERROR_UNKNOWN_ENCODING,
_("Unknown encoding of: %s"),
- uri);
+ rb->uri);
return NULL;
}
/* Rewind since get_encoding goes through the file */
- if ( ! readbuf_rewind (rb)) {
+ if (! readbuf_rewind (rb)) {
readbuf_close (rb);
/* spec says, don't read this file */
g_set_error (error,
GNOME_DESKTOP_ITEM_ERROR,
GNOME_DESKTOP_ITEM_ERROR_CANNOT_OPEN,
- _("Error rewinding file '%s': %s"),
- uri);
+ _("Error rewinding file '%s'"),
+ rb->uri);
return NULL;
}
@@ -3202,10 +3259,10 @@ rb->eof=FALSE;
/* Here we do a little bit of sanitazition */
/* sanitize some things */
- sanitize (item, uri);
+ sanitize (item, rb->uri);
/* make sure that we set up the type */
- setup_type (item, uri);
+ setup_type (item, rb->uri);
return item;
}
@@ -3255,26 +3312,15 @@ ditem_save (GnomeDesktopItem *item, cons
GnomeVFSHandle *handle;
GnomeVFSResult result;
result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_WRITE);
- if (result == GNOME_VFS_ERROR_NOT_FOUND) {
+ if (result == GNOME_VFS_ERROR_NOT_FOUND)
result = gnome_vfs_create (&handle, uri, GNOME_VFS_OPEN_WRITE, TRUE, GNOME_VFS_PERM_USER_ALL);
- if (result != GNOME_VFS_OK) {
- g_set_error (error,
- /* FIXME: better errors */
- GNOME_DESKTOP_ITEM_ERROR,
- GNOME_DESKTOP_ITEM_ERROR_CANNOT_OPEN,
- _("Error writing file '%s': %s"),
- uri, strerror (errno));
-
- return FALSE;
- }
- }
if (result != GNOME_VFS_OK) {
g_set_error (error,
/* FIXME: better errors */
GNOME_DESKTOP_ITEM_ERROR,
GNOME_DESKTOP_ITEM_ERROR_CANNOT_OPEN,
_("Error writing file '%s': %s"),
- uri, strerror (errno));
+ uri, gnome_vfs_result_to_string (result));
return FALSE;
}
Index: libgnome-desktop/gnome-desktop-item.h
===================================================================
RCS file: /cvs/gnome/gnome-desktop/libgnome-desktop/gnome-desktop-item.h,v
retrieving revision 1.36
diff -p -u -r1.36 gnome-desktop-item.h
--- libgnome-desktop/gnome-desktop-item.h 2002/01/17 02:09:59 1.36
+++ libgnome-desktop/gnome-desktop-item.h 2002/02/20 22:04:18
@@ -137,6 +137,11 @@ GnomeDesktopItem * gnome_desktop_it
GnomeDesktopItem * gnome_desktop_item_new_from_uri (const char *uri,
GnomeDesktopItemLoadFlags flags,
GError **error);
+GnomeDesktopItem * gnome_desktop_item_new_from_string (const char *uri,
+ const char *string,
+ gssize length,
+ GnomeDesktopItemLoadFlags flags,
+ GError **error);
GnomeDesktopItem * gnome_desktop_item_copy (const GnomeDesktopItem *item);
/* if under is NULL save in original location */
===================================================================
-- Darin
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]